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

时间:2023-02-25 08:22:43

  这是之前接到的一个工作内容,项目原本的登录操作是获得账号和密码以后,对密码进行一遍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),放上代码:

     printf("<script type=\"text/javascript\" src=\"/bh/pjs/crypto-js-3.1.6/gibberish-aes.js\"></script>\n");
printf("<script type=\"text/javascript\" src=\"/bh/pjs/crypto-js-3.1.6/jquery.md5.js\"></script>\n"); printf("//--------------------------------aes MD5 加密-------------------------------------------------------------------------------\n");
printf(" var plaintText = document.frm.UserName.value + session_tmp;\n");
printf(" var keyStr = document.frm.UserPwd.value;\n");
printf(" var addZero;\n");
/* 利用网上流传比较多的CryptoJS的aes加密,解密
* printf(" var key = CryptoJS.enc.Utf8.parse(keyStr);\n");
* printf(" plaintText = '00112233445566778899aabbccddeeff';\n"); * printf(" var encryptedData = CryptoJS.AES.encrypt(plaintText, key, {\n");
* printf(" mode: CryptoJS.mode.ECB,\n");
* printf(" padding: CryptoJS.pad.Pkcs7\n");
* printf(" padding: CryptoJS.pad.NoPadding\n");
* printf(" });\n");
* printf(" var encryptedBase64Str = encryptedData.toString();\n");
* printf(" var encryptedStr = encryptedData.ciphertext.toString();\n");
* //解密
* printf(" var encryptedHexStr = CryptoJS.enc.Hex.parse(encryptedStr);\n");
* printf(" var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr);\n");
* //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();");
* printf(" var decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, { \n");
* printf(" mode: CryptoJS.mode.ECB,\n");
* printf(" padding: CryptoJS.pad.Pkcs7\n");
* printf(" });\n");
* printf(" var decryptedStr = decryptedData.toString(CryptoJS.enc.Utf8); \n");
* printf(" console.log(\"jiemi:\"+decryptedStr); \n");
*/ printf("\n /*AES加密前,将密钥转为16进制,将向量为sessio,再手动补位*/\n");
printf(" var keyStr16 = stringToHex(keyStr);\n");
printf(" var keyStr_iv = session_tmp;\n");
printf(" console.log(\"plaint:\"+plaintText+\", len1:\"+plaintText.length+\", len2:\"+addZero+\", keyStr:\"+keyStr);\n");
printf(" for(addZero = 64 - keyStr16.length;addZero > 0;addZero--){\n");
printf(" keyStr16 = keyStr16 + \"0\";\n");
printf(" };\n");
printf(" for(addZero = 32 - keyStr_iv.length;addZero > 0;addZero--){\n");
printf(" keyStr_iv = keyStr_iv + \"0\";\n");
printf(" };\n");
printf(" console.log(\"plaintText\"+plaintText+\"keyStr:\"+keyStr16+\"keyStr_iv:\"+keyStr_iv);\n"); printf("\n /*AES加密,Gibberrish私有库*/\n");
printf(" GibberishAES.size(256);\n");
printf(" var password = GibberishAES.h2a(keyStr16);\n");
printf(" var iv = GibberishAES.h2a(keyStr_iv);\n");
printf(" var plaintext = GibberishAES.s2a(plaintText);\n");
printf(" var plaintext_enc = GibberishAES.rawEncrypt(plaintext, password, iv);\n");
printf(" var plaintext_str64 = GibberishAES.Base64.encode(plaintext_enc);\n");
printf(" console.log(\"plaintext_str64 is :\"+plaintext_str64);\n"); printf("\n /*密文转为Base64格式*/\n");
printf(" plaintext_str64_str = plaintext_str64.toString();\n");
printf(" plaintext_str64_str = plaintext_str64_str.substr(0,plaintext_str64_str.length-1);\n"); printf("\n /*MD5 加密*/\n");
printf(" plaintText = $.md5(plaintext_str64_str);\n");
printf(" console.log(\"MD5_Str:\"+plaintText);\n");
printf(" if(document.frm.UserPwd.value!=\"\"){document.frm.UserPwd.value = plaintText;}\n");

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

 #include <openssl/aes.h>
