请问用调用openssl的api来及使用openssl的命令行工具进行AES加密,密文为什么不一致

dungeonsnd 2012-02-07 04:43:34
请问用调用openssl的api来及使用openssl的命令行工具进行AES加密,密文为什么不一致?
我使用了三种方式来对同一字符串进行AES加密,
a 使用 openssl命令行工具.
b 使用java的javax.crypto这个包的相关类.
c 使用openssl的c语言api函数.

结果,a与b得到相同的密文结果(输入相同的key及iv),而c与a(b)密文结果不同.
a,b,c方式都是可以自己加解密的.
因为我要保证这三种方式任意一种都可以解密另一种加密过的密文,所以我要确保密文结果相同。

我觉得是c方式写的代码问题,因为a与b可以得到相同的密文。请问问题在哪?

------------------------------------------------
测试环境是centos,openssl版本1.0.0f

方式a
下面是我用命令行工具时使用的命令

[root@COS56DEV-64 ~]# cat e.sh
openssl enc -aes-128-cbc -e -a -in pt.txt -out ct.txt -K 01020304050607080900010203040506 -iv 01020304050607080900010203040506 -p


方式b
是eclipse中写的java代码,我就不贴了,加密后的密文与方式a相同.

方式c
这是我的c代码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/aes.h>

int main(int argc, char** argv) {
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
unsigned char iv[AES_BLOCK_SIZE]; // init vector
unsigned char* input_string;
unsigned char* encrypt_string;
unsigned char* decrypt_string;
unsigned int len; // encrypt length (in multiple of AES_BLOCK_SIZE)
unsigned int i;

// check usage
if (argc != 2) {
fprintf(stderr, "%s <plain text>\n", argv[0]);
exit(-1);
}

// set the encryption length
len = 0;
if ( strlen(argv[1])>=AES_BLOCK_SIZE ||
(strlen(argv[1]) + 1) % AES_BLOCK_SIZE == 0) {
len = strlen(argv[1]) + 1;
} else {
len = ((strlen(argv[1]) + 1) / AES_BLOCK_SIZE + 1) * AES_BLOCK_SIZE;
}

// set the input string
input_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (input_string == NULL) {
fprintf(stderr, "Unable to allocate memory for input_string\n");
exit(-1);
}
strncpy((char*)input_string, argv[1], strlen(argv[1]));

// Generate AES 128-bit key
memset(key, 0x01, AES_BLOCK_SIZE);

// Set encryption key
memset(iv, 0x01, AES_BLOCK_SIZE);
if (AES_set_encrypt_key(key, 128, &aes) < 0) {
fprintf(stderr, "Unable to set encryption key in AES\n");
exit(-1);
}

// alloc encrypt_string
encrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (encrypt_string == NULL) {
fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
exit(-1);
}

// encrypt (iv will change)
AES_cbc_encrypt(input_string, encrypt_string, len, &aes, iv, AES_ENCRYPT);

/////////////////////////////////////

// alloc decrypt_string
decrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (decrypt_string == NULL) {
fprintf(stderr, "Unable to allocate memory for decrypt_string\n");
exit(-1);
}

// Set decryption key
memset(iv, 0x01, AES_BLOCK_SIZE);
if (AES_set_decrypt_key(key, 128, &aes) < 0) {
fprintf(stderr, "Unable to set decryption key in AES\n");
exit(-1);
}

// decrypt
AES_cbc_encrypt(encrypt_string, decrypt_string, len, &aes, iv,
AES_DECRYPT);

// print
printf("input_string =%s\n", input_string);
printf("encrypted string =");
for (i=0; i<len; ++i) {
printf("%u ", encrypt_string[i]);
}
printf("\n");
printf("decrypted string =%s\n", decrypt_string);

return 0;
}




谢谢!
...全文
810 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
dungeonsnd 2012-02-11
  • 打赏
  • 举报
回复
Correct c program:
---------------------------


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/aes.h>

