C-使用CBC(密码块链接)模式的OpenSSL加密
我使用的是的C-API,但我对OpenSSL中如何使用IV()感到困惑 说吧,我有C-使用CBC(密码块链接)模式的OpenSSL加密,c,encryption,openssl,cbc-mode,C,Encryption,Openssl,Cbc Mode,我使用的是的C-API,但我对OpenSSL中如何使用IV()感到困惑 说吧,我有 plaintext.txt file = "This is a top secret." Key = "example#########" IV = 010203040506070809000a0b0c0d0e0f 当我使用OpenSSL AES-128-CBC对此进行加密时,我应该得到: e5accdb667e8e569b1b34f423508c1
plaintext.txt file = "This is a top secret."
Key = "example#########"
IV = 010203040506070809000a0b0c0d0e0f
当我使用OpenSSL AES-128-CBC对此进行加密时,我应该得到:
e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22
当我尝试此操作时(键转换为十六进制),这是正确的:
我得到:
xxd -p ciphertext.bin
e5accdb667e8e569b1b34f423508c15422631198454e104ceb658f5918800c22
但是我用C得到了不同的东西
char plaintext[] = "This is a top secret.";
unsigned char iv[16] = {
0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x00, 0x0A, 0x0B,
0x0C, 0x0D, 0x0E, 0x0F
};
unsigned char ciphertext[] = {
0xe5, 0xac, 0xcd, 0xb6,
0x67, 0xe8, 0xe5, 0x69,
0xb1, 0xb3, 0x4f, 0x42,
0x35, 0x08, 0xc1, 0x54,
0x22, 0x63, 0x11, 0x98,
0x45, 0x4e, 0x10, 0x4c,
0xeb, 0x65, 0x8f, 0x59,
0x18, 0x80, 0x0c, 0x22
};
关键字(示例)位于words.txt
文件中
我的加密过程:
while(fgets(words, 16, wordsfile)) { //for getting key and padding
index = strlen(words) - 1; //key "example" is the last word in words.txt
while(index < 16) {
words[index] = 0x20;
index++;
}
words[index] = '\0';
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, words, iv, 1);
EVP_CipherUpdate(&ctx, outbuf, &outlen, plaintext, strlen(plaintext));
EVP_CipherFinal_ex(&ctx, outbuf + outlen, &templ);
outlen += templ;
EVP_CIPHER_CTX_cleanup(&ctx);
}
while(fgets(words,16,wordsfile)){//用于获取键和填充
index=strlen(words)-1;//关键字“example”是words.txt中的最后一个单词
而(指数<16){
字[索引]=0x20;
索引++;
}
字[索引]='\0';
执行副总裁;
EVP_CIPHER_CTX_init(&CTX);
EVP_CipherInit_ex(&ctx,EVP_aes_128_cbc(),NULL,words,iv,1);
执行副总裁密码更新(ctx、EXBUF和outlen、明文、strlen(明文));
执行副总裁、最终执行副总裁(ctx、EXBUF+outlen和模板);
outlen+=模板;
EVP_密码_CTX_清理(&CTX);
}
当我检查密文与键“example”的匹配时,我得到了一个完全不同的密文。哪一部分我错了?我假设IV的格式或我实现IV的方式是错误的。看起来你已经非常接近了。通过将问题缩小到加密,可以生成正确的密文。因此,与其从文件中读取密钥,不如将其定义为一个无符号字符数组,类似于对其他变量所做的操作:
unsigned char key[]={0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23};
然后,以下代码(重用变量)显示了成功的加密:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(),NULL, key, iv, 1);
EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned char *)plaintext, strlen(plaintext));
EVP_CipherFinal_ex(&ctx, outbuf+outlen, &templ);
outlen+=templ;
EVP_CIPHER_CTX_cleanup(&ctx);
int cmpres = memcmp(outbuf, ciphertext, sizeof(ciphertext));
printf("cmpres is %d, sizeof(ciphertext) is %lu, outlen is %d\n",
cmpres, sizeof(ciphertext), outlen);
因为它会打印
$ ./main
cmpres is 0, sizeof(ciphertext) is 32, outlen is 32
这意味着问题在于如何从文件中读取密钥。这比密码问题更容易分析:-)我将把这部分留给你们来解决
顺便说一句,请确保检查OpenSSL调用的所有返回代码,它将帮助您检测错误情况。看起来您已经非常接近了。通过将问题缩小到加密,可以生成正确的密文。因此,与其从文件中读取密钥,不如将其定义为一个无符号字符数组,类似于对其他变量所做的操作:
unsigned char key[]={0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23};
然后,以下代码(重用变量)显示了成功的加密:
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(),NULL, key, iv, 1);
EVP_CipherUpdate(&ctx, outbuf, &outlen, (unsigned char *)plaintext, strlen(plaintext));
EVP_CipherFinal_ex(&ctx, outbuf+outlen, &templ);
outlen+=templ;
EVP_CIPHER_CTX_cleanup(&ctx);
int cmpres = memcmp(outbuf, ciphertext, sizeof(ciphertext));
printf("cmpres is %d, sizeof(ciphertext) is %lu, outlen is %d\n",
cmpres, sizeof(ciphertext), outlen);
因为它会打印
$ ./main
cmpres is 0, sizeof(ciphertext) is 32, outlen is 32
这意味着问题在于如何从文件中读取密钥。这比密码问题更容易分析:-)我将把这部分留给你们来解决
顺便说一下,请确保检查OpenSSL调用的所有返回代码,它将帮助您检测错误情况