1

我正在尝试使用 AES128(ECB 模式)加密文本块,以测试我使用的 ECB-AES123 测试向量产生的加密/解密功能,来自“建议块密码操作模式:方法和技术,NIST 特别出版物 800 -38A,2001 年版; “。

例如:

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)

但同时我需要使用 Microsoft 的 Crypto 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 );

但是这段代码会产生不同的结果。

  1. 如果“Final”为 TRUE(如上所示),input_data 的大小将是 32 字节,这根本与预期值不匹配。根据 MSDN,没关系,因为在这种情况下,数据会附加一个额外的填充块。
  2. 如果“Final”为 FALSE,则 input_data 将具有预期的大小(16 字节),但结果也会错误。

我一直坚持这个案子,我不明白我错过了什么。是否可以产生与 OpenSSL 相同的结果(根据规范预期)?为什么 ECB 模式下的 AES128 会改变结果的大小(在 ECB 模式下不应该这样做)?

4

0 回答 0