复制代码代码如下:
// Paul Tero,2001年7月
//http://www.tero.co.uk/des/
//
//迈克尔·海沃思(Michael Hayworth),2001年11月,迈克尔·海沃斯(Michael Hayworth
//http://www.netdealing.com
//
//提供“原样”提供此软件
//任何明示或暗示的保证,包括但不限于
//暗示对特定目的的适销性和适合性的保证
//被否认。在任何情况下,作者或贡献者均不承担任何责任
//对于任何直接,间接,偶然,特殊,示例性或结果
//损坏(包括但不限于替代商品的采购
//或服务;损失使用,数据或利润;或业务中断)
//然而造成并以任何责任理论造成的理论,无论合同中,严格
//责任,或以任何方式产生的侵权行为(包括疏忽或其他)
//不使用该软件,即使告知可能性
//这样的伤害。
// des
//这是键,消息以及是加密还是解密
功能DES(键,消息,加密,模式,IV,填充){
//宣布此本地会加快速度
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,0x10004,0x404,0x10404040x10000000000,0x10000000000 x10000,0x101040x40x1010000,0x1010000,0000000,0000000,000,0000000,000,000,000,00000,00000,000,000,000,000,000,000,000,000,000,000,000000,000000,000000,000000,000000000,00000,00000,0000000000,0X10100000090000来10000,0x10400,0x1000004,0x400,0x4,0x1000404, 0x10404,0x10404,0x10004,0x1010000,0x100040404,0x1000004,0x404,0x104040x10400,0x10400,0x404,0x100x1000400 x1000400,0x1000400,0x1000400,0x1000x1044,0x1010004,0x10400,0x10400,0x10400 x104,040004,040004,04,04,040004,040004,04,04,04,040004,04,04,04)
var spfunction2 =新数组(-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,000,0x20,-0x7feffFe0,-0x7fff7fe0,-0x7fffffe0 0x20,-0x7fefffe0,0x108000, 0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffFe0,0x108000,0x80202020202020202020202020202010,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80 feeffe。 0x7FFF7FE0,-0x7ff00000 ,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe7fe0,0x108020,0x20,0x8000,-0x80000000,000,0x8020,-0x7fef8000,0x100000,-0x7x7x7ffeFefeFefeffefefefeffefeffe 0,0x100020,0x108000,0, -0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0fe0,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,0x4200000000,0x42080100,0x2080000,0x2080000,0x40080000000000000000000000000000000000,0x80100,0x80100,0x2000100,0x40000,0000,0000,00000,0000,00000 000,00000,00000,00000,00000,00000,000000,000000,000000,000000,000,000,000000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000倍
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 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000, 0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802, 0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040, 0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000, 0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
//创建我们需要的16或48个子钥匙
var键= des_createkeys(key);
var m = 0,i,j,temp,temp2,right1,right2,左,右,循环;
var cbcleft,cbcleft2,cbcright,cbcright2
var endloop,loopinc;
var len = message.length;
var块= 0;
//设置单个和三重DES的循环
var Iterations = keys.length == 32? 3:9; //单人或三重DES
if(迭代== 3){looping =加密?新数组(0,32,2):新数组(30,-2,-2);}
else {looping =加密?新数组(0,32,2,62,30,-2,64,96,2):新数组(94,62,-2,32,64,64,2,2,30,-2,-2);}
//填充消息取决于填充参数
if(padding == 2)消息 +=“”; //用空格加信消息
否则if(padding == 1){temp = 8-(len%8);消息 += string.fromcharcode(temp,temp,temp,temp,temp,temp,temp,temp,temp); if(temp == 8)len+= 8;} // pkcs7填充
否则(!填充)消息 +=“/0/0/0/0/0/0/0/0/0/0”; //用null字节填充消息
//将结果存储在这里
结果=“”;
tempresult =“”;
如果(模式== 1){// CBC模式
cbcleft =(iv.CharCodeat(M ++)<< 24)| (iv.Charcodeat(M ++)<< 16)| (iv.Charcodeat(M ++)<< 8)| iv.Charcodeat(M ++);
cbcright =(iv.CharCodeat(M ++)<< 24)| (iv.Charcodeat(M ++)<< 16)| (iv.Charcodeat(M ++)<< 8)| iv.Charcodeat(M ++);
M = 0;
}
//循环浏览消息的每一部分
而(m <len){
left =(message.charcodeat(m ++)<< 24)| (Message.CharCodeat(M ++)<< 16)| (Message.CharCodeat(M ++)<< 8)| Message.CharCodeat(M ++);
right =(message.charcodeat(m ++)<< 24)| (Message.CharCodeat(M ++)<< 16)| (Message.CharCodeat(M ++)<< 8)| Message.CharCodeat(M ++);
//对于密码块链式模式,请带有先前结果的消息
if(mode == 1){if(gent){left ^= cbcleft;右 ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft =左; cbcright =正确;}}
//首先,每64个,但必须根据IP置入消息的一部分
temp =(((左>>> 4) ^右)&0x0f0f0f0f;正确 ^= temp;左 ^=(temp << 4);
temp =(((左>>> 16) ^右)&0x0000ffff;正确 ^= temp;左 ^=(temp << 16);
temp =(((右>>> 2) ^左)&0x33333333;左 ^= temp;正确 ^=(temp << 2);
temp =((右>>> 8) ^左)&0x00ff00ff;左 ^= temp;正确 ^=(temp << 8);
temp =(((左>>> 1) ^右)&0x55555555;正确 ^= temp;左 ^=(temp << 1);
左=((左<< 1)|(左>>> 31));
right =((right << 1)|(右>>> 31));
//对消息的每个部分进行1或3次执行此操作
for(j = 0; j <迭代; j+= 3){
endloop = looping [j+1];
loopinc = looping [j+2];
//现在通过并执行加密或解密
for(i = looping [j]; i!= endloop; i+= loopinc){//提高效率
right1 =右 ^键[i];
right2 =((右>>> 4)|(右<< 28)) ^键[i+1];
//通过通过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] | spfunction7 [right2&0x3f]);
}
temp = left;左=右;正确= temp; //左右反面
} //对于1或3迭代
//移动然后向右移动
left =(((左>>> 1)|(左<< 31));
right =((右>>> 1)|(right << 31));
//现在执行IP-1,这是朝相反方向的IP
temp =(((左>>> 1) ^右)&0x55555555;正确 ^= temp;左 ^=(temp << 1);
temp =((右>>> 8) ^左)&0x00ff00ff;左 ^= temp;正确 ^=(temp << 8);
temp =(((右>>> 2) ^左)&0x33333333;左 ^= temp;正确 ^=(temp << 2);
temp =(((左>>> 16) ^右)&0x0000ffff;正确 ^= temp;左 ^=(temp << 16);
temp =(((左>>> 4) ^右)&0x0f0f0f0f;正确 ^= temp;左 ^=(temp << 4);
//对于密码块链式模式,请带有先前结果的消息
if(mode == 1){if(gentrypt){cbcleft = left; cbcright = right;} else {left ^= cbcleft2;对 ^= cbcright2;}}}
tempresult += string.fromcharcode((((左>>> 24),(((左>>> 16)&0xff),((左>>> 8)&0xff),(左&0xff),(右>>> 24),((右>>> 16)&0xff),((右>>> 8)&0xff),(右&0xff));
块 += 8;
if(chunk == 512){结果 += tempresult; tempresult =“”;块= 0;}
} //每8个字符,或消息中的64位
//将结果作为数组返回
返回结果 + tempresult;
} // DES的结束
// des_createkeys
//这是输入的64位键(即使仅使用56位)
//作为2个整数的数组,返回16 48位键
功能des_createkeys(key){
//宣布此本地会加快速度
pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
PC2BYTES2 =新阵列(0,0x8,0x800,0x808,0x100000000,0x1000008,0x1000800,0x1000800,0x1000808080x8,0x800,0x800,0x808080 x808,0x10000000000000000000000000 x100000800 x100080008000808008088088);
pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
PC2BYTES4 =新阵列(0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x41000,0x1010,0x410101010,0x1000,0x41000,0x41000,0x1010,0x4101010);
pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
PC2BYTES7 =新阵列(0,0x10000,0x800,0x10800,0x20000000,0x200100000000,0x20000800,0x20010800,0x20000,0x20000,0x3000000000000 x30000,0x20800,0x30800,0x20800,0x2000000 x2000000000,00000,00000,00000,00200200300300,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000,00000300,00200200200200300300,000300,000300,000009009300,000009300930093009300930093009300930000倍。
pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
PC2BYTES10 =新阵列(0,0x20,0x20,0x100000,0x1000202020,0x100000,0x1000202020202020202020202020202020202020202000,0x102000,0x10202020202020202000,0x10202020202020202020202020202020202020202020202020202020202020202020202020);
pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
pc2bytes13 =新数组(0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x1,0x15,0x101,0x105,0x1,0x1,0x5,0x15,0x101,0x105);
//多少次迭代(DES 1,三倍DES的3)
var迭代= key.length> 8? 3:1; //由Paul 16/6/2007更改为9+字节键使用Triple DES
//存储返回键
var键=新数组(32 *迭代);
//现在定义需要完成的左移位
var shifts =新数组(0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0);
//其他变量
var leftTemp,rightTemp,m = 0,n = 0,temp;
for(var j = 0; j <迭代; j ++){// 1或3迭代
left =(key.charcodeat(m ++)<< 24)| (key.charcodeat(m ++)<< 16)| (key.charcodeat(m ++)<< 8)| key.charcodeat(m ++);
right =(key.charcodeat(m ++)<< 24)| (key.charcodeat(m ++)<< 16)| (key.charcodeat(m ++)<< 8)| key.charcodeat(m ++);
temp =(((左>>> 4) ^右)&0x0f0f0f0f;正确 ^= temp;左 ^=(temp << 4);
temp =((右>>> -16) ^左)&0x0000ffff;左 ^= temp;正确 ^=(temp << -16);
temp =(((左>>> 2) ^右)&0x33333333;正确 ^= temp;左 ^=(temp << 2);
temp =((右>>> -16) ^左)&0x0000ffff;左 ^= temp;正确 ^=(temp << -16);
temp =(((左>>> 1) ^右)&0x55555555;正确 ^= temp;左 ^=(temp << 1);
temp =((右>>> 8) ^左)&0x00ff00ff;左 ^= temp;正确 ^=(temp << 8);
temp =(((左>>> 1) ^右)&0x55555555;正确 ^= temp;左 ^=(temp << 1);
//右侧需要移动并获得左侧的最后四个位
temp =(左<< 8)| ((右>>> 20)&0x000000f0);
//左边需要倒置
左=(右<< 24)| ((右<< 8)&0xff0000)| ((右>>> 8)&0xff00)| ((右>>> 24)&0xf0);
正确= temp;
//现在通过并在左键和右键执行这些班次
for(var i = 0; i <shifts.length; i ++){
//将钥匙向左移动一个或两个位
if(shifts [i]){left =(left << 2)| (左>>> 26);正确=(对<< 2)| (右>>> 26);}
else {left =(left << 1)| (左>>> 27);正确=(对<< 1)| (右>>> 27);}
左= -0xf;正确&= -0xF;
//现在应用PC-2,以使E加密或解密时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 [right >>> 28] | pc2bytes8 [(右>>> 24)&0xf]
| pc2bytes9 [(右>>> 20)&0xf] | pc2bytes10 [(右>>> 16)&0xf]
| pc2bytes11 [(右>>> 12)&0xf] | pc2bytes12 [(右>>> 8)&0xf]
| pc2bytes13 [(右>>> 4)&0xf];
temp =((rightTemp >>> 16) ^ leftTemp)&0x0000ffff;
键[n ++] = leftTemp ^ temp;键[n ++] = rightTemp ^(temp << 16);
}
} //对于每个迭代
//返回我们创建的密钥
返回键;
} // des_createkeys的结束
////////////////////////////// 测试 /////////////////// ////////////////////
功能stringToHex(s){
var r =“ 0x”;
var hexes = new Array(“ 0”,“ 1”,“ 2”,“ 3”,“ 4”,“ 5”,“ 6”,“ 7”,“ 8”,“ 9”,“ A”,“ A”,“”,“ “ b”,“ c”,“ d”,“ e”,“ f”);
for(var i = 0; i <s.length; i ++){r += hexes [s.charcodeat(i)>> 4] +hexes [s.charcodeat(i)&0xf];}
返回r;
}
功能hextostring(h){
var r =“”;
for(var i =(h.substr(0,2)==“ 0x”)?2:0; i <h.length; i += 2){r += string.fromcharcode(parseint(h.substr(i)) ,2),16));}
返回r;
}
var key =“这是24个字节键!”;
var messages =“这是测试消息”;
var ciphertext = des(键,消息,1,0);
document.writeln(“ des test:” + StringToHex(ciphertext));