首頁 >web前端 >js教程 >javascript實作des解密加密全過程_javascript技巧

javascript實作des解密加密全過程_javascript技巧

WBOY
WBOY原創
2016-05-16 16:53:381866瀏覽
複製程式碼 程式碼如下:

//Paul Tero, July 2001
//http://www.tero.co.uk/des/
//
//Optimised for performance with large blocks by Michael Hayworth, November 2001
//http://www.netdealing.com
//
//THIS SOFTWARE IS PROVIDED "AS IS" AND
//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
//SUCH DAMAGE.

//des
//this takes the key, the message, and whether to encrypt or decrypt
function des (key, message, encrypt, mode, iv, padding) {
//declaring this locally speeds things up a bit
var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
var spfunction7 = , 0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000, 0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x40000x 0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x 0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x420000x 00,0x200002);
var spfunction8 = 新數組(0x10001040,0x1000,0x40000 ,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0xxx 10040000,0x10000040,0x10001000,0x1040,0x41000 ,0x40040,0x10040040,0x10041000,0x1040,0,0, 0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1040,0x40000,0x1000,0xx 000,0x40,0x10000040,0x10040000,0x10040040,0x10000000 ,0x40000,0x10001040,0,0x10041040,00x10001040,0,0x10041040,00x ,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040, 0x1040,0x400040,0100x /建立我們需要的16 或48 個子項
var keys = des_createKeys (key);
var m=0, i, j, temp, temp2, right1, right2, left, right, 循環;
var cbcleft、cbcleft2、cbcright、cbcright2
var endloop、loopinc var len = message.length;
var 區塊= 0;
//設定單循環和三重循環
var iterations =keys.length == 32 ? 3:9; //單一或三個des
if (iterations == 3) {looping = encrypt ?新數組(0, 32, 2) : 新數組(30, -2, -2);}
else {循環= 加密?新數組(0, 32, 2, 62, 30, -2, 64, 96, 2) : 新數組(94, 62, -2, 32, 64, 2, 30, -2, -2);}

//根據padding參數填入訊息
if (padding == 2) message = " "; //用空格填滿訊息
else if (padding == 1) {temp = 8-(len %8);訊息= String.fromCharCode (temp,temp,temp,temp,temp,temp,temp,temp); if (temp==8) len =8;} //PKCS7 填入
else if (! padding) message = " "; //用空位元組填滿訊息

//將結果儲存在這裡
result = "";
tempresult = "";

if (mode == 1) { //CBC 模式
cbcleft = (iv.charCodeAt(m ) cbcright = (iv.charCodeAt(m ) 米=0;
}

//循環遍歷訊息的每個64 位元區塊
while (m left = (message.charCodeAt(m ) 右= ( message.charCodeAt(m )
///對於密碼塊連結模式,將訊息與先前的結果進行異或
if (mode == 1) {if (encrypt) {left ^= cbcleft;右^= cbcright;} 否則{cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = 左; cbcright = 右;}}

//首先每64 個訊息區塊必須依照IP 進行排列
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;右^=溫度;左^= (溫度temp = ((左>>16)^右)&0x0000ffff;右^=溫度;左^= (溫度temp = ((右>>2)^左) &0x33333333;左^=溫度;右^= (溫度temp = ((右>>8)^左)&0x00ff00ff;左^=溫度;右^= (溫度temp = ((左>>>1)^右)&0x55555555;右^=溫度;左^= (溫度
左= ((左> 31));
右= ((右> 31));

//對訊息的每個區塊執行1 或3 次
for (j=0; jendloop = looping[j 1];
loopinc = 迴圈[j 2];
//現在執行加密或解密
for (i=looping[j]; i!=endloop; i =loopinc) { //為了提高效率
right1 = right ^ keys[i ];
right2 = ((右>> 4) | (右//透過將這些位元組傳遞給S選擇函數來獲得結果
temp = left;
左=右;
right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
| spfunction6[(right1 >>> > ;> 8) & 0x3f] | spfunction8[right1 & 0x3f]
| spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >> 16) & 0x3f]
| spfunction5[(right2 >>> 8) & 0x3f] | spftionunc7[ right2 & 0x3f]);
}
temp = 左;左=右;右=溫度; //左右反轉
} //進行1次或3次迭代

/ /然後向右移動一位
left = ((left >>> 1) | (左右= ((右>> 1) | (右
//現在執行IP-1,即相反方向的IP
temp = ((left >>> 1) ^ right) & 0x55555555;右^=溫度;左^= (溫度temp = ((右>>8)^左)&0x00ff00ff;左^=溫度;右^= (溫度temp = ((右>>2)^左) &0x33333333;左^=溫度;右^= (溫度temp = ((左>>16)^右)&0x0000ffff;右^=溫度;左^= (溫度temp = ((左>>4)^右)&0x0f0f0f0f;右^=溫度;左^= (溫度
//對於密碼區塊連結模式,將訊息與先前的結果進行異或
if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = 右;} else {左^= cbcleft2;右^= cbcright2;}}
tempresult = String. fromCharCode ((左>>>24), ((左>>>16) & 0xff), ((左>>>8) & 0xff)、(左>>>24)、((右>>>16) &0xff)、((右>>>8)&0xff)、(右& 0xff));

塊= 8;
if (chunk == 512) {結果= tempresult;溫度結果=“ 」; chunk = 0;}
} //對於訊息中的每8 個字元或64 位元

//以陣列形式傳回結果
return result tempresult;
}// des



的結尾
//des_createKeys
//這採用64 位元金鑰作為輸入(即使只使用56 位元)
//作為陣列2 個整數,並傳回16 個48 位元金鑰
function des_createKeys (key) {
//在本地聲明這會加快速度
pc2bytes0 = new Array (0,0x4,0x20000000,0x20000,000x , 0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x2001104,0x10200,0x10204,0x2001100,002000,000x 新組0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100, 0x101,0x100100,0x100101,0x4000100,0 x4000101,0x4100100,0x4100101);
pc2bytes2 = 新數組(0,00,00x 1000800,0x1000808,0,0x8,0x800,0x808,0x1000000, 0x1000008,0x1000800,0 x1000808);
pc2bytes3 = 新數組(0,0x200000,0x8000000,0x8200000,0x2000,00x ,0x220000,0x8020000,0x8220000,0 x22000,0x222000,0x8022000,0x8222000);
pc2bytes4 =新陣列(0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x410000x1010x x41000,00x1010,0x4101010);
pc2bytes5 =新數組(0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x200000x );
pc2bytes6 = 新數組(0,0x10000000,0x80000, 0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x12000. tes7 = 新數組(0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800, 0x20010800,0x20000,0x30000,0x20800,0x30800,0x200 20000,0x20030000,0x20020800,0x20030800); 000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000, 0x2040000,0x2000002,0x2040002,0 x2000002,0x2040002);
pc2bytes9 =0 x2000002,0x2040002);
pc2bytes9 = 新數組(0,0x10000000,0x8,010x 8,0x400,0x10000400,0x408,0x10000408,0x400,0x1000040 0,0x408 ,0x10000408);
pc2bytes10 = 新數組(0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x100020,0x100000,0x100020,0x20000x 2020,0x102000,0 x102020);
pc2bytes11 = 新數組(0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x500000x 0x5200000,0x4200200,0x5200200);
pc2bytes12 = 新數組(0,0x1000, 0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x800x10,00x 10);
pc2bytes13 = 新數組(0,0x4,0x100,0x104,0,0x4,0x100 ,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);

//迭代次數(1 次為des,3 次為三重des)
var iterations = 迭代次數(1 次為des,3 次為三重des)
var iterations = 迭代. length >; 8? 3:1; // Paul 於2007 年6 月16 日更改為對9 位元組金鑰使用Triple DES
//儲存回傳金鑰
var keys = new Array (32 * iterations);
//現在定義需要完成的左移
var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 );
//其他變數
var lefttemp, righttemp, m=0, n=0, temp;

for (var j=0; jleft = (key.charCodeAt(m ) 右= (key.charCodeAt(m )
溫度= ((左>>> 4) ^ 右) & 0x0f0f0f0f;右^=溫度;左^= (溫度temp = ((右>>-16 )^左)&0x0000ffff;左^=溫度;右^=(溫度temp = ((左>>2)^右)&0x33333333;右^=溫度;左^= (溫度temp = ((右>>-16)^左)&0x0000ffff;左^=溫度;右^=(溫度temp = ((左>>>1 )^右)&0x55555555;右^=溫度;左^= (溫度temp = ((右>>8)^左)&0x00ff00ff;左^=溫度;右^= (溫度temp = ((左>>>1)^右)&0x55555555;右^=溫度;左^= (溫度
//右側需要移位並取得左側的最後四位
temp = (left >20)&0x000000f0);
//left需要顛倒
left = (right >8) & 0xff00) | ((右>>24)&0xf0);
右=溫度;

//現在檢查並在左右鍵上執行這些移位
for (var i=0; i //移位鍵向左移動一位或兩位
if (shifts[i ]) {left = (left >26);右= (右>26);}
else {左=(左>27);右= (右>27);}
左&= -0xf;右&= -0xf;

//現在應用PC-2,這樣E在加密或解密時就更容易
//這個轉換看起來像PC-2,除了只使用每個位元組的最後6位
//而不是48 個連續位,行的順序將根據
//如何應用S 選擇函數:S2、S4、S6、S8、S1、S3、S5、S7
lefttemp = pc2bytes0[左>>>> 28]| pc2bytes1[(左>>24) & 0xf]
| pc2bytes2[(左>>20)&0xf]| pc2bytes3[(左>>16)&0xf]
| pc2bytes4[(左>>12)&0xf]| pc2bytes5[(左>>8) & 0xf]
| pc2bytes6[(左>>4)&0xf];
righttemp = pc2bytes7[右>>>> 28];
righttemp = pc2bytes7[右>>>> ]| pc2bytes8[(右>>24) & 0xf]
| pc2bytes9[(右>>20) & 0xf] | pc2bytes9[(右>>20) & 0xf] pc2bytes10[(右>>16) & 0xf ]
| pc2bytes11[(右>>12) & 0xf] | pc2bytes12[(右>>8) & 0xf]
| pc2bytes13[(右>>4)&0xf];
| pc2bytes13[(右>>4)&0xf];
temp = ( righttemp >> 16) ^ lefttemp) & 0x0000ffff;
keys[n] = lefttemp ^ temp;鍵[n] = righttemp ^ (temp }
} //對於每次迭代
//返回我們建立的鍵
返回鍵;
} // des_createKeys 結束



///////////// ////////////////// / TEST //////////////////////////////
function stringToHex (s) {
var r = "0x" ;
var hexes = new Array ("0","1","2","3","4","5 ","6","7","8","9"," a」、「b」、「c」、「d」、「e」、「f」);
for (var i =0; i>> 4] 十六進位[s.charCodeAt(i) & 0xf];}
return r;
}

function hexToString (h) {
var r = "";
for (var i= (h.substr(0, 2)=="0x") ?2:0; i回傳r;
}

var key = "這是一個24 位元組的金鑰!!";
var message = "這是一個測試訊息";
var 密文= des (金鑰, 訊息, 1, 0);
document.writeln("DES檢定:" stringToHex(密文));
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn