zoukankan      html  css  js  c++  java
  • 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命令将结果写到文件中,然后读取文件的方式实现了这个操作。如果有人解决了这个问题,希望能够联系我,也可以发送邮件,我的邮箱地址是:blithegu9123@gmail.com

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

      插入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
    ",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("
    buff_CBC:%s
    ",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]={''},buf[33]={''};
    203 
    204     data = cbcText_f+4;
    205     data[strlen(data)-1] = '';
    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     }
  • 相关阅读:
    Windows 编程
    javascript 快速入门
    python 在windows下监听键盘按键
    eleme 项目使用到的库
    lftp 快速使用
    自动测试工具
    Cookie(1)
    fillder script使用
    Boost.Hana
    Haskell语言学习笔记(50)Extra
  • 原文地址:https://www.cnblogs.com/blitheG/p/5613662.html
Copyright © 2011-2022 走看看