JavaScript实现AES算法加密和解密
JavaScript的加密和解密用的是google的CryptoJS库。本文以AES/ECB/NoPadding为例展示AES加密和解密的方法。
需要下载CryptoJS库,下载地址如下:
https://github.com/sytelus/CryptoJS
需要引入库文件:
<script src="./CryptoJS-master/rollups/aes.js"></script>
<script src="./CryptoJS-master/components/mode-ecb.js"></script>
<script src="./CryptoJS-master/components/pad-nopadding.js"></script>
加密方法:
function encrypt(str) {
var decArray = hexStrToDecArray(str);
var wordArray = int8parse(decArray);
var encrypted = CryptoJS.AES.encrypt(wordArray, aesKeyBytes(), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});
return wordArrayToHexStr(encrypted.ciphertext.words);
}
这个方法传入的是十六进制字符串,格式为"AA BB CC DD EE FF";
hexStrToDecArray()方法用来将十六进制字符串转换成十进制数字的数组;
int8parse()方法用来将十进制数字转换成CryptoJS所需要的wordArray数组;
最后,encrypt()方法加密得到的是一个wordArray数组,wordArrayToHexStr()再将其解析成十六进制字符串。
解密方法:
function decrypt(str) {
var decArray = hexStrToDecArray(str);
var wordArray = int8parse(decArray);
var base64Str = CryptoJS.enc.Base64.stringify(wordArray);
var decrypted = CryptoJS.AES.decrypt(base64Str, aesKeyBytes(), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});
return wordArrayToHexStr(decrypted.words);
}
解密方法同加密方法类似,但是CryptoJS.AES.decrypt()方法需要传入Base64格式的加密字符串,因此这里需要先使用CryptoJS.enc.Base64.stringify()方法做一次转换。
以下是完整的Demo代码:
<!DOCTYPE html>
<html>
<head>
<script src="./CryptoJS-master/rollups/aes.js"></script>
<script src="./CryptoJS-master/components/mode-ecb.js"></script>
<script src="./CryptoJS-master/components/pad-nopadding.js"></script>
<script>
function encryptText() {
var plain = document.getElementById("plain").value;
console.log("plain: " + plain);
var encrypted = encrypt(plain);
console.log("encrypted: " + encrypted);
document.getElementById("encrypted").value = encrypted;
} function decryptText() {
var encrypted = document.getElementById("todecrypt").value;
console.log("encrypted: " + encrypted);
var decrypted = decrypt(encrypted);
console.log("decrypted: " + decrypted);
document.getElementById("decrypted").value = decrypted;
} // 加解密用到的密钥
function aesKeyBytes() {
var key_Int = new Int8Array([65, 144, 48, 53, 18, 52, 86, 120, 131, 116, 124, 139, 237, 203, 169, 135]);
var keyBytes = int8parse(key_Int);
return keyBytes;
} // 十六进制字符串数组,个数如果不足16整数倍则补0
function hexTo16Hex(str) {
var diff = 16 - (str.length + 1) / 3 % 16;
for(var i = 0; i < diff; i++) {
str = str + " 00";
}
return str;
} // AES加密
function encrypt(str) {
var decArray = hexStrToDecArray(str);
var wordArray = int8parse(decArray);
var encrypted = CryptoJS.AES.encrypt(wordArray, aesKeyBytes(), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});
return wordArrayToHexStr(encrypted.ciphertext.words);
} // AES解密
function decrypt(str) {
var decArray = hexStrToDecArray(str);
var wordArray = int8parse(decArray);
var base64Str = CryptoJS.enc.Base64.stringify(wordArray);
var decrypted = CryptoJS.AES.decrypt(base64Str, aesKeyBytes(), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.NoPadding
});
return wordArrayToHexStr(decrypted.words);
} // 构建WordArray对象
function int8parse(u8arr) {
var len = u8arr.length;
var words = [];
for (var i = 0; i < len; i++) {
words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
}
return CryptoJS.lib.WordArray.create(words, len);
} // 十六进制字符串(空格分割)转成十进制数字的数组
function hexStrToDecArray(str) {
var strArray = str.split(" ");
var decArray = [];
for(var i = 0; i < strArray.length; i++) {
decArray.push(parseInt(strArray[i], 16));
}
return arrayTo16Array(decArray);
} // 十进制数组转成十六进制字符串
function decArrayToHexStr(array) {
var hexStr = "";
for(var i = 0; i < array.length; i++) {
var str = array[i].toString(16).toUpperCase();
if (str.length < 2) {
str = "0" + str;
}
hexStr = hexStr + str + " ";
}
return hexStr.substr(0, hexStr.length - 1);
} // word类型的十进制数组转成十六进制字符串
function wordArrayToHexStr(array) {
var hexStr = "";
for(var i = 0; i < array.length; i++) {
var num = array[i];
if (num < 0) {
num = array[i] + 0x100000000;
}
var str = num.toString(16).toUpperCase();
var fullStr = str;
if (str.length < 8) {
for(var j = 0; j < 8 - str.length; j++) {
fullStr = "0" + fullStr;
}
}
hexStr = hexStr + fullStr;
}
var ret = "";
for(var i = 0; i < hexStr.length; i += 2) {
ret = ret + hexStr.substr(i, 2) + " "
}
return ret.substr(0, ret.length - 1);
} // 数组元素个数必须是16的整数倍,不足的在后面补0
function arrayTo16Array(array) {
var len = array.length;
var distLen = parseInt((array.length - 1) / 16) * 16 + 16;
for(var i = array.length; i < distLen; i++) {
array[i] = 0;
}
return array;
}
</script>
</head>
<body>
<h1>加解密测试</h1>
AES128,ECB模式,PaddingModeZeros,不足部分补0
<br>
<input id="plain" type="text" style="width:500px; height:20px;"/>
<button type="button" onclick="encryptText()">加密</button>
<input id="encrypted" type="text" style="width:500px; height:20px;" />
<br>
<br>
<br>
<input id="todecrypt" type="text" style="width:500px; height:20px;"/>
<button type="button" onclick="decryptText()">解密</button>
<input id="decrypted" type="text" style="width:500px; height:20px;" />
</body>
</html>
在浏览器中打开之后效果如下:
输入要加密或解密的字符串,点击加密/解密按钮即可。
JavaScript实现AES算法加密和解密的更多相关文章
- ORACLE 字段AES算法加密、解密
ORACLE 字段AES算法加密.解密(解决中文乱码问题)2014年02月12日 17:13:37 华智互联 阅读数:97971.加解密函数入口 CREATE OR REPLACE FUNCTION ...
- JAVA实现AES的加密和解密算法
原文 JAVA实现AES的加密和解密算法 import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import ja ...
- C#与Java互通AES算法加密解密
/// <summary>AES加密</summary> /// <param name="text">明文</param> /// ...
- .NET与Java互通AES算法加密解密
/// <summary>AES加密</summary> /// <param name="text">明文</param> /// ...
- AES对称加密和解密
package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingException; impo ...
- java的AES对称加密和解密,有偏移量
import java.math.BigDecimal; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; i ...
- AES对称加密和解密(转)
AES对称加密和解密 package demo.security; import java.io.IOException; import java.io.UnsupportedEncodingExce ...
- AES块加密与解密
AES块加密与解密 解密目标 在CBC和CTR两种模式下分别给出十篇加密的样例密文,求解密一篇特定的密文 解密前提 全部密文及其加密使用的key都已给出 加密的方法遵循AES的标准 解密过程分析 实验 ...
- java sm4国密算法加密、解密
java sm4国密算法加密.解密 CreationTime--2018年7月5日09点20分 Author:Marydon 1.准备工作 所需jar包: bcprov-jdk15on-1.59. ...
随机推荐
- python 面向对象七 property() 函数和@property 装饰符
一.property引入 为了使对象的属性不暴露给调用者和进行属性值检查,设置了访问属性的接口函数,使用函数访问属性,并可以在函数内部检查属性. >>> class Student( ...
- bzoj 4521: [Cqoi2016]手机号码【数位dp】
比较基础的数位dp,dfs的时候带上上一位,上上位,是否已经有连续3个相同位,是否有4,是否有8即可 但是要注意两点(在洛谷上一直70) 当l=1e10的时候,直接输出clc(r)即可,因为如果再减去 ...
- Logstash读取文本信息并写入到ES
Logstash读取文本信息并写入到ES 前提是ELK安装没问题 进入到logstash安装目录下的bin目录(我的logstash安装目录:/usr/local/) [root@es1 bin]# ...
- c语言程序设计案例教程(第2版)笔记(一)—零散、输入输出、最小公倍数、选择排序、冒泡排序
零散知识点: 非格式化输入输出:getchar().putchar() 格式化输入输出 :scanf().printf() 字符串输入输出 :gets() 或 scanf().puts() 或 ...
- dalvik.system.VMRuntime 隐藏api的迷惑
[Android UI界面]关于dalvik.system.VMRuntime 的 使用迷惑 我也遇到了相同问题.不知楼主现在解决了没有? 回答1: [Android UI界面]关于dalvik.sy ...
- Object流
- 关于java的arrays数组排序示例AJPFX的分享
Java API对Arrays类的说明是:此类包含用来操作数组(比如排序和搜索)的各种方法. 1.对基本数据类型的数组的排序 说明: (1)Arrays类中的sort()使用的是“经过调优的快速排序法 ...
- 电商网站项目Angular+Bootstrap+Node+Express+Mysql
1.登陆 2.注册 3.主页 4.购物车 5.管理中心 6.文件上传 代码: https://github.com/Carol0311/min_Shop.git 后期会持续进行功能更新以及开发阶段遇到 ...
- Farseer.net轻量级ORM开源框架 V1.2版本升级消息
V1.1到V1.2的更新,重构了很多类及方法,其中主要做了性能优化(取消所有反射,使用表达式树+缓存).解耦了SQL生成层(没有实体.队列的依赖,所有数据均通过表达式树传递解析) 先上内部更新历史记录 ...
- Android(java)学习笔记194:ContentProvider使用之获得系统联系人信息02(掌握)
1.重要: 系统删除一个联系人,默认情况下并不是把这个联系人直接删除掉了,只是做了一个标记,标记为被删除. 2.前面一讲说过了如何获取系统联系人信息(通过ContentProvider),获取联系人信 ...