#include <openssl/md5.h>
//---------------------------------- aes 加密 ------------------------- /* 利用openssl接口带有的AES函数进行的ecb加密解密
* char key[16],*text=NULL,temp_plaint[256],temp_session[256];
* //memset(text,0,sizeof(text));
* memset(temp_session,0,sizeof(temp_session));
* memset(temp_plaint,0,sizeof(temp_plaint));
* memset(key,0,16);
* if(strlen(password)<16){
* int fixZero = 16-strlen(password);
* char *fix = "0";
* for(i =0; i<fixZero;i++){
* strcat(password,fix);
* }
* }
* memcpy(key,password,strlen(password)); * //user = "admin6291494661564876577";
* //strcpy(text,user);
* //text = user;
* //sprintf(temp_session,"%llu",session);
* //strcat(text,temp_session);
* text = "super"; * AES_KEY aes_key;
* AES_set_encrypt_key((unsigned char *)key, 128, &aes_key); * int text_len = strlen(text);
* int blk_num = (text_len / AES_BLOCK_SIZE) + 1;
* int alg_len = blk_num * AES_BLOCK_SIZE; * //uint8_t *alg_s = (typeof(alg_s)) malloc(alg_len);
* unsigned char *alg_s = malloc(alg_len);
* memcpy(alg_s, text, text_len);
* int pad = AES_BLOCK_SIZE - text_len % AES_BLOCK_SIZE; * for (i = text_len; i < alg_len; i++) {
* alg_s[i] = pad;
* } * int enc_len = alg_len; * unsigned char *enc_s = malloc(enc_len);
* memset(enc_s, 0, enc_len);
* for (i = 0; i < blk_num; i++) {
* //AES_ecb_encrypt(OFFOF(alg_s, i * AES_BLOCK_SIZE), OFFOF(enc_s, i * AES_BLOCK_SIZE), &aes_key, AES_ENCRYPT);
* AES_ecb_encrypt(alg_s + i * AES_BLOCK_SIZE, enc_s + i * AES_BLOCK_SIZE, &aes_key, AES_ENCRYPT);
* trace("%02x ,%d\n",enc_s[i],i);
* } * int t =0;
* for (i = 0; i < enc_len; i++) {
* if(t) t += sprintf(temp_plaint + t,"%02x", enc_s[i]);
* else t = sprintf(temp_plaint,"%02x", enc_s[i]);
* } * //解密
* AES_set_decrypt_key(key, 128, &aes_key);
* int dec_len = enc_len;
* uint8_t *dec_s = (typeof(dec_s)) malloc(dec_len);
* for (i = 0; i < blk_num; i++) {
* AES_ecb_encrypt(OFFOF(enc_s, i * AES_BLOCK_SIZE), OFFOF(dec_s, i * AES_BLOCK_SIZE), &aes_key, AES_DECRYPT);
* }
*/ /* 利用openssl接口带有的AES函数进行的cbc加密解密
* unsigned char pt[64] = "secretsecretsecret";
* unsigned char kt[64] = "1234567800000000000000000000000000000000000000000000000000000000";
* unsigned char it[33] = "12345678000000000000000000000000";
* // char pt[64] = "secretsecretsecret";
* //char kt[65] = "1234567800000000000000000000000000000000000000000000000000000000";
* //char it[33] = "12345678000000000000000000000000";
* // char kt[64] = "12345678";
* // char it[32] = "12345678"; * unsigned char plainText[AES_BLOCK_SIZE * 4];
* unsigned char cipherText[AES_BLOCK_SIZE * 4];
* unsigned char keyText[AES_BLOCK_SIZE*4];
* unsigned char ivText[AES_BLOCK_SIZE*2];
* unsigned char ivdecText[AES_BLOCK_SIZE*2];
* AES_KEY aes_key;
* char plainText[AES_BLOCK_SIZE * 4];
* char cipherText[AES_BLOCK_SIZE * 4];
* char keyText[AES_BLOCK_SIZE * 4];
* char ivText[AES_BLOCK_SIZE * 2];
* char ivdecText[AES_BLOCK_SIZE * 2]; * memset(plainText,0,sizeof(plainText));
* memset(cipherText,0,sizeof(cipherText));
* memset(keyText,0,sizeof(keyText));
* memset(ivText,0,sizeof(ivText));
* memset(ivdecText,0,sizeof(ivdecText)); * memcpy(plainText,pt,strlen(pt));
* memcpy(keyText,kt,strlen(kt));
* memcpy(ivText,it,strlen(it));
* memcpy(ivdecText,it,strlen(it)); * // strcpy(plainText,pt);
* // strcpy(keyText,kt);
* // strcpy(ivText,it);
* //strcpy(ivdecText,ivText);
* // strcpy(ivdecText,it); * // strncpy(plainText,pt,strlen(pt));
* // strncpy(keyText,kt,strlen(kt));
* // strncpy(ivText,it,strlen(it));
* // strncpy(ivdecText,it,strlen(it)); * for(i = 0;i < sizeof(plainText);++i){
* if(plainText[i] == 0) break;
* }
* AES_set_encrypt_key((unsigned char*)keyText,256,&aes_key);
* AES_cbc_encrypt((unsigned char *)plainText,(unsigned char *)cipherText,sizeof(plainText),&aes_key,(unsigned char *)ivText,AES_ENCRYPT); * char temw[256];
* for(i = 0;i < sizeof(cipherText);++i){
* if(cipherText[i] == 0) break;
* sprintf(&temw[i],"%02x",cipherText[i]&0xff);
* }
* char plainba64[256];
* memset(plainba64,0,strlen(plainba64));
* int t_len;
* base64_encode((unsigned char *)temw,(unsigned char *)plainba64,strlen(temw),&t_len);
* AES_set_decrypt_key((unsigned char *)keyText,256,&aes_key);
* AES_cbc_encrypt((unsigned char *)cipherText,(unsigned char *)plainText,sizeof(cipherText),&aes_key,(unsigned char *)ivdecText,AES_DECRYPT);
* for(i = 0;i < sizeof(plainText);++i){
* if(plainText[i] == 0) break;
* }
*/ /*将session,明文, key,iv合成字符串*/
int t = ,cmd = ,wlen = ;
char buff_CBC[],buff_CBC_cmd[],userText[],keyText[],temp_session[],file[],buff_ret[],*cbcText_f;
FILE *fp = NULL;
SlasRes sr; memset(keyText,,sizeof(keyText));
memset(buff_ret,,sizeof(buff_ret));
memset(temp_session,,sizeof(temp_session)); /*session*/
sprintf(temp_session,"%llu",session);
strcpy(buff_CBC,temp_session);
strcat(buff_CBC,","); /*mingwen*/
strcpy(userText,user);
strcat(userText,temp_session);
strcat(buff_CBC,userText);
strcat(buff_CBC,","); /*key,转换成16进制*/
for(i = ;i<strlen(password);i++){
if(password[i] == ) break;
if(t) t += sprintf(keyText+t,"%02x",password[i]);
else t = sprintf(keyText,"%02x",password[i]);
}
strcat(buff_CBC,keyText);
strcat(buff_CBC,","); /*iv*/
strcat(buff_CBC,temp_session);
//trace("\nbuff_CBC:%s\n",buff_CBC); cmd = CMD_PASS_CBC_ENC;
memcpy(buff_CBC_cmd, &cmd, sizeof(int));
memcpy(buff_CBC_cmd+sizeof(int),buff_CBC,strlen(buff_CBC));
wlen = strlen(buff_CBC)+;
ret = CGIServerData((char *)buff_CBC_cmd,(int *)&wlen,&sr);
if(ret != || sr.error || sr.state){
printf("error");
goto _END_;
} strcpy(file,"/var/tmp/sess/sess_");
strcat(file,temp_session); fp = fopen(file, "r");
if(NULL == fp){
printf("error");
unlink(file);
goto _END_;
} fread(buff_ret,,,fp);
cbcText_f = memmem(buff_ret,,"ffff",);
/* if(cbcText == NULL){
printf("error");
goto _END_;
}
*/ //-------------------------------- MD5 加密--------------------------------- char *data;
unsigned char md[];
memset(md,,sizeof(md));
char tmp[]={'\0'},buf[]={'\0'}; data = cbcText_f+;
data[strlen(data)-] = '\0'; //trace("date:%s,%d",data,strlen(data));
MD5_CTX ctx;
MD5_Init(&ctx);
MD5_Update(&ctx,data,strlen(data));
MD5_Final(md,&ctx); for (i = ; i < ; i++){
sprintf(tmp,"%02x",md[i]&0xff);
strcat(buf,tmp);
}

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

  1. 你真的了解字典&lpar;Dictionary&rpar;吗&quest; C&num; Memory Cache 踩坑记录 &period;net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的&period;NET开源项目 &period;net 笔试面试总结&lpar;3&rpar; &period;net 笔试面试总结&lpar;2&rpar; 依赖注入 C&num; RSA 加密 C&num;与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  2. ruby AES加密解密

    最近和京东合作做一个项目,在接口对接传递参数时,参数需要通过AES加密解密. 本来想到用gem 'aescrypt'处理,但是aescrypt的编码方式用的base64,而京东那边用的是16进制.所以 ...

  3. Java 关于密码处理的工具类&lbrack;MD5编码&rsqb;&lbrack;AES加密&sol;解密&rsqb;

    项目中又遇到了加密问题,又去翻了半天,然后做测试,干脆就把常用的两类小结一下. 1.第一种所谓的MD5加密 其实也不算加密,只是基于Hash算法的不可逆编码而已,等于说,一旦经过MD5处理,是不可能从 ...

  4. &period;Net Core AES加密解密

    一.AES说明 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦*采用的一种区块加密标准.这个标准用来替 ...

  5. Android数据加密之Aes加密

    前言: 项目中除了登陆,支付等接口采用rsa非对称加密,之外的采用aes对称加密,今天我们来认识一下aes加密. 其他几种加密方式: Android数据加密之Rsa加密 Android数据加密之Aes ...

  6. AES加密类

    代码: using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace ...

  7. DES加密解密与AES加密解密

    随着开发时间的变长,当初认为比较难的东西,现在渐渐也就变的不那么难了!特别对于一些经常很少使用的类,时间长了之后渐渐就陌生了.所以在这里写一些日后可能会用到的加密与解密. 一.AES加密算法和DES加 ...

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

    一.AES加密概述 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦*采用的一种区块加密标准.这个标准用 ...

  9. php AES加密解密的例子

    一共有两个文件:AES.php(aes算法类文件)和aesDemo.php(应用实例文件) aesDemo.php:例子, <?php require_once('./AES.php'); // ...

