找回密码
 注册
搜索
查看: 2568|回复: 0

使用Javascript进行AES加密解密

[复制链接]
发表于 2014-12-18 21:09:15 | 显示全部楼层 |阅读模式
用Javascript实现AES的加密与解密,密钥长度128位(16字节)当密钥长度在01字节到16字节时[8,128]Bits,密钥以0x00填充满16字节.
当密钥长度在16字节到24字节时(128,192]Bits,密钥以0x00填充满24字节.
当密钥长度在24字节到32字节时(192,256]Bits,密钥以0x00填充满32字节.
当密钥长度超过32字节时(256,+∞)Bits,密钥只取前32字节(128Bits).
仅支持ASCII字符.采用ECB模式加密
注:本代码来源于网络,对其进行了适当的修改,使其能够正确的工作
使用方法:
var test = new AES.Crypto('My Password');//已My Password为密钥建立一个新的AES.Crypto对象.
test.encrypt('123');//返回一个16进制字符串,为使用相应密钥加密字符串123的结果
test.decrypt('98152411195aece9493e712be2f22b8a');//返回使用密钥解密相应密文后的明文信息
代码:
  1. var AES = {
  2.         sbox: [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16],
  3.     Invsbox: [0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d],
  4.     rcon: [[0x00, 0x00, 0x00, 0x00], [0x01, 0x00, 0x00, 0x00], [0x02, 0x00, 0x00, 0x00], [0x04, 0x00, 0x00, 0x00], [0x08, 0x00, 0x00, 0x00], [0x10, 0x00, 0x00, 0x00], [0x20, 0x00, 0x00, 0x00], [0x40, 0x00, 0x00, 0x00], [0x80, 0x00, 0x00, 0x00], [0x1b, 0x00, 0x00, 0x00], [0x36, 0x00, 0x00, 0x00]],
  5.     cipher: function(input, w) {
  6.         var nb = 4;
  7.         var nr = w.length / nb - 1;
  8.         var state = [new Array(nb), new Array(nb), new Array(nb), new Array(nb)];
  9.         var output = new Array(4 * nb);
  10.         var i, round;
  11.         for (i = 0; i < input.length; i++) {
  12.             state[i % 4][Math.floor(i / 4)] = input[i];
  13.         }
  14.         this.addRoundKey(state, w, 0, nb);
  15.         for (round = 1; round < nr; round++) {
  16.             this.subBytes(state, nb, 0);
  17.             this.shiftRows(state, nb, 0);
  18.             this.mixColumns(state, nb, 0);
  19.             this.addRoundKey(state, w, round, nb);
  20.         }
  21.         this.subBytes(state, nb, 0);
  22.         this.shiftRows(state, nb, 0);
  23.         this.addRoundKey(state, w, nr, nb);
  24.         for (i = 0; i < output.length; i++) {
  25.             output[i] = state[i % 4][Math.floor(i / 4)];
  26.         }
  27.         return output;
  28.     },
  29.     Invcipher: function(input, w) {
  30.         var nb = 4;
  31.         var nr = w.length / nb - 1;
  32.         var state = [new Array(nb), new Array(nb), new Array(nb), new Array(nb)];
  33.         var output = new Array(4 * nb);
  34.         var i, round;
  35.         for (i = 0; i < input.length; i++) {
  36.             state[i % 4][Math.floor(i / 4)] = input[i];
  37.         }
  38.         this.addRoundKey(state, w, nr, nb);
  39.         for (round = nr - 1; round >= 1; round--) {
  40.             this.shiftRows(state, nb, 1);
  41.             this.subBytes(state, nb, 1);
  42.             this.addRoundKey(state, w, round, nb);
  43.             this.mixColumns(state, nb, 1);
  44.         }
  45.         this.shiftRows(state, nb, 1);
  46.         this.subBytes(state, nb, 1);
  47.         this.addRoundKey(state, w, round, nb);
  48.         for (i = 0; i < output.length; i++) {
  49.             output[i] = state[i % 4][Math.floor(i / 4)];
  50.         }
  51.         return output;
  52.     },
  53.     subBytes: function(state, nb, type) {
  54.         var r, c;
  55.         var type = type || 0;
  56.         var tempBox = type === 0 ? this.sbox: this.Invsbox;
  57.         for (c = 0; c < nb; c++) {
  58.             for (r = 0; r < 4; r++) {
  59.                 state[r][c] = tempBox[state[r][c]];
  60.             }
  61.         }
  62.     },
  63.     shiftRows: function(state, nb, type) {
  64.         var temp = new Array(nb);
  65.         var type = type || 0;
  66.         var r, c;
  67.         type = type === 0 ? 1 : -1;
  68.         for (r = 1; r < 4; r++) {
  69.             for (c = 0; c < nb; c++) {
  70.                 temp[c] = state[r][(c + r * type + nb) % nb];
  71.             }
  72.             for (c = 0; c < 4; c++) {
  73.                 state[r][c] = temp[c];
  74.             }
  75.         }
  76.     },
  77.     mixColumns: function(state, nb, type) {
  78.         var r, c, i;
  79.         var t = new Array(nb);
  80.         var n = [[0x02, 0x03, 0x01, 0x01], [0x0e, 0x0b, 0x0d, 0x09]];
  81.         for (c = 0; c < nb; c++) {
  82.             for (r = 0; r < 4; r++) {
  83.                 t[r] = state[r][c];
  84.             }
  85.             for (r = 0; r < 4; r++) {
  86.                 state[r][c] = 0;
  87.                 for (i = 0; i < 4; i++) {
  88.                     state[r][c] ^= this.FFmul(n[type][i], t[(r + i) % 4]);
  89.                 }
  90.             }
  91.         }
  92.     },
  93.     FFmul: function(a, b) {
  94.         var bw = new Array(4);
  95.         var res = 0;
  96.         var i;
  97.         bw[0] = b;
  98.         for (i = 1; i < 4; i++) {
  99.             bw[i] = bw[i - 1] << 1;
  100.             if (bw[i - 1] & 0x80) {
  101.                 bw[i] ^= 0x11b;
  102.             }
  103.         }
  104.         for (i = 0; i < 4; i++) {
  105.             if ((a >> i) & 0x01) {
  106.                 res ^= bw[i];
  107.             }
  108.         }
  109.         return res;
  110.     },
  111.     addRoundKey: function(state, w, round, nb) {
  112.         var r, c;
  113.         for (c = 0; c < nb; c++) {
  114.             for (r = 0; r < 4; r++) {
  115.                 state[r][c] ^= w[round * 4 + c][r];
  116.             }
  117.         }
  118.     },
  119.     keyExpansion: function(key) {
  120.         var nk = key.length / 4;
  121.         var nb = 4;
  122.         var nr = nk + 6;
  123.         var w = new Array(nb * (nr + 1));
  124.         var temp = new Array(4);
  125.         var i, j;
  126.         for (i = 0; i < nk; i++) {
  127.             w[i] = [key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]];
  128.         }
  129.         for (i = nk; i < w.length; i++) {
  130.             w[i] = new Array(4);
  131.             for (j = 0; j < 4; j++) {
  132.                 temp[j] = w[i - 1][j];
  133.             }
  134.             if (i % nk === 0) {
  135.                 this.rotWord(temp);
  136.                 this.subWord(temp);
  137.                 for (j = 0; j < 4; j++) {
  138.                     temp[j] ^= AES.rcon[i / nk][j];
  139.                 }
  140.             } else if (nk > 6 && i % nk === 4) {
  141.                 this.subWord(temp);
  142.             }
  143.             for (j = 0; j < 4; j++) {
  144.                 w[i][j] = w[i - nk][j] ^ temp[j];
  145.             }
  146.         }
  147.         return w;
  148.     },
  149.     rotWord: function(w) {
  150.         var temp = w[0];
  151.         var i;
  152.         for (i = 0; i < 3; i++) {
  153.             w[i] = w[i + 1];
  154.         }
  155.         w[3] = temp;
  156.     },
  157.     subWord: function(w) {
  158.         var i;
  159.         for (i = 0; i < 4; i++) {
  160.             w[i] = this.sbox[w[i]];
  161.         }
  162.     }
  163. };
  164. AES.Crypto = function(key) {
  165.     this.String2Array = function(input, block) {
  166.         var i;
  167.         if (block != null) {
  168.             var output = new Array(16);
  169.             for (i = 0; i < 16; i++) {
  170.                 output[i] = input.charCodeAt(16 * block + i) || 0;
  171.             }
  172.         } else {
  173.             var realLength = input.length <= 16 ? 16 : input.length <= 24 ? 24 : 32;
  174.             var output = new Array(realLength);
  175.             for (i = 0; i < realLength; i++) {
  176.                 output[i] = input.charCodeAt(i) || 0;
  177.             }
  178.         }
  179.         return output;
  180.     }
  181.     this.Byte2Char = function(input) {
  182.         var i;
  183.         var output = '';
  184.         for (i = 0; i < input.length / 2; i++) {
  185.             output += String.fromCharCode(parseInt(input[i * 2], 16) * 16 + parseInt(input[i * 2 + 1], 16));
  186.         }
  187.         return output;
  188.     }
  189.     this.encrypt = function(input) {
  190.         var blockCount = Math.ceil(input.length / blockSize);
  191.         var output = new Array();
  192.         var counterBlock, byteCount, offset;
  193.         var block, c;
  194.         for (block = 0; block < blockCount; block++) {
  195.             counterBlock = AES.cipher(this.String2Array(input, block), this.keySchedule);
  196.             offset = block * blockSize;
  197.             for (c = 0; c < 16; c++) {
  198.                 output[offset + c] = counterBlock[c] < 16 ? ('0' + counterBlock[c].toString(16)) : counterBlock[c].toString(16);
  199.             }
  200.         }
  201.         return output.join("");
  202.     };
  203.     this.decrypt = function(input) {
  204.         var blockCount = Math.ceil(input.length / blockSize * 0.5);
  205.         var output = new Array();
  206.         var counterBlock, byteCount, offset;
  207.         var block, c;
  208.         input = this.Byte2Char(input);
  209.         for (block = 0; block < blockCount; block++) {
  210.             counterBlock = AES.Invcipher(this.String2Array(input, block), this.keySchedule);
  211.                         offset = block*blockSize;
  212.             for (c = 0; c < 16 && counterBlock[c] != 0; c++) {
  213.                 output[offset + c] = String.fromCharCode(counterBlock[c]);
  214.             }
  215.         }
  216.         return output.join("");
  217.     };
  218.     var blockSize = 16;
  219.     this.key = this.String2Array(key, null);
  220.     this.keySchedule = AES.keyExpansion(this.key);
  221. };
复制代码
本文来自lyz810的新浪博客,http://blog.sina.com.cn/s/blog_a9d3c71c0101ds37.html


您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-5-4 22:13 , Processed in 0.017109 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表