【前端Js】高级加密解密标准AES加密(Javascript代码实现)
2017-02-13 09:54
961 查看
高级加密标准(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核心代码:
所有核心代码secret.js【点击下载】
Html测试页面:
显示页面
![](http://img.blog.csdn.net/20170213094647293?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGo3amF5/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
Java验证
结果:
高级加密标准(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 info function 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 information function 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 array function 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 state var AES_output = new Array(16); // format AES output // -- uses the global array DES_output function 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
相关文章推荐
- JavaScript实现的前端AES加密解密功能【基于CryptoJS】
- RSA AES 前端JS与后台JAVA的加密解密的是实现
- Javascript实现前端AES加密解密功能
- jsencrypt代码分析——openssl的rsa加密解密在js的实现
- C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现[转载]
- 【加密解密】高级加密标准AES加密(Javascript实现)
- C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现
- C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现
- PHP开发过程中AES加密解密问题 js前端AES加密,PHP解密
- AES加密解密代码实现
- RSA实现JS前端加密,PHP后端解密
- java和js实现aes加密解密
- java和js实现aes加密解密
- JavaScript前端和Java后端的AES加密和解密
- AES三端加密解密 – iOS与Android,JS的同步实现
- RSA实现JS前端加密,PHP后端解密
- 服务端AES加密解密,前端crypto-js加密解密
- C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现【多种语言AES/CBC/PKCS5Padding通用加解密数据】
- RSA前端JS加密,后端JAVA解密实现
- RSA前端JS加密,后端JAVA解密实现