【发布时间】:2018-11-18 14:17:34
【问题描述】:
我一直有一些问题试图弄清楚为什么我的加密与 php 和 node 相比在 go 中有所不同。我希望有人可以帮助我找出差异。假设这是数据:
明文:hello big worldshello big worlds
密钥:jJr44P3WSM5F8AC573racFpzU5zj7Rg5
iv:97iEhhtgVjoVwdUw
以下是 base64 中的加密结果:
节点和 PHP 返回:
OTdpRWhodGdWam9Wd2RVd0OgJ+Z7pSCVioYq41721jarxqLKXN3PcnnY6/AOrHeEfsTxXfCgm2uUi+vmCAdpvw==
Go 返回:
OTdpRWhodGdWam9Wd2RVd0OgJ+Z7pSCVioYq41721jarxqLKXN3PcnnY6/AOrHeE
如您所见,它们几乎完全相同,这让我发疯。你们能否快速查看下面的加密代码并提示我可能出现的问题?
去:
func EncryptString(plainstring string, keystring string, encFormat int, ivOverride bool) (string) {
// Load your secret key from a safe place and reuse it across multiple
// NewCipher calls. (Obviously don't use this example key for anything
// real.) If you want to convert a passphrase to a key, use a suitable
// package like bcrypt or scrypt.
key := []byte(keystring)
plaintext := []byte(plainstring)
// CBC mode works on blocks so plaintexts may need to be padded to the
// next whole block. For an example of such padding, see
// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll
// assume that the plaintext is already of the correct length.
if len(plaintext)%aes.BlockSize != 0 {
panic("plaintext is not a multiple of the block size")
}
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(bytes.NewReader([]byte("97iEhhtgVjoVwdUw")), iv); err != nil {
panic(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
// It's important to remember that ciphertexts must be authenticated
// (i.e. by using crypto/hmac) as well as being encrypted in order to
// be secure.
return base64.StdEncoding.EncodeToString(ciphertext)
}
节点:
encryptString: function(string, key, fmt = null, ivOverride = false) {
// Build an initialisation vector
let iv;
if(!ivOverride) {
iv = crypto.randomBytes(IV_NUM_BYTES).toString('hex').slice(0,16);
} else {
iv = IV_OVERRIDE_VALUE; //97iEhhtgVjoVwdUw
}
// and encrypt
let encryptor = crypto.createCipheriv('aes-256-cbc', key, iv);
let encryptedData = encryptor.update(string, 'utf8', 'binary') + encryptor.final('binary');
encryptedData = iv+''+encryptedData;
encryptedData = Buffer.from(encryptedData, 'binary').toString('base64');
return encryptedData;
}
我注意到删除encryptor.final('binary') 会使两者得到相同的加密,但 php 没有 .final() 功能。 Php uses open_ssl_encrypt() 似乎内置了这个。有没有办法在 go 中添加一个等价物?寻求建议。谢谢
【问题讨论】:
-
echo $output = openssl_encrypt("hello big worldshello big worlds", "AES-256-CBC", "jJr44P3WSM5F8AC573racFpzU5zj7Rg5", 0, "97iEhhtgVjoVwdUw");在 PHP Q6An5nulIJWKhirjXvbWNqvGospc3c9yedjr8A6sd4R+xPFd8KCba5SL6+YIB2m/ 中获得不同的输出
标签: php node.js go encryption aes