AES ECB加密/解密仅能解密前16个字节

5

我有一个解密AES 256字符串的函数,但它只返回16个字符。

bool decrypt_block(unsigned char* cipherText, unsigned char* plainText, unsigned char* key)
{
    AES_KEY decKey;
    if (AES_set_decrypt_key(key, 256, &decKey) < 0)
        return false;
    AES_decrypt(cipherText, plainText, &decKey);
    return true;
}

decrypt_block( encoded, resultText, ( unsigned char *) "57f4dad48e7a4f7cd171c654226feb5a");

有什么想法吗?


1
你不应该使用 AES_encrypt 和相关函数,而应该使用 EVP_* 函数。请参考 OpenSSL wiki 上的 EVP Symmetric Encryption and Decryption。事实上,你应该使用认证加密,因为它提供了*机密性和真实性两个方面的保护。请参考 OpenSSL wiki 上的 EVP Authenticated Encryption and Decryption - jww
2个回答

5

您似乎混淆了密钥长度和块大小。

AES可以使用3种不同的密钥长度:128位、192位和256位。

AES始终使用128位(16字节)的块大小。对于超过16个字节长的消息,您需要每次解密(或加密)16个字节,并期望每次获得16个字节的输出。(您还需要决定使用哪种模式,例如CBC、CTR、ECB等。如果您正在解密其他人提供的文本,则该决策已经为您做出。如果自己做出决策,请记住ECB几乎从未是正确的选择。) 如果消息的长度不是16个字节的倍数,则需要填充它,使其成为16个字节的倍数。PKCS#7填充是最常见的。

有关更多信息,请参见AES的维基百科文章


4

AES是一种块密码。它加密和解密一个128位(16字节)的块。 AES_decrypt和AES_encrypt每次只处理一个块。所以,你只能获得前16个字节。你需要手动解密或加密其他块。

如果你知道模式(如CBC、ECB等),可以调用类似AES_decrypt_cbc的函数。

你需要按照以下方式修改代码(这只是一个例子):

 int len = strlen(ciphertext); //or get cipher text length by any mean.
 int i;
 for(i=0; i<=len; i+=16)
    AES_decrypt(cipherText+i, plainText+i, &decKey);

如果您确定加密模式,请调用cbc/ecb/cfb/ofb模式函数。

如果有任何疑问,请告诉我。


是的,但只适用于短字符串,如果字符串较长会返回错误。 - user956584
什么是损坏的数据? - doptimusprime
这个损坏的数据:(unsigned char*)encod.c_str() - user956584
encod 中是否有任何 '\0'? - doptimusprime
问题出在strlen上,所以我只是向函数中添加了另一个参数来表示长度。 - user956584
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接