我一直在努力熟悉OpenSSL库,为此,我想制作一些使用不同操作模式加密文本的程序。我已经创建了一个程序,我想使用ECB模式进行加密和解密,但结果并不是我所期望的。
以下是我迄今为止的代码。
#include <stdio.h>
#include <openssl/aes.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/rand.h>
//static const unsigned char key[]={01234567890123456789012345678900};
int main()
{
int keylength;
printf("Give a key length [only 128 or 192 or 256!]:n");
scanf("%d", &keylength);
/* generate a key with a given length */
unsigned char aes_key[keylength];
memset(aes_key, 0, sizeof(aes_key));
if (!RAND_bytes(aes_key, keylength))
{
exit(-1);
}
aes_key[keylength-1] = ' ';
unsigned char text[] = "TestText TestText"; //Assign text to be encrypted
unsigned char enc_out[AES_BLOCK_SIZE]; //Set to 16 bytes
unsigned char dec_out[AES_BLOCK_SIZE];
AES_KEY enc_key, dec_key; //establish AES enc and dec key
AES_set_encrypt_key(aes_key, 128, &enc_key);
AES_encrypt(text, enc_out, &enc_key);
AES_set_decrypt_key(aes_key, 128, &dec_key);
AES_decrypt(enc_out, dec_out, &dec_key);
int x;
printf("original:t");
for(x=0;*(text+x)!=0x00;x++)
printf("%X ",*(text+x));
printf("nencrypted:t");
for(x=0;*(enc_out+x)!=0x00;x++)
printf("%X ",*(enc_out+x));
printf("ndecrypted:t");
for(x=0;*(dec_out+x)!=0x00;x++)
printf("%X ",*(dec_out+x));
printf("n");
return 0;
}
我知道对于ECB模式,相同的明文块应该被加密为相同的密文块,但当我运行代码时,这种情况不会发生。这里有一个例子:
original: 54 65 73 74 54 65 78 74 2E 20 20 54 65 73 74 54 65 78 74 2E
encrypted: A2 FE 93 40 F5 92 95 F A2 5A D0 4A A6 53 95 58 54 65 73 74
54 65 78 74 2E 20 20 54 65 73 74 54 54 65 73 74 54 65 78 74
2E 20 20 54 65 73 74 54 65 78 74 2E
decrypted: 54 65 73 74 54 65 78 74 2E 20 20 54 65 73 74 54 54 65 73 74
54 65 78 74 2E 20 20 54 65 73 74 54 65 78 74 2E
首先,我将输入文本转换为十六进制,然后使用ECB模式对其进行加密,最后对所有内容进行解密。我加密的两个文本字符串是相同的,但十六进制格式的文本没有显示这一点。相同的明文不共享相同的密文。明文的十六进制似乎也在尾随加密文本,我不确定为什么会发生这种情况。有人能解释为什么加密不能正常工作吗?我的代码中是否有任何错误没有提供必要的结果?感谢您的帮助。感谢
这里有几个错误。
首先:您将大小混合为位和字节。128位密钥的长度是16字节,而不是128字节。这基本上是无害的,因为您最终会生成过大的密钥。
第二:您假设AES的输入和输出(包括密钥)是以null结尾的。事实并非如此。打印的输出的前16个字节之后的所有内容都是随机垃圾,密钥不会(也不应该!)以null终止。
第三:您的测试输入("TestText TestText"
)太长,无法放入单个AES块。AES_encrypt()
仅对单个块进行操作。