这是之前接到的一个工作内容,项目原本的登录操作是获得账号和密码以后,对密码进行一遍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. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

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

  2. js逆向之AES加密

    故事背景: 在获取某网站接口数据时,发现其请求的 headers 中的参数 使用了 AES算法加密 ,并对其进行校验,在此简单记录下自己的踩坑历程. AES简介: 高级加密标准(AES,Advance ...

  3. ruby AES加密解密

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

  4. Java 关于密码处理的工具类[MD5编码][AES加密/解密]

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

  5. .Net Core AES加密解密

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

  6. Android数据加密之Aes加密

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

  7. AES加密类

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

  8. DES加密解密与AES加密解密

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

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

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

随机推荐

  1. 优秀的弹窗插件 jquery.lightbox_me.js

    项目地址: https://github.com/buckwilson/Lightbox_me用法:http://buckwilson.me/lightboxme/ var opt = { 'cent ...

  2. ORACLE数据库多表关联查询效率问题解决方案

    最近在做项目中遇到多表关联查询排序的效率问题(5张以上40W+数据的表),查询一次大概要20多秒,经过一番苦思冥想,处理方案如下: 1.软件设计初期,需要一对一关联的表应该设计在一张大表里,这样虽然字 ...

  3. Sample rate 理解

    在Gnuradio中,我们可以看到很多模块中都有Sample rate 这个概念 然后看到一个说明 Any processing block's 'Sample Rate' parameter is ...

  4. Chapter 2. OpenSSL的安装和配置学习笔记

    Chapter 2. OpenSSL的安装和配置学习笔记 2.1 在linux上面安装OpenSSL我还是做点No paper事情比较在行,正好和老师的课程接轨一下.以前尝试过在Windows上面安装 ...

  5. Web前端开发人员和设计师必读文章推荐

    推荐一个很好的学习资源: Web前端开发人员和设计师必读文章推荐[系列一] Web前端开发人员和设计师必读文章推荐[系列二] Web前端开发人员和设计师必读文章推荐[系列三] Web前端开发人员和设计 ...

  6. Substrings

    hdu1238:http://acm.hdu.edu.cn/showproblem.php?pid=1238 题意:给你n个串,求一个子串,这个子串在所有串中都出现,或者在逆串中出现.求最大的这个子串 ...

  7. Delphi会自动初始化全局变量和类成员变量,但不初始化局部变量

    If you don't explicitly initialize a global variable, the compiler initializes it to 0. Object insta ...

  8. Android 手机上安装并运行 Ubuntu 12.04(转,没实测)

    设备需要root权限,并且安装了BusyBox最小 1GHz 处理器(推荐)Android 系统版本 2.1 或以上Android 设备需要自定义的ROM固件SD卡至2.5GB (安装大映像的需要3. ...

  9. 【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法

    原文网址:http://blog.csdn.net/harvic880925/article/details/40475367 前言:前一篇文章给大家展示了传统的Listview的写法,但有的时候我们 ...

  10. 【转】android MSM8974 上DeviceTree简介----不错

    原文网址:http://blog.csdn.net/dongwuming/article/details/12784213 简介 主要功能是不在代码中硬编码设备信息,而是用专门的文件来描述.整个系统的 ...