JS和利用openssl的object C加密得到相同的aes加密密文

  这是之前接到的一个工作内容,项目原本的登录操作是获得账号和密码以后,对密码进行一遍MD5加密,然后传递账号和密文到cgi文件。在c中获取到账户以后,从数据库中获取到密码,对密码进行一次MD5的加密,然后将该密文与post过来的密文进行对比,进行登录验证。也就是说,虽然进行了一次密码加密,但是在get/post的过程中,该密文是可见的,不符合客户的保密需求。

  经过协商以后决定,在传递的过程中不再对密码进行传输,而是将账号与session进行组合,组合成一个新的字符串以后,将密码当做密钥,进行一次AES的加密操作,以及一次MD5的加密操作生成用来POST的密文。而C中,获取到账号和密文以后,将账号和session组合,然后利用c中openssl的接口进行AES加密,MD5加密的操作获取新的密文,然后将该密文和传送得到的密文进行对比,进行登录验证。如此一来,密码的作用就仅仅是两边进行加密操作的密钥,而传送的验证字符串,更是进行了两次加密操作,大大提高了保密性。

  在工作的过程中,遇到的最大难题到并非是加密的操作,而是JS中AES加密的密文和Object C中利用openSSL的AES加密的密文总是无法相同,而直到最后也没有解决JS和openssl的结果不同的问题,幸运的是,在工作的过程中,意外发现直接利用linux的aes加密命令却能获得和JS相同的密文(echo -n "secretsecretsecret" | openssl enc -e -a -aes-256-cbc -K 12345678 -iv 12345678)。于是,在CGI中添加了调用linux命令将结果写到文件中,然后读取文件的方式实现了这个操作。如果有人解决了这个问题,希望能够联系我,也可以发送邮件,我的邮箱地址是:[email protected]

  首先是JS的,在JS的aes加密过程中,用了好几个不同的CryptoJs的库,虽然也是可以的到加密解密的实现,但是得到结果并不符合我的需要,直到使用Mark Percival 写的脚本:放上地址(https://github.com/mdp/gibberish-aes),放上代码:

 1     printf("<script type=\"text/javascript\" src=\"/bh/pjs/crypto-js-3.1.6/gibberish-aes.js\"></script>\n");
 2     printf("<script type=\"text/javascript\" src=\"/bh/pjs/crypto-js-3.1.6/jquery.md5.js\"></script>\n");
 3
 4     printf("//--------------------------------aes MD5 加密-------------------------------------------------------------------------------\n");
 5     printf("    var plaintText = document.frm.UserName.value + session_tmp;\n");
 6     printf("    var keyStr = document.frm.UserPwd.value;\n");
 7     printf("    var addZero;\n");
 8     /* 利用网上流传比较多的CryptoJS的aes加密,解密
 9     * printf("    var key = CryptoJS.enc.Utf8.parse(keyStr);\n");
10     * printf("    plaintText = ‘00112233445566778899aabbccddeeff‘;\n");
11
12     * printf("    var encryptedData = CryptoJS.AES.encrypt(plaintText, key, {\n");
13     * printf("        mode: CryptoJS.mode.ECB,\n");
14     * printf("        padding: CryptoJS.pad.Pkcs7\n");
15     * printf("        padding: CryptoJS.pad.NoPadding\n");
16     * printf("    });\n");
17     * printf("    var encryptedBase64Str = encryptedData.toString();\n");
18     * printf("    var encryptedStr = encryptedData.ciphertext.toString();\n");
19     * //解密
20     * printf("    var encryptedHexStr = CryptoJS.enc.Hex.parse(encryptedStr);\n");
21     * printf("    var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);\n");
22     * //printf("    var decryptedStr = CryptoJS.AES.decrypt(CryptoJS.lib.CipherParams.create({ ciphertext: CryptoJS.enc.Hex.parse(encryptedStr) }), key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }).toString();");
23     * printf("    var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, { \n");
24     * printf("        mode: CryptoJS.mode.ECB,\n");
25     * printf("        padding: CryptoJS.pad.Pkcs7\n");
26     * printf("    });\n");
27     * printf("    var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8); \n");
28     * printf("    console.log(\"jiemi:\"+decryptedStr); \n");
29     */
30
31     printf("\n    /*AES加密前,将密钥转为16进制,将向量为sessio,再手动补位*/\n");
32     printf("    var keyStr16 = stringToHex(keyStr);\n");
33     printf("    var keyStr_iv = session_tmp;\n");
34     printf("    console.log(\"plaint:\"+plaintText+\", len1:\"+plaintText.length+\", len2:\"+addZero+\", keyStr:\"+keyStr);\n");
35     printf("    for(addZero = 64 - keyStr16.length;addZero > 0;addZero--){\n");
36     printf("        keyStr16 = keyStr16 + \"0\";\n");
37     printf("    };\n");
38     printf("    for(addZero = 32 - keyStr_iv.length;addZero > 0;addZero--){\n");
39     printf("        keyStr_iv = keyStr_iv + \"0\";\n");
40     printf("    };\n");
41     printf("    console.log(\"plaintText\"+plaintText+\"keyStr:\"+keyStr16+\"keyStr_iv:\"+keyStr_iv);\n");
42
43     printf("\n    /*AES加密,Gibberrish私有库*/\n");
44     printf("    GibberishAES.size(256);\n");
45     printf("    var password = GibberishAES.h2a(keyStr16);\n");
46     printf("    var iv = GibberishAES.h2a(keyStr_iv);\n");
47     printf("    var plaintext = GibberishAES.s2a(plaintText);\n");
48     printf("    var plaintext_enc = GibberishAES.rawEncrypt(plaintext, password, iv);\n");
49     printf("    var plaintext_str64 = GibberishAES.Base64.encode(plaintext_enc);\n");
50     printf("    console.log(\"plaintext_str64 is :\"+plaintext_str64);\n");
51
52
53     printf("\n    /*密文转为Base64格式*/\n");
54     printf("    plaintext_str64_str = plaintext_str64.toString();\n");
55     printf("    plaintext_str64_str = plaintext_str64_str.substr(0,plaintext_str64_str.length-1);\n");
56
57     printf("\n    /*MD5 加密*/\n");
58     printf("    plaintText = $.md5(plaintext_str64_str);\n");
59     printf("    console.log(\"MD5_Str:\"+plaintText);\n");
60     printf("    if(document.frm.UserPwd.value!=\"\"){document.frm.UserPwd.value = plaintText;}\n");

  插入Object C的代码,在Object C中,我利用openssl实现了AES的ebc和cbc两种方式的加密,但是可能是openssl的加密函数与命令实现时进行的补位操作不同,导致的到的密文也是不相同的:

  1 #include <openssl/aes.h>
  2 #include <openssl/md5.h>
  3     //---------------------------------- aes 加密 -------------------------
  4
  5     /* 利用openssl接口带有的AES函数进行的ecb加密解密
  6     * char key[16],*text=NULL,temp_plaint[256],temp_session[256];
  7     * //memset(text,0,sizeof(text));
  8     * memset(temp_session,0,sizeof(temp_session));
  9     * memset(temp_plaint,0,sizeof(temp_plaint));
 10     * memset(key,0,16);
 11     * if(strlen(password)<16){
 12     *     int fixZero = 16-strlen(password);
 13     *     char *fix = "0";
 14     *     for(i =0; i<fixZero;i++){
 15     *         strcat(password,fix);
 16     *     }
 17     * }
 18     * memcpy(key,password,strlen(password));
 19
 20     * //user = "admin6291494661564876577";
 21     * //strcpy(text,user);
 22     * //text = user;
 23     * //sprintf(temp_session,"%llu",session);
 24     * //strcat(text,temp_session);
 25     * text = "super";
 26
 27     * AES_KEY aes_key;
 28     * AES_set_encrypt_key((unsigned char *)key, 128, &aes_key);
 29
 30     * int text_len = strlen(text);
 31     * int blk_num = (text_len / AES_BLOCK_SIZE) + 1;
 32     * int alg_len = blk_num * AES_BLOCK_SIZE;
 33
 34     * //uint8_t *alg_s = (typeof(alg_s)) malloc(alg_len);
 35     * unsigned char *alg_s = malloc(alg_len);
 36     * memcpy(alg_s, text, text_len);
 37     * int pad = AES_BLOCK_SIZE - text_len % AES_BLOCK_SIZE;
 38
 39     * for (i = text_len; i < alg_len; i++) {
 40     *     alg_s[i] = pad;
 41     * }
 42
 43     * int enc_len = alg_len;
 44
 45     * unsigned char *enc_s = malloc(enc_len);
 46     * memset(enc_s, 0, enc_len);
 47     * for (i = 0; i < blk_num; i++) {
 48     *     //AES_ecb_encrypt(OFFOF(alg_s, i * AES_BLOCK_SIZE), OFFOF(enc_s, i * AES_BLOCK_SIZE), &aes_key, AES_ENCRYPT);
 49     *     AES_ecb_encrypt(alg_s + i * AES_BLOCK_SIZE, enc_s + i * AES_BLOCK_SIZE, &aes_key, AES_ENCRYPT);
 50     *     trace("%02x ,%d\n",enc_s[i],i);
 51     * }
 52
 53     * int t =0;
 54     * for (i = 0; i < enc_len; i++) {
 55     *     if(t)    t += sprintf(temp_plaint + t,"%02x", enc_s[i]);
 56     *     else    t = sprintf(temp_plaint,"%02x", enc_s[i]);
 57     * }
 58
 59
 60     * //解密
 61     * AES_set_decrypt_key(key, 128, &aes_key);
 62     * int dec_len = enc_len;
 63     * uint8_t *dec_s = (typeof(dec_s)) malloc(dec_len);
 64     * for (i = 0; i < blk_num; i++) {
 65     *     AES_ecb_encrypt(OFFOF(enc_s, i * AES_BLOCK_SIZE), OFFOF(dec_s, i * AES_BLOCK_SIZE), &aes_key, AES_DECRYPT);
 66     * }
 67     */
 68
 69     /* 利用openssl接口带有的AES函数进行的cbc加密解密
 70     * unsigned char pt[64] = "secretsecretsecret";
 71     * unsigned char kt[64] = "1234567800000000000000000000000000000000000000000000000000000000";
 72     * unsigned char it[33] = "12345678000000000000000000000000";
 73     * // char pt[64] = "secretsecretsecret";
 74     * //char kt[65] = "1234567800000000000000000000000000000000000000000000000000000000";
 75     * //char it[33] = "12345678000000000000000000000000";
 76     * // char kt[64] = "12345678";
 77     * // char it[32] = "12345678";
 78
 79     * unsigned char plainText[AES_BLOCK_SIZE * 4];
 80     * unsigned char cipherText[AES_BLOCK_SIZE * 4];
 81     * unsigned char keyText[AES_BLOCK_SIZE*4];
 82     * unsigned char ivText[AES_BLOCK_SIZE*2];
 83     * unsigned char ivdecText[AES_BLOCK_SIZE*2];
 84     * AES_KEY aes_key;
 85     * char plainText[AES_BLOCK_SIZE * 4];
 86     * char cipherText[AES_BLOCK_SIZE * 4];
 87     * char keyText[AES_BLOCK_SIZE * 4];
 88     * char ivText[AES_BLOCK_SIZE * 2];
 89     * char ivdecText[AES_BLOCK_SIZE * 2];
 90
 91     * memset(plainText,0,sizeof(plainText));
 92     * memset(cipherText,0,sizeof(cipherText));
 93     * memset(keyText,0,sizeof(keyText));
 94     * memset(ivText,0,sizeof(ivText));
 95     * memset(ivdecText,0,sizeof(ivdecText));
 96
 97     * memcpy(plainText,pt,strlen(pt));
 98     * memcpy(keyText,kt,strlen(kt));
 99     * memcpy(ivText,it,strlen(it));
100     * memcpy(ivdecText,it,strlen(it));
101
102     * // strcpy(plainText,pt);
103     * // strcpy(keyText,kt);
104     * // strcpy(ivText,it);
105     * //strcpy(ivdecText,ivText);
106     * // strcpy(ivdecText,it);
107
108     * // strncpy(plainText,pt,strlen(pt));
109     * // strncpy(keyText,kt,strlen(kt));
110     * // strncpy(ivText,it,strlen(it));
111     * // strncpy(ivdecText,it,strlen(it));
112
113     * for(i = 0;i < sizeof(plainText);++i){
114     *     if(plainText[i] == 0)    break;
115     * }
116     * AES_set_encrypt_key((unsigned char*)keyText,256,&aes_key);
117     * AES_cbc_encrypt((unsigned char *)plainText,(unsigned char *)cipherText,sizeof(plainText),&aes_key,(unsigned char *)ivText,AES_ENCRYPT);
118
119     * char temw[256];
120     * for(i = 0;i < sizeof(cipherText);++i){
121     *     if(cipherText[i] == 0)    break;
122     *     sprintf(&temw[i],"%02x",cipherText[i]&0xff);
123     * }
124     * char plainba64[256];
125     * memset(plainba64,0,strlen(plainba64));
126     * int t_len;
127     * base64_encode((unsigned char *)temw,(unsigned char *)plainba64,strlen(temw),&t_len);
128     * AES_set_decrypt_key((unsigned char *)keyText,256,&aes_key);
129     * AES_cbc_encrypt((unsigned char *)cipherText,(unsigned char *)plainText,sizeof(cipherText),&aes_key,(unsigned char *)ivdecText,AES_DECRYPT);
130     * for(i = 0;i < sizeof(plainText);++i){
131     *     if(plainText[i] == 0)    break;
132     * }
133     */
134
135     /*将session,明文, key,iv合成字符串*/
136     int t = 0,cmd = 0,wlen = 0;
137     char buff_CBC[256],buff_CBC_cmd[256],userText[256],keyText[65],temp_session[256],file[256],buff_ret[1024],*cbcText_f;
138     FILE *fp = NULL;
139     SlasRes sr;
140
141     memset(keyText,0,sizeof(keyText));
142     memset(buff_ret,0,sizeof(buff_ret));
143     memset(temp_session,0,sizeof(temp_session));
144
145     /*session*/
146     sprintf(temp_session,"%llu",session);
147     strcpy(buff_CBC,temp_session);
148     strcat(buff_CBC,",");
149
150     /*mingwen*/
151     strcpy(userText,user);
152     strcat(userText,temp_session);
153     strcat(buff_CBC,userText);
154     strcat(buff_CBC,",");
155
156     /*key,转换成16进制*/
157     for(i = 0;i<strlen(password);i++){
158         if(password[i] == 0)    break;
159         if(t)    t += sprintf(keyText+t,"%02x",password[i]);
160         else    t = sprintf(keyText,"%02x",password[i]);
161     }
162     strcat(buff_CBC,keyText);
163     strcat(buff_CBC,",");
164
165     /*iv*/
166     strcat(buff_CBC,temp_session);
167     //trace("\nbuff_CBC:%s\n",buff_CBC);
168
169     cmd = CMD_PASS_CBC_ENC;
170     memcpy(buff_CBC_cmd, &cmd, sizeof(int));
171     memcpy(buff_CBC_cmd+sizeof(int),buff_CBC,strlen(buff_CBC));
172     wlen = strlen(buff_CBC)+4;
173     ret = CGIServerData((char *)buff_CBC_cmd,(int *)&wlen,&sr);
174     if(ret != 0 || sr.error || sr.state){
175         printf("error");
176         goto _END_;
177     }
178
179     strcpy(file,"/var/tmp/sess/sess_");
180     strcat(file,temp_session);
181
182     fp = fopen(file, "r");
183     if(NULL == fp){
184         printf("error");
185         unlink(file);
186         goto _END_;
187     }
188
189     fread(buff_ret,1024,1,fp);
190     cbcText_f = memmem(buff_ret,1024,"ffff",4);
191 /*    if(cbcText == NULL){
192         printf("error");
193         goto _END_;
194     }
195 */
196
197     //-------------------------------- MD5 加密---------------------------------
198
199     char *data;
200     unsigned char md[16];
201     memset(md,0,sizeof(md));
202     char tmp[3]={‘\0‘},buf[33]={‘\0‘};
203
204     data = cbcText_f+4;
205     data[strlen(data)-1] = ‘\0‘;
206
207     //trace("date:%s,%d",data,strlen(data));
208     MD5_CTX ctx;
209     MD5_Init(&ctx);
210     MD5_Update(&ctx,data,strlen(data));
211     MD5_Final(md,&ctx);
212
213     for (i = 0; i < 16; i++){
214         sprintf(tmp,"%02x",md[i]&0xff);
215         strcat(buf,tmp);
216     }
时间: 2024-11-05 19:04:44

JS和利用openssl的object C加密得到相同的aes加密密文的相关文章

小编带你简单了解一下加密技术原理:AES加密标准

随着因特网的发展,信息传输及存储的安全问题成为影响因特网应用发展的重要因素.信息安全技术也就成为了人们研究因特网应用的新热点. 信息安全的研究包括密码理论与技术.安全协议与技术.安全体系结构理论.信息对抗理论与技术.网络安全与安全产品等领域,其中密码算法的理论与实现研究是信息安全研究的基础. AES加密标准1977年1月公布的数据加密标准DES(Data Encrption Standard)经过20年的实践应用后,现在已被认为是不可靠的.1997年1月美国国家标准和技术研究所(NIST)发布了

Base64加密解密不一致导致AES加密报出javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher

报错的意思的是使用该种解密方式出入长度应为16bit的倍数,但实际的错误却不是这个,错误原因根本上是因为在http请求是特殊字符编码错误,具体数就是base64生成的+号,服务器接收时成了空格,然后导致base64解码出的字节数组有改变. 下面来还原并分析一下具体原因: 请求代码: @Test public void testHttp() throws Exception { //16进制字节数组,单纯的为了生成含有+的base64位字符串,是在试了好多遍都没试到+,只能把我错误例子的byte数

ruby AES加密解密

最近和京东合作做一个项目,在接口对接传递参数时,参数需要通过AES加密解密. 本来想到用gem 'aescrypt'处理,但是aescrypt的编码方式用的base64,而京东那边用的是16进制.所以就自己写了加密解密方法. AES 加密 def aes_encrypt(key, encrypted_string) aes = OpenSSL::Cipher::Cipher.new("AES-128-ECB") aes.encrypt aes.key = key txt = aes.u

常见的加密和解密算法—AES

一.AES加密概述 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准.2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一. Rijndae

Android数据加密之Aes加密

前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密. 什么是aes加密? 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用. 接下来我们来实际看下具体怎么实现: 对于AesUtils类常量简介: private final static String HE

AES加密类

代码: using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Utils { /// <summary> /// AES加密解密 /// </summary> public class AES { #region 加密 #region 加密字符串 /// <summary> /// AES 加密(高级加密标准,是下一代的加密算法标准,

DES加密解密与AES加密解密

目录 [1]AES加密算法和DES加密算法的效率比较[2]AES和DES加密解密代码 随着开发时间的变长,当初认为比较难的东西,现在渐渐也就变的不那么难了!特别对于一些经常很少使用的类,时间长了之后渐渐就陌生了.所以在这里写一些日后可能会用到的加密与解密. 一.AES加密算法和DES加密算法的效率比较: 下面是在网上看到的一段关于“ES加密程序和一个AES加密程序,比较两个程序进行大文件加密的效率”: 实验步骤: 实验结果: 结果分析: 当文件很小时,两个程序加密的时间差不多.但是当文件变大时,

加密/解密&利用OpenSSL构建私有CA

在互联网安全及个人隐私状况日益严峻的今天,加密技术变得尤为重要并且不可或缺.在密码雪中,加密是指将明文信息隐匿起来,使之在缺少特殊信息时不可读.本文所讲的主要是在互联网传输数据时所用的加密方式.我们都知道OSI&TCP/IP网络参考模型,通常我们会把这两个模型分为通信子网和资源子网两部分,但是在构建网络的初期,信息从发送端送达到接受端都非常困难所以在设计模型之初并没有考虑过多的安全因素,以至于通信子网和资源子网都没有涉及到数据加密的内容.为了解决这个问题,网景公司在资源子网和通信子网之间添加了半

利用openssl进行RSA加密解密

openssl是一个功能强大的工具包,它集成了众多密码算法及实用工具.我们即可以利用它提供的命令台工具生成密钥.证书来加密解密文件,也可以在利用其提供的API接口在代码中对传输信息进行加密. RSA是一个非对称加密算法.简单说来,非对称加密算法就是说加密解密一个文件需要有两个密钥,一个用来加密,为公钥,一个用来解密,为私钥.证书可以用来授权公钥的使用. 今天小研究了下openssl的rsa加密,其中主要涉及利用公钥和密钥加解密文件,没有涉及对证书的操作.想要集体了解的可以去: http://ww