随机推荐

  1. 批量设置select为默认项

    app.$form.find("select").prop("selectedIndex", 0);

  2. Hibernate2

    计应134(实验班) 杨伟 Hibernate 中提供了两级Cache(高速缓冲存储器),第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存.这一级别的缓存由hibernate管理的,一 ...

  3. 一个好用的Log管理类

    public class L { private static String className; //所在的类名 private static String methodName; //所在的方法名 ...

  4. unity3d旋转摄像机脚本

    void Update () { )) { if (axes == RotationAxes.MouseXAndY) { // Read the mouse input axis rotationX ...

  5. libevent使用之安装(一)

    1.下载安装包,在官网http://www.monkey.org/~provos/libevent/下载 2.解压 运行命令: tar zxvf libevent-2.0.10-stable.tar. ...

  6. hdu 5640 King&&num;39&semi;s Cake(模拟)

    Problem Description   It is the king's birthday before the military parade . The ministers prepared ...

  7. Python&lowbar;语法和界面设计

    http://www.runoob.com/python/python-gui-tkinter.html  http://www.python-course.eu/python_tkinter.php

  8. 论文阅读笔记五十一:CenterNet&colon; Keypoint Triplets for Object Detection&lpar;CVPR2019&rpar;

    论文链接:https://arxiv.org/abs/1904.08189 github:https://github.com/Duankaiwen/CenterNet 摘要 目标检测中,基于关键点的 ...

  9. 7、LwIP协议规范翻译——网络接口

    7.网络接口 在lwIP中,物理网络硬件设备驱动是由类似于BSD网络接口结构表示.网络接口结构如图5所示.网络接口被保存在一个全局的链表中,通过结构体中的next指针来完成链表的链接. 每个网络接口都 ...

  10. 1&period;5 pycharm使用

    1.5 pycharm使用 前言    在写脚本之前,先要找个顺手的写脚本工具.python是一门解释性编程语言,所以一般把写python的工具叫解释器.写python脚本的工具很多,小编这里就不一一 ...