• 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     }
  • 相关阅读:
    The three toppaying tech roles in 2022 and the skills you need to land them
    Using serilog with azure application insights and .Net core
    炉石传说 佣兵战纪 奥特兰克山谷
    跑步减肥 不同年龄要有不同配速
    聊聊微软面试 超哥的地盘
    风暴英雄上传录像举报
    Node.js Express 框架 规格严格
    redis查询key的数量 规格严格
    MySQL DATE_FORMAT() 函数 规格严格
    fastjson/jackson 转 json Boolean布尔类型 is丢失问题 规格严格
  • 原文地址:https://www.cnblogs.com/blitheG/p/5613662.html
Copyright © 2020-2023  润新知