int main(int argc, char** argv) {
AES_KEY aes;
unsigned char key[AES_BLOCK_SIZE]; // AES_BLOCK_SIZE = 16
unsigned char iv[AES_BLOCK_SIZE]; // init vector
unsigned char* input_string;
unsigned char* encrypt_string;
unsigned char* decrypt_string;
unsigned int len; // encrypt length (in multiple of AES_BLOCK_SIZE)
unsigned int i;
int remainder;


// check usage
if (argc != 2) {
fprintf(stderr, "%s <plain text>\n", argv[0]);
exit(-1);
}
// check input
if (strlen(argv[1])<=0) {
fprintf(stderr, "input length is zero!\n");
exit(-1);
}

// set the encryption length
len = strlen(argv[1]) + AES_BLOCK_SIZE;
remainder =strlen(argv[1])%AES_BLOCK_SIZE;
if ( 0!=remainder)
len -= remainder;

// set the input string
input_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (input_string == NULL) {
fprintf(stderr, "Unable to allocate memory for input_string\n");
exit(-1);
}
//padding! Important!
memset( input_string,len-strlen(argv[1]),len );
strncpy((char*)input_string, argv[1], strlen(argv[1]));

// Generate AES 128-bit key
memset(key, 0x01, AES_BLOCK_SIZE);

// Set encryption key
memset(iv, 0x01, AES_BLOCK_SIZE);
if (AES_set_encrypt_key(key, 128, &aes) < 0) {
fprintf(stderr, "Unable to set encryption key in AES\n");
exit(-1);
}

// alloc encrypt_string
encrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (encrypt_string == NULL) {
fprintf(stderr, "Unable to allocate memory for encrypt_string\n");
exit(-1);
}

// encrypt (iv will change)
AES_cbc_encrypt(input_string, encrypt_string, len, &aes, iv, AES_ENCRYPT);

/////////////////////////////////////

// alloc decrypt_string
decrypt_string = (unsigned char*)calloc(len, sizeof(unsigned char));
if (decrypt_string == NULL) {
fprintf(stderr, "Unable to allocate memory for decrypt_string\n");
exit(-1);
}

// Set decryption key
memset(iv, 0x01, AES_BLOCK_SIZE);
if (AES_set_decrypt_key(key, 128, &aes) < 0) {
fprintf(stderr, "Unable to set decryption key in AES\n");
exit(-1);
}

// decrypt
AES_cbc_encrypt(encrypt_string, decrypt_string, len, &aes, iv,
AES_DECRYPT);

// print
printf("input_string =%s\n", input_string);
printf("encrypted string =");
for (i=0; i<len; ++i) {
printf("%u ", encrypt_string[i]);
}
printf("\n");
printf("decrypted string =%s\n", decrypt_string);

return 0;
}

dungeonsnd 2012-02-10
  • 打赏
  • 举报
回复
Results in three types :

=================================================================

Type a:

[pro@COS56DEV-64 aestest_20120210]$ ll
-rwxrwxr-x 1 pro pro 13516 02-10 02:52 aes_usingapi
-rwxrwxr-x 1 pro pro 131 02-10 02:59 e.sh
-rwx------ 1 pro pro 6 02-10 02:54 pt.txt
-rwxrwxr-x 1 pro pro 7094 02-10 02:52 write
[pro@COS56DEV-64 aestest_20120210]$ cat e.sh
openssl enc -aes-128-cbc -e -a -in pt.txt -out ct.txt -K 01010101010101010101010101010101 -iv 01010101010101010101010101010101 -p
[pro@COS56DEV-64 aestest_20120210]$
[pro@COS56DEV-64 aestest_20120210]$ od -t d1 -A x pt.txt
000000 97 98 99 49 50 51
000006
[pro@COS56DEV-64 aestest_20120210]$ cat pt.txt
abc123[pro@COS56DEV-64 aestest_20120210]$
[pro@COS56DEV-64 aestest_20120210]$
[pro@COS56DEV-64 aestest_20120210]$ ./e.sh
salt=B03246E4FF7F0000
key=01010101010101010101010101010101
iv =01010101010101010101010101010101
[pro@COS56DEV-64 aestest_20120210]$ cat ct.txt
RXG494v+N8n/mP0GspeBsA==
[pro@COS56DEV-64 aestest_20120210]$
And I decode the ciphertext "RXG494v+N8n/mP0GspeBsA==" in with java,
Decode result is:
69 113 184 247 139 254 55 201 255 152 253 6 178 151 129 176

