基于Golang关于CFB解密的文档,我写了一个最小的工作示例来解密使用AES CFB加密的字符串,然后使用python3编码的base 64。
当邮件在Golang中加密(使用Golang doc示例中的加密功能)时,golang解密工作正常。但是,当我使用python crypto包在python脚本中加密消息时,我无法在golang脚本中成功解密它。我没有得到正确的字节。
$ python3 stack.py Going to encrypt and base64 "This is not encrypted" result: b'jf9A5LCxKWPuNb1XiH+G3APAgR//' Now going to call the Golang script: b'Hello from Golang, going to decrypt: jf9A5LCxKWPuNb1XiH+G3APAgR// Result: Tl!\xca/\xf1\xc0\xb2\xd01Y\x02V\xec\xdf\xecy\xd38&\xd9\n'
两种AES实现的默认块大小为16。
那么问题来了:出了什么问题?
Golang脚本:
package main import ( "crypto/aes" "crypto/cipher" "encoding/base64" "fmt" "os" ) func main() { key := []byte("TfvY7I358yospfWKcoviZizOShpm5hyH") iv := []byte("mb13KcoviZizvYhp") payload_python := os.Args[1] fmt.Println("Hello from Golang, going to decrypt: "+payload_python+" Result: "+string(decrypt(key, payload_python, iv))) } func decrypt(key []byte, cryptoText string, iv []byte) []byte { ciphertext, _ := base64.StdEncoding.DecodeString(cryptoText) //decode base64 coding //prepare decryption based on key and iv block, _ := aes.NewCipher(key) stream := cipher.NewCFBDecrypter(block, iv) //decrypt stream.XORKeyStream(ciphertext, ciphertext) return ciphertext }
Python脚本:
#!/usr/bin/env python3 import base64 from Crypto.Cipher import AES from subprocess import check_output original_message = 'This is not encrypted' key = 'TfvY7I358yospfWKcoviZizOShpm5hyH' iv = 'mb13KcoviZizvYhp' #prepare encryption cfb_cipher_encrypt = AES.new(key, AES.MODE_CFB, iv) #encrypt and base64 encode encryptedpayload = base64.b64encode(cfb_cipher_encrypt.encrypt(original_message)) print('Going to encrypt and base64 "{}" result:\n{}\n'.format(original_message,encryptedpayload)) print('Now going to call the Golang script:') print(check_output('go run stack.go {}'.format(encryptedpayload.decode()),shell=True))
尝试像这样从Python加密。
然后可以从Go成功解密结果。
#!/usr/bin/env python3 import base64 from Crypto.Cipher import AES MODE = AES.MODE_CFB BLOCK_SIZE = 16 SEGMENT_SIZE = 128 def _pad_string(value): length = len(value) pad_size = BLOCK_SIZE - (length % BLOCK_SIZE) return value.ljust(length + pad_size, '\x00') def encrypt(key, iv, plaintext): aes = AES.new(key, MODE, iv, segment_size=SEGMENT_SIZE) plaintext = _pad_string(plaintext) encrypted_text = aes.encrypt(plaintext) return encrypted_text key = 'TfvY7I358yospfWKcoviZizOShpm5hyH' iv = 'mb13KcoviZizvYhp' original_message = 'This is not encrypted' encryptedpayload = base64.b64encode(encrypt(key, iv, original_message)) print('Going to encrypt and base64 "{}" result:\n{}\n'.format(original_message,encryptedpayload))
来源:http://chase-seibert.github.io/blog/2016/01/29/cryptojs-pycrypto- ios-aes256.html