我需要从OpenSSL迁移到MS CryptoAPI。
当我使用OpenSSL时,我得到了N字节(已经对齐 - 例如,假设数据长度= 32bytes)的数据,并将其从一个缓冲区编码/解码到另一个缓冲区。一切正常。
现在我必须"使用CryptoAPI!"。 所以我写了类似的东西:
// Import AES key
if(!CryptImportKey(m_hProvider, (CONST BYTE*)&aeskey, structsize, NULL, 0, &m_hAesKey ) ) {
throw WinAESException("SetKey: Import key failed");
}
// Set Mode
DWORD dwMode = CRYPT_MODE_ECB; //I can also use CRYPT_MODE_CBC with set of IV but let simple the code;
if(!CryptSetKeyParam(m_hAesKey, KP_MODE, (BYTE*)&dwMode, 0)) {
throw WinAESException("SetKey: Set ECB mode failed");
}
它运作正常, 现在我尝试编码数据
DWORD d = (DWORD)psize;
result = CryptEncrypt( m_hAesKey, NULL, TRUE, 0, buffer, &d, (DWORD)bsize );
我看到了什么?数据的编码部分大于源。 我知道CryptEncrypt函数以某种方式填充了填充数据吗?
无论如何,是否有可能将编码结果与普通数据相同?
我不使用非对齐块,我希望,当我加密32字节时,准确得到32字节,而不是48 ...
当我测试预期的大小时
DWORD d = 16;
result = CryptEncrypt( m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize ); //need 32
d = 32;
result = CryptEncrypt( m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize ); //need 48
d = 48;
result = CryptEncrypt( m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize ); //need 64
d = 64;
result = CryptEncrypt( m_hAesKey, NULL, TRUE, 0, 0, &d, (DWORD)bsize ); //need 80
我做错了吗? 附:如果我将加密结果截断为所需大小然后尝试解密,则使用返回的预期错误代码完成解密,但数据正确解密。但这个黑客不适合我...
答案 0 :(得分:0)
首先,它不是编码和解码-它是加密和解密。
Microsoft可能默认情况下添加了PKCS5_PADDING-没有NO_PADDING这样的选项。 这很奇怪,尤其是对于ECB模式,但这解释了为什么CryptEncrypt返回扩展的缓冲区大小-它增加了一个用于填充的块。
另一方面,您在上述答案中使用bFinal == FALSE的“技巧”实际上是可以的,因为ECB模式不需要任何终结处理。
如果要使用其他加密模式,则应始终使用bFinal == TRUE加密。
如果您想正确执行操作,则应该分两步进行加密:
DWORD dwEncryptedDataLen = dwRealDataLen;
result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, NULL, &dwEncryptedDataLen, 0);
...
pbData = (BYTE*)malloc(dwEncryptedDataLen);
memcpy(pbData, pbRealData, dwRealDataLen);
...
result = CryptEncrypt(m_hAesKey, NULL, TRUE, 0, pbData, &dwRealDataLen, dwEncryptedDataLen);
...
不要忘记检查Crypt函数的结果值。
答案 1 :(得分:-1)
我似乎找到了临时解决方案。 当我需要加密/解密整个块时 - 我需要的只是功能 - “它不是最后一个/唯一的块”: 所以不要输入:
result = CryptEncrypt( m_hAesKey, NULL, TRUE, 0, buffer, &d, (DWORD)bsize );
但:
result = CryptEncrypt( m_hAesKey, NULL, FALSE, 0, buffer, &d, (DWORD)bsize );
现在它有效。并希望他们不要在最后一篇文章的末尾更改填充数据的概念,以便在块的开头添加对齐...