---------------------------------------------------------------------

Type b:

key=0x01010101010101010101010101010101
ivString=0x01010101010101010101010101010101
Encrypted bytes are:69 113 184 247 139 254 55 201 255 152 253 6 178 151 129 176
Plaintext:abc123
Ciphertext:RXG494v+N8n/mP0GspeBsA==
Decrypted:abc123

---------------------------------------------------------------------

Type c:


[pro@COS56DEV-64 aestest_20120210]$ ll
-rwxrwxr-x 1 pro pro 13516 02-10 02:52 aes_usingapi
-rw-rw-r-- 1 pro pro 25 02-10 03:01 ct.txt
-rwxrwxr-x 1 pro pro 131 02-10 02:59 e.sh
-rwx------ 1 pro pro 6 02-10 02:54 pt.txt
-rwxrwxr-x 1 pro pro 7094 02-10 02:52 write
[pro@COS56DEV-64 aestest_20120210]$ ./aes_usingapi abc123
input_string =abc123
encrypted string =26 149 138 59 4 5 252 174 150 148 74 151 222 141 77 2
decrypted string =abc123
[pro@COS56DEV-64 aestest_20120210]$
liao19795 2012-02-08
  • 打赏
  • 举报
回复
可以试试看以 EVP 的 API 来做加解秘看是否能得到相同的结果

加密
EVP_CIPHER_CTX ctx;
if(EVP_EncryptInit(&ctx,EVP_aes_256_cbc(),(unsigned char *)evp_eky2,(unsigned char *)evp_ivc2) == 0)
throw "quit";
outp = evp_encrypt_cstr(&ctx,src,&outlen);
if(outp == NULL) throw "quit";
EVP_CIPHER_CTX_cleanup(&ctx);

解秘

*(uch_tmp1+dlen) = NULL;
EVP_CIPHER_CTX ctx;
if(EVP_DecryptInit(&ctx,EVP_aes_256_cbc(),(unsigned char *)evp_eky2,(unsigned char *)evp_ivc2) == 0)
throw "quit";
int clen = EVP_CIPHER_CTX_block_size(&ctx);
int buflen = dlen+clen+1+64;
outp = new char[buflen];
if(outp == NULL) throw "quit";
memset(outp,0x0,buflen);
if(EVP_DecryptUpdate(&ctx,(unsigned char*)outp,&outlen,(unsigned char *)uch_tmp1,dlen) == 0 && outlen < ONEK_MSG_LEN/*protection*/)
throw "quit";
if(EVP_DecryptFinal_ex(&ctx,(unsigned char*)outp+outlen,&finallen) == 0)
{
throw "quit";
}
*(outp+outlen+finallen) = NULL;
EVP_CIPHER_CTX_cleanup(&ctx);
dungeonsnd 2012-02-07
  • 打赏
  • 举报
回复
改正两个笔误:

标题是
请问用调用openssl的api以及使用openssl的命令行工具进行AES加密,密文为什么不一致?

另外,方式a中的e.sh内容实际为:

openssl enc -aes-128-cbc -e -a -in pt.txt -out ct.txt -K 01010101010101010101010101010101 -iv 01010101010101010101010101010101 -p

4,451

社区成员

发帖
与我相关
我的任务
社区描述
云计算 云安全相关讨论
社区管理员
  • 云安全社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