【前端Js】高级加密解密标准AES加密(Javascript代码实现)
来源:互联网 发布:windowsphone软件格式 编辑:程序博客网 时间:2024/06/07 05:55
高级加密标准(Advanced Encryption Standard,AES)
是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。Rijndael加密算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael之命名之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhinedoll"。)
AES的区块长度固定为128比特,密钥长度则可以是128,192或256比特;而Rijndael使用的密钥和区块长度均可以是128,192或256比特。
AES加密有很多轮的重复和变换。大致步骤如下:
1、密钥扩展(KeyExpansion),
2、初始轮(Initial Round),
3、重复9轮(Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,
4、最终轮(Final Round),最终轮没有MixColumns。
4种操作:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)。
1 字节代替
字节代替的主要功能是通过S盒完成一个字节到另外一个字节的映射。
2 行移位
行移位的功能是实现一个4x4矩阵内部字节之间的置换。
3 列混淆
列混淆:利用GF(2^8)域上算术特性的一个代替。
4 轮密码加
这个操作相对简单,其依据的原理是“任何数和自身的异或结果为0”。加密过程中,每轮的输入与每轮密钥异或一次;因此,解密时再异或上该轮的密钥即可恢复输入。
5 密钥扩展
密钥扩展过程说明:
1) 将初始密钥以列为主,转化为4个32 bits的字,分别记为w[0…3];
2) 按照如下方式,依次求解w[j],其中j是整数并且属于[4,43];
3) 若j%4=0,则w[j]=w[j-4]⊕g(w[j-1]),否则w[j]=w[j-4]⊕w[j-1];
函数g的流程说明:
4) 将w循环左移一个字节;
5) 分别对每个字节按S盒进行映射;
6) 与32 bits的常量(RC[j/4],0,0,0)进行异或,RC是一个一维数组,其值如下。(RC的值只需要有10个,而此处用了11个,实际上RC[0]在运算中没有用到,增加RC[0]是为了便于程序中用数组表示。由于j的最小取值是4,j/4的最小取值则是1,因此不会产生错误。)
RC = {00, 01, 02, 04, 08, 10, 20, 40, 80, 1B, 36}
Js核心代码:
// inverse process column infofunction InvMixColumns(state){ var col; var c0, c1, c2, c3; for( col=0; col<4; col++ ) { c0 = state[I(0,col)]; c1 = state[I(1,col)]; c2 = state[I(2,col)]; c3 = state[I(3,col)]; // do inverse mixing, and put back into array state[I(0,col)] = aes_mul(0x0e,c0) ^ aes_mul(0x0b,c1) ^ aes_mul(0x0d,c2) ^ aes_mul(0x09,c3); state[I(1,col)] = aes_mul(0x09,c0) ^ aes_mul(0x0e,c1) ^ aes_mul(0x0b,c2) ^ aes_mul(0x0d,c3); state[I(2,col)] = aes_mul(0x0d,c0) ^ aes_mul(0x09,c1) ^ aes_mul(0x0e,c2) ^ aes_mul(0x0b,c3); state[I(3,col)] = aes_mul(0x0b,c0) ^ aes_mul(0x0d,c1) ^ aes_mul(0x09,c2) ^ aes_mul(0x0e,c3); } return state;}// insert subkey informationfunction AddRoundKey( state, w, base ){ var col; for( col=0; col<4; col++ ) { state[I(0,col)] ^= w[base+col*4]; state[I(1,col)] ^= w[base+col*4+1]; state[I(2,col)] ^= w[base+col*4+2]; state[I(3,col)] ^= w[base+col*4+3]; } return state;}// return a transposed arrayfunction transpose( msg ){ var row, col; var state = new Array( 16 ); for( row=0; row<4; row++ ) for( col=0; col<4; col++ ) state[I(row,col)] = msg[I(col,row)]; return state;}// final AES statevar AES_output = new Array(16);// format AES output// -- uses the global array DES_outputfunction format_AES_output(){ var i; var bits; var str=""; // what type of data do we have to work with? if ( document.stuff.outtype[0].checked ) { // convert each set of bits back to ASCII for( i=0; i<16; i++ ) str += String.fromCharCode( AES_output[i] ); } else { // output hexdecimal data (insert spaces) str = cvt_hex8( AES_output[0] ); for( i=1; i<16; i++ ) { str += " " + cvt_hex8( AES_output[i] ); } } // copy to textbox document.stuff.outdata.value = str;}
所有核心代码secret.js【点击下载】
Html测试页面:
<BODY>2001年Rijndael算法成为高级加密标准(Advanced Encryption Standard,AES)的获胜者。这个标准用来替代原先的DES,AES的区块长度固定为128比特,密钥长度则可以是128,192或256比特;而Rijndael使用的密钥和区块长度均可以是128,192或256比特。<P><form name="stuff"><br>输入一个16个ASCII字符以内的字符串。<p><table><tr> <td>输入信息:</td> <td><input type="text" name="indata" size="50" value="abcdefghijklmnop" /></td> <td><input type="radio" name="intype" checked>ASCII <input type="radio" name="intype">十六进制 </td></tr><tr> <td>密钥</td> <td><select name="key"> <OPTION value="0f1571c947d9e8590cb7add6af7f6798">0f 15 71 c9 47 d9 e8 59 0c b7 ad d6 af 7f 67 98</OPTION> <OPTION value="f6cc34cdc555c5418254260203ad3ecd">f6 cc 34 cd c5 55 c5 41 82 54 26 02 03 ad 3e cd</OPTION> <OPTION value="3070971ab7ce45063fd2573f49f5420d">30 70 97 1a b7 ce 45 06 3f d2 57 3f 49 f5 42 0d</OPTION> <OPTION value="a9aa1f9fd153bcb6c7834212c51f5c41">a9 aa 1f 9f d1 53 bc b6 c7 83 42 12 c5 1f 5c 41</OPTION> <OPTION value="d2f60c436e7ccebb8eaceaf3f86c8bad">d2 f6 0c 43 6e 7c ce bb 8e ac ea f3 f8 6c 8b ad</OPTION> <OPTION value="2b7e151628aed2a6abf7158809cf4f3c">2b 7e 15 16 28 ae d2 a6 ab f7 15 88 09 cf 4f 3c</OPTION> </SELECT></TD> <TD></TD></TR><TR> <TD colspan=3 align=center> <INPUT type="button" value="加密" onClick="aes_encrypt();" /> <INPUT type="button" value="解密" onClick="aes_decrypt();" /> </TD></TR><TR> <TD>输出信息:</TD> <TD><INPUT type="text" name="outdata" size="50" /></TD> <TD><INPUT type="radio" name="outtype" onClick="format_AES_output();">ASCII <INPUT type="radio" name="outtype" checked onClick="format_AES_output();">十六进制 </TD></TR></TABLE><hr>细节:<BR><TEXTAREA name="details" id="details" rows="25" cols="90"></TEXTAREA></FORM></BODY>
显示页面
Java验证
private byte[] keys = { 0x0f,0x15,0x71,(byte)0xc9, 0x47,(byte)0xd9,(byte)0xe8,0x59, 0x0c,(byte)0xb7,(byte)0xad,(byte)0xd6,(byte)0xaf,0x7f,0x67,(byte)0x98 }; //KeyGenerator 提供对称密钥生成器的功能,支持各种算法 private KeyGenerator keygen; //SecretKey 负责保存对称密钥 private SecretKey deskey; //Cipher负责完成加密或解密工作 private Cipher c; //该字节数组负责保存加密的结果 private byte[] cipherByte; public AesDemo() throws NoSuchAlgorithmException, NoSuchPaddingException{ Security.addProvider(new com.sun.crypto.provider.SunJCE());// //实例化支持DES算法的密钥生成器(算法名称命名需按规定,否则抛出异常)// keygen = KeyGenerator.getInstance("AES");// //生成密钥// deskey = keygen.generateKey(); deskey= new SecretKeySpec(keys, "AES"); System.out.println("密钥:" + UBytes.toHexString(deskey.getEncoded())); //生成Cipher对象,指定其支持的DES算法 c = Cipher.getInstance("AES/ECB/NOPADDING"); // PKCS5Padding } /** * 对字符串加密 * * @param str * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Encrytor(String str) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,ENCRYPT_MODE表示加密模式 c.init(Cipher.ENCRYPT_MODE, deskey); byte[] src = str.getBytes(); System.out.println("明文:" + UBytes.toHexString(src)); // 加密,结果保存进cipherByte cipherByte = c.doFinal(src); System.out.println("密文:" + UBytes.toHexString(cipherByte)); return cipherByte; } /** * 对字符串解密 * * @param buff * @return * @throws InvalidKeyException * @throws IllegalBlockSizeException * @throws BadPaddingException */ public byte[] Decryptor(byte[] buff) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { // 根据密钥,对Cipher对象进行初始化,DECRYPT_MODE表示加密模式 c.init(Cipher.DECRYPT_MODE, deskey); cipherByte = c.doFinal(buff); return cipherByte; } /** * @param args * @throws NoSuchPaddingException * @throws NoSuchAlgorithmException * @throws BadPaddingException * @throws IllegalBlockSizeException * @throws InvalidKeyException */ public static void main(String[] args) throws Exception { AesDemo de1 = new AesDemo(); String msg ="abcdefghijklmnop"; byte[] encontent = de1.Encrytor(msg); byte[] decontent = de1.Decryptor(encontent); System.out.println("解密:" + UBytes.toHexString(decontent)); System.out.println("明文是:" + msg); System.out.println("加密后:" + new String(encontent)); System.out.println("解密后:" + new String(decontent)); }
结果:
密钥:0F 15 71 C9 47 D9 E8 59 0C B7 AD D6 AF 7F 67 98 明文:61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 密文:11 0A AF F3 F2 D5 6C 9E 69 1A 95 A5 2E 19 28 EB 解密:61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 明文是:abcdefghijklmnop解密后:abcdefghijklmnop
- 【前端Js】高级加密解密标准AES加密(Javascript代码实现)
- 高级加密标准AES加密(Javascript实现)
- Javascript实现前端AES加密解密功能
- AES加密解密代码实现
- 高级加密标准(AES)中的加密和解密
- AES高级加密标准加密
- AES 高级加密标准
- JAVA实现AES加密[高级加密标准(AdvancedEncryptionStandard,AES)]
- AES加密解密代码
- javascript实现AES加密解密(ECB&CBC)
- java和js实现aes加密解密
- java和js实现aes加密解密
- java和js实现aes加密解密
- AES前端加密后端解密
- PHP开发过程中AES加密解密问题 js前端AES加密,PHP解密
- 高级加密标准(AES)简介
- 【加密解密】-AES加密解密实现
- 【加密解密】-AES加密解密实现
- 2016 年 7 个顶级 JavaScript 框架
- 1052. Linked List Sorting (25) PAT甲级
- python 的yagamil第三方模块使用方法
- linux的top命令参数详解
- chrome应用开发API之chrome.fileSystem
- 【前端Js】高级加密解密标准AES加密(Javascript代码实现)
- 如何判断一个数是否是质数(C语言)-超详细
- ARP协议的报文格式
- JavaSE_20th_常用类——枚举类型
- BarTender如何打印额外字符
- HDU - 1241 dfs or bfs [kuangbin带你飞]专题一
- uname命令获取Linux系统详情
- map的[]操作
- 脱壳-ASPack 2.12