AES-256 / Erlang中的CBC加密和C语言中的解密不起作用



我在Erlang中对AES 256位CBC进行加密而面临问题,然后在C代码中解密它。而加密/解密在Erlang和C中起作用,而不是从一个到另一个。

Ivec = "1200000000000000",
Key = "586E36EEE726B37F70A6F7B770764E99",
Data = "encrypt[38ce517c95b011bbfc999f36d09e4feb92d22dd8,38ce517c95b011bbfc999f36d09e4feb92d22222]",
PaddedText = string:left(Data ++ ",",128,$0),
%%Data is "encrypt[38ce517c95b011bbfc999f36d09e4feb92d22dd8,38ce517c95b011bbfc999f36d09e4feb92d22222],0000000000000000000000000000000000000"
EncryptedText = crypto:block_encrypt(aes_cbc256, Key, Ivec, PaddedText),
%%Send to C code

和C代码

unsigned char *key = (unsigned char *)"586E36EEE726B37F70A6F7B770764E99";
unsigned char *iv = (unsigned char *)"1200000000000000";
EVP_CIPHER_CTX *ctx;
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)
EVP_DecryptUpdate(ctx, plaintext, &len, buf, buf_len)

我得到的错误是

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:

当我在Erlang中解密时,它可以正常工作,当我在C中加密时,它也可以与相同的键和IV一起工作。它是密码模式不匹配的吗?虽然对我来说看起来正确。任何指针都将真正有用。谢谢

我弄清楚,我在C中加密和解密的数据相同,然后进行了十六进制。实际的加密数据erlang是Senginh是128个字节,C OpenSSL库加密相同的数据为144个字节。这是普通的密码文本通常很长。这是输出。

Erlang二进制返回后返回:

<<165,171,208,104,24,97,173,130,177,99,50,22,51,180,112,123,36,18,208,170,250,131,195,162,182,162,253,14,121,242,61,60,202,172,74,121,223,50,128,255,134,51,253,91,195,174,90,93,77,65,1,115,119,64,25,131,47,245,68,156,163,145,111,125,143,208,255,53,131,220,174,243,64,120,229,21,86,107,139,148,164,39,144,106,232,64,252,234,26,208,138,187,213,244,210,11,174,47,126,4,97,179,194,85,8,207,116,140,236,3,145,209,95,106,36,121,241,228,153,120,226,125,227,138,130,183,217,39>>

这是由Erlang发送的

    Encrypted =  128
a5 ab d0 68 18 61 ad 82 b1 63 32 16 33 b4 70 7b  
24 12 d0 aa fa 83 c3 a2 b6 a2 fd 0e 79 f2 3d 3c 
ca ac 4a 79 df 32 80 ff 86 33 fd 5b c3 ae 5a 5d 
4d 41 01 73 77 40 19 83 2f f5 44 9c a3 91 6f 7d 
8f d0 ff 35 83 dc ae f3 40 78 e5 15 56 6b 8b 94 
a4 27 90 6a e8 40 fc ea 1a d0 8a bb d5 f4 d2 0b 
ae 2f 7e 04 61 b3 c2 55 08 cf 74 8c ec 03 91 d1
5f 6a 24 79 f1 e4 99 78 e2 7d e3 8a 82 b7 d9 27 

这是openssl(c(库相同数据的输出。

Encrypted = 144
a5 ab d0 68 18 61 ad 82 b1 63 32 16 33 b4 70 7b  
24 12 d0 aa fa 83 c3 a2 b6 a2 fd 0e 79 f2 3d 3c  
ca ac 4a 79 df 32 80 ff 86 33 fd 5b c3 ae 5a 5d 
4d 41 01 73 77 40 19 83 2f f5 44 9c a3 91 6f 7d 
8f d0 ff 35 83 dc ae f3 40 78 e5 15 56 6b 8b 94 
a4 27 90 6a e8 40 fc ea 1a d0 8a bb d5 f4 d2 0b  
ae 2f 7e 04 61 b3 c2 55 08 cf 74 8c ec 03 91 d1 
5f 6a 24 79 f1 e4 99 78 e2 7d e3 8a 82 b7 d9 27 
f7 01 c0 ed 95 e3 14 e5 d2 62 21 da a9 1d 2a e7  

Erlang缺少最后16个字节。我还需要从Erlang加密库库打电话其他API?

您正在查看的是填充的区别。OpenSSL始终使用PKCS#7定义的填充方案进行垫板。在Erlang中,您可以使用零(这称为零填充(在使用密码加密之前。密码本身没有垫子(似乎(。

由于明文是16个的倍数(128位,AES的块大小(一块完整的填充块 - 由OpenSSL例程添加到明文中,由16个字节估算的10组成。

因此,如果要匹配密文,则应使用EVP_CIPHER_CTX_set_padding(0)

EVP_CIPHER_CTX_set_padding()启用或禁用填充。默认情况下,使用标准块填充填充加密操作,并在解密时检查和删除填充。如果PAD参数为零,则不会执行填充,因此必须将加密或解密的数据总量为块大小的倍数,否则将发生错误。

最新更新