相当于OpenSSL EVP对称EVP_aes_256_cbc

时间:2014-09-03 23:39:32

标签: encryption go openssl aes evp-cipher

我正在编写一个Go脚本,用于解密使用EVP_aes_256_cbc和RSA公钥加密的一些旧数据。

在C中,这将是:

key_size = EVP_OpenInit(&ctx, EVP_aes_256_cbc(), evp_key, eklen, iv, pkey);
//...
EVP_OpenUpdate(&ctx, destination, &len_out, buffer_in, buffer_size)
//...
EVP_OpenFinal(&ctx, destination+len_out, &len_out);

我在Go中有evp_keyiv字节数组,但我必须承认EVS在OpenSSL中如何工作的顺序让我失望(我在C中相当称职,但我可以'通过查看OpenSSL源来了解解密过程。)

在Go中,我可以做到这一点:

pKey := //rsa.PrivateKey
eklen := 32
evpKey := "// hidden 32 byte array"
iv := "// hidden 16 byte array"

c, err := aes.NewCipher(iv)
cbc := cipher.NewCBCDecrypter(c, iv)

这就是我迷路的地方。我有一个evpKeypKey,但我不确定如何从这里解密数据。 OpenSSL使用RSA_decrypt_old或类似的东西,但我无法追查其实际含义。

是否有Go等价物,或者我是否需要淘汰价格过高的cgo套装并卷起袖子?

更新(决议):

对于任何想要在Go中复制EVP行为的人或只想知道EVP如何正常工作,以下是细分。 如果您知道C(或Java或任何OpenSSL实现)正在加密,例如:

// pseudo-code: don't copypasta and expect amazing
EVP_PKEY_assign_RSA(pkey, public_key);
EVP_CIPHER_CTX_init(&ctx);
EVP_SealInit(&ctx, EVP_aes_256_cbc(), &evp_key, &evp_key_len, iv, &pkey, 1);
EVP_SealUpdate(&ctx, buffer_out, &encrypt_len, (unsigned char*)buffer_in, len);
EVP_SealFinal(&ctx, buffer_out+encrypt_len, &encrypt_len);

“Seal”实际上只是使用RSA公钥加密密钥。

在Go中解密类似的东西:

evpKeyBytes := "// the rsa.PublicKey encoded evpKey"
evpKey, err := rsa.DecryptPKCS1v15(rand.Reader, PrivateKeyRSA, evpKeyBytes)
c, err := aes.NewCipher(evpKey)
cbc := cipher.NewCBCDecrypter(c, iv)
decryptedDataBytes := make([]bytes, 2048) // some message size
cbc.CryptBlocks(decryptedDataBytes, encryptedDataBytes)
data = string(decryptedDataBytes)
// data should have the expected decrypted result.

1 个答案:

答案 0 :(得分:2)

NewCipher期望密钥不是iv,因为你将它传递给128位iv,它就像aes128cbc一样。