Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ AES128/ECB的加密结果错误(OpenSSL和WinCrypt)_C++_Encryption_Openssl_Aes_Wincrypt - Fatal编程技术网

C++ AES128/ECB的加密结果错误(OpenSSL和WinCrypt)

C++ AES128/ECB的加密结果错误(OpenSSL和WinCrypt),c++,encryption,openssl,aes,wincrypt,C++,Encryption,Openssl,Aes,Wincrypt,我正在尝试使用AES128(ECB模式)加密文本块,以测试结果加密/解密功能,我正在使用来自“”的ECB-AES123测试向量 例如: Key: 2b7e151628aed2a6abf7158809cf4f3c (16 bytes) Input Plaintext: 6bc1bee22e409f96e93d7e117393172a (16 bytes) Resulted Ciphertext: 3ad77bb40d7a3660a89ecaf32466ef97 (16 byte

我正在尝试使用AES128(ECB模式)加密文本块,以测试结果加密/解密功能,我正在使用来自“”的ECB-AES123测试向量

例如:

Key: 2b7e151628aed2a6abf7158809cf4f3c  (16 bytes)      
Input Plaintext: 6bc1bee22e409f96e93d7e117393172a  (16 bytes) 
Resulted Ciphertext: 3ad77bb40d7a3660a89ecaf32466ef97  (16 bytes)
对于OpenSSL,以下代码非常有效:

AES_KEY aes_key; 
//key vector of bytes 2b7e151628aed2a6abf7158809cf4f3c (16 bytes)
//input_vector also vector of bytes 6bc1bee22e409f96e93d7e117393172a  (16 bytes) 
if ( AES_set_encrypt_key( &key[0], 128, &aes_key ) != 0 )
{
    return false;
}
AES_ecb_encrypt( &input_vector[ 0 ], &encrypted_vector[ 0 ], &aes_key, AES_ENCRYPT );
//encrypted_vector will have expected value 3ad77bb40d7a3660a89ecaf32466ef97 (16 bytes)
但同时我需要用微软的加密API实现同样的功能。以下是应执行此操作的代码:

HCRYPTPROV crypto_provider_handle;
HCRYPTHASH crypto_hash_handle;
HCRYPTKEY crypto_key_handle;

CryptAcquireContext( &crypto_provider_handle, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
                     CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET );
CryptCreateHash( crypto_provider_handle, CALG_SHA1, 0, 0, &crypto_hash_handle ); 
CryptHashData( crypto_hash_handle, &key[ 0 ], key.size( ), 0 );
CryptDeriveKey( crypto_provider_handle, CALG_AES_128, crypto_hash_handle,
                0x00800000 | CRYPT_NO_SALT, crypto_key_handle );

// Set ECB mode
DWORD mode = CRYPT_MODE_ECB;
CryptSetKeyParam( crypto_key_handle, KP_MODE, (BYTE*)&mode, 0 );

// input_data is buffer of 16 bytes with additional space, total size 16*2
// input_size equals 16
CryptEncrypt( crypto_key_handle, NULL, TRUE, 0, input_data, &input_size, 16*2 );
但是这个代码会产生不同的结果

  • 如果“最终”为真(如上所示),则输入数据将为 大小为32字节,与预期值完全不匹配。相符合的 对于MSDN来说,这没关系,因为在这种情况下,会有一个额外的填充块 被追加到数据中
  • 如果“Final”为假,则输入的数据将具有预期大小(16字节),但结果也是错误的
  • 我一直在处理这个案子,我不明白我错过了什么。
    是否可能产生与OpenSSL相同的结果(根据规范预期)?为什么ECB模式下的AES128会改变结果的大小(在ECB模式下不应该这样做)

    设置
    NoPadding
    (或其等效项)将删除第二个块。最好检查您的密钥和IVs是否完全相同。OpenSSL和MS可能有不同的默认值,因此如果依赖系统默认值,则会出现不匹配。只要可能,明确地指定所有内容,这样你就知道在两个系统中它们是相同的。是的,我同意。我已经考虑过了。但问题是,当最后一个纯文本块是来自MSDN的短示例时,通常应添加填充:“如果块长度为64位,而最后一个块仅包含40位,则必须向最后一个块添加24位填充”。但是在我们的例子中,所有的块都有相同的大小——16字节。也没有发现对传入数据禁用填充的任何可能性。看起来这是默认行为。@AlexZeydel 1)我不明白你的意思。如果使用PKCS#7填充,16字节的明文将映射为32字节的密文,因为它添加了1到16字节的填充。如果在解密过程中也使用PKCS#7填充,则在解密时会自动删除。如果不需要填充,则需要禁用它。2) 你为什么用静脉注射?ECB不支持IVs。另外,为OpenSSL和MS Crypto API库设置相同的默认行为有点棘手,因为我们不知道什么是默认MS行为。OpenSSL很容易检查,因为所有src都可用。对于我来说,这个问题看起来像是我在调用之前的配置步骤中遗漏了什么CryptoEnctypt@CodesInChaos1)是的,看起来pkcs#7是MS CryptoApi的默认行为,但同时我们不能在那里禁用它。此外,据我所知,AES不能使用pkcs#5作为示例。2) 为什么你对IV做出这样的决定。在ECB模式下,我们根本不需要它。在我的情况下,我只有16个字节的密钥(密码)、16个字节的普通数据(也是16个字节)和16个字节的结果