复制代码代码如下:
// Paul Tero, julio de 2001
//http://www.tero.co.uk/des/
//
// optimizado para el rendimiento con grandes bloques de Michael Hayworth, noviembre de 2001
//http://www.netdealing.com
//
// Este software se proporciona "tal cual" y
// cualquier garantía expresa o implícita, incluidas, entre otros, el
// garantías implícitas de comerciabilidad y estado físico para un propósito particular
// son rechazados. En ningún caso el autor o los contribuyentes serán responsables
// para cualquier directo, indirecto, incidental, especial, ejemplar o consecuente
// Daños (incluidos, entre otros, la adquisición de bienes sustitutos
// o servicios; Pérdida de uso, datos o ganancias; O interrupción comercial)
// Sin embargo, causado y en cualquier teoría de responsabilidad, ya sea en contrato, estricto
// responsabilidad o agravio (incluida negligencia o de otra manera) que surja de cualquier manera
// fuera del uso de este software, incluso si se recomienda la posibilidad de
// tal daño.
// des
// Esto toma la clave, el mensaje y si cifrar o descifrar
function des (clave, mensaje, cifrado, modo, iv, relleno) {
// Declarar esto localmente acelera las cosas un poco
var spfunction1 = nueva matriz (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x10400,0x1040404,0x4400,0x1000404,0x1010004,0x10000000000004004,0x4404,0X404,0X404,0X404,0X404,0X404,0X404,0X404,0XETOMENTO. X1000400,0x10400,0x10400,0x1010000, 0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000, 0x10000,0x1010404,0x4,0x1010000,0x10400,0x10000000010000 0000,0x10400,0x1000004,0x400,0x4,0x1000404, 0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0x10410004);
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,0x108020, -0x2ffe x7fff7fe0, -0x7ff00000 , -0x7fef8000,0x8000, -0x7ff00000, -0x7fff8000,0x20, -0x7fef7fe0,0x108020,0x20,0x8000,--0x800000.0x8020, -0x7fef8000,0x100000, -0x7fffffe0x10002020, -0x7fe , 0x100020,0x108000,0, -0x7fff8000,0x8020, -0x80000000, -0x7fefffe0, -0x7fef7fe0,0x108000);
var spFunction3 = nueva matriz (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200200,0x20008,0x8000008,0x8000008,0x2000000,0x8020208,0x20008,0x802000000208,0x208,0X8000000. 020200,0x200,0x20200,0x8020000, 0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x80000 0x8020208,0x8000200,0x8000008,0x200,0, 0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x802000000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x2020200);
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,0 81,0x1,0x802001,0x2081,0x2081, 0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
var spfunction5 = nueva matriz (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x4000000000,0x208000000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0X42080000,0X2000100100100X420800,0XETOMATO. 00000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100, 0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x200000000,0x42000 80100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000, 0x42080000,0x42080100,0x80100,0x4200000000,0x42080100,0x2080000,0,0x40080000,0x4200000000,0x80100,0x2000100,0x440000100,0x80000,0x40080000,0x20100100100100100100100100100100;
var spfunction6 = nueva matriz (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x40404010,0x400000,0x2000001010101004000,0X4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000,0x4000. X400010,0x20004010,0x4000,0x404000,0x20004010, 0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x200000000 0,0x20004000,0x10,0x20400010,0x404000,0x2040401010000. x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000, 0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x2000404010,0,0x2040404000,0x20000000,0x400010,0x200040101010);
var spfunction7 = nueva matriz (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0X402,0X40008 200802,0x200002,0x4000800,0x4000002,0x4200000, 0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x400000000,0X200800,0X200000,0X4000802,0X4000802,0X42002002002002002002002002002,0X4002002002002002002002002002002002.0XETO. 0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802, 0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x20000002);
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,0x4000000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x4104040410 0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000, 0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x100000000100200
// Cree las 16 o 48 subciclistas que necesitaremos
var teclas = des_createKeys (clave);
var m = 0, i, j, temp, temp2, derecha1, derecha2, izquierda, derecha, bucle;
var cbcleft, cbcleft2, cbcright, cbcright2
var endloop, loopinc;
var len = Message.length;
var fragmento = 0;
// Configura los bucles para un single y triple des
var iterations = keys.length == 32? 3: 9; //
if (iterations == 3) {looping = encrypt? nueva matriz (0, 32, 2): nueva matriz (30, -2, -2);}
else {looping = encrypt? nueva matriz (0, 32, 2, 62, 30, -2, 64, 96, 2): nueva matriz (94, 62, -2, 32, 64, 2, 30, -2, -2);}
// rellena el mensaje dependiendo del parámetro de relleno
if (padding == 2) mensaje += ""; // rellena el mensaje con espacios
else if (padding == 1) {temp = 8- (len%8); mensaje += string.FromCharCode (temp, temp, temp, temp, temp, temp, temp, temp, temp); if (temp == 8) len+= 8;} // pkcs7 relleno
else if (! Padding) Mensaje += "/0/0/0/0/0/0/0/0"; // rellena el mensaje con bytes nulos
// almacenar el resultado aquí
resultado = "";
tempresult = "";
if (mode == 1) {// modo 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;
}
// recorre cada trozo de 64 bits del mensaje
while (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 ++);
// Para el modo de encadenamiento de bloque de cifrado, xor el mensaje con el resultado anterior
if (mode == 1) {if (encrypt) {izquierda ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; CBCright2 = CBCright; cbcleft = izquierda; cbcright = right;}}
// Primero cada 64 pero la parte del mensaje debe permitirse de acuerdo con IP
temp = ((izquierda >>> 4) ^ derecha) y 0x0f0f0f0f; recto ^= temp; izquierda ^= (temperatura << 4);
temp = ((izquierda >>> 16) ^ derecha) y 0x0000ffff; recto ^= temp; Izquierda ^= (temperatura << 16);
temp = ((derecha >>> 2) ^ izquierda) y 0x33333333; izquierda ^= temp; recto ^= (tempe << 2);
temp = ((derecha >>> 8) ^ izquierda) y 0x00ff00ff; izquierda ^= temp; recto ^= (temperatura << 8);
temp = ((izquierda >>> 1) ^ derecha) y 0x555555555; recto ^= temp; izquierda ^= (temperatura << 1);
izquierda = ((izquierda << 1) | (izquierda >>> 31));
right = ((derecha << 1) | (derecha >>> 31));
// Haga esto 1 o 3 veces por cada parte del mensaje
para (j = 0; j <iterations; j+= 3) {
endloop = looping [j+1];
LoopInC = Looping [j+2];
// ahora pasa y realiza el cifrado o descifrado
para (i = looping [j]; i! = endloop; i+= loopinc) {// para eficiencia
right1 = right ^ teclas [i];
right2 = ((derecha >>> 4) | (derecha << 28)) ^ claves [i+1];
// El resultado se logra pasando estos bytes a través de las funciones de selección S
temp = izquierda;
izquierda = derecha;
Derecho = temp ^ (spfunction2 [(right1 >>> 24) y 0x3f] | spfunction4 [(right1 >>> 16) y 0x3f]
| SPFunction6 [(Right1 >>> 8) y 0x3f] | SPFunction8 [Right1 y 0x3f]
| SPFunction1 [(Right2 >>> 24) y 0x3f] | SPFunction3 [(Right2 >>> 16) y 0x3f]
| SPFunction5 [(Right2 >>> 8) y 0x3f] | spfunction7 [right2 y 0x3f]);
}
temp = izquierda; izquierda = derecha; Right = temp; // no reverso a la izquierda y a la derecha
} // para 1 o 3 iteraciones
// Muévete y luego cada uno a la derecha
izquierda = ((izquierda >>> 1) | (izquierda << 31));
right = ((derecha >>> 1) | (derecha << 31));
// ahora realiza IP-1, que es IP en la dirección opuesta
temp = ((izquierda >>> 1) ^ derecha) y 0x555555555; recto ^= temp; izquierda ^= (temperatura << 1);
temp = ((derecha >>> 8) ^ izquierda) y 0x00ff00ff; izquierda ^= temp; recto ^= (temperatura << 8);
temp = ((derecha >>> 2) ^ izquierda) y 0x33333333; izquierda ^= temp; recto ^= (tempe << 2);
temp = ((izquierda >>> 16) ^ derecha) y 0x0000ffff; recto ^= temp; Izquierda ^= (temperatura << 16);
temp = ((izquierda >>> 4) ^ derecha) y 0x0f0f0f0f; recto ^= temp; izquierda ^= (temperatura << 4);
// Para el modo de encadenamiento de bloque de cifrado, xor el mensaje con el resultado anterior
if (mode == 1) {if (encrypt) {cbcleft = izquierda; cbcright = right;} else {izquierda ^= cbcleft2; Right ^= CbCright2;}}
TEMPRESULT += String.FromCharCode ((izquierda >>> 24), ((izquierda >>> 16) y 0xff), ((izquierda >>> 8) y 0xff), (izquierda y 0xff), (derecha >>> 24), ((derecho >>> 16) y 0xff), ((derecho >>> 8) y 0xff), (Right & 0xff));
trozo += 8;
if (chunk == 512) {resultado += tempresult; tempresult = ""; trozo = 0;}
} // por cada 8 caracteres, o 64 bits en el mensaje
// devuelve el resultado como una matriz
Resultado de retorno + tempresult;
} // final de des
// des_createkeys
// Esto toma como entrada una tecla de 64 bits (aunque solo se usan 56 bits)
// como una matriz de 2 enteros y devuelve 16 teclas de 48 bits
función des_createKeys (clave) {
// Declarar esto localmente acelera las cosas un poco
pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
PC2Bytes1 = nueva matriz (0,0x1,0x100000,0x100001,0x400000000,0x4000001,0x4100000,0x4100001,0x100100,0x101,0x100100100,0x10010101,0x4000100,0x4000101,0x41001001001001001001001010010100100
PC2Bytes2 = nueva matriz (0,0x8,0x800,0x808,0x100000000,0x1000008,0x1000800,0x1000808,0,0x88,0x800,0x808,0x100000000,0x1000008,0x1000800,0x1000808);
PC2Bytes3 = nueva matriz (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x2000000,0x220000,0x8020000,0x88220000,0x22000,0x222000,0x802222222222222222222222000);
PC2Bytes4 = nueva matriz (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x101010x41010);
PC2Bytes5 = nueva matriz (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
PC2Bytes6 = nueva matriz (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x8000000,0x1008000000,0x2,0x100002,0x80002,0x100800020002
PC2Bytes7 = nueva matriz (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x3000000,0x20800,0X30800,0x20020000,0x20030000,0x200208000000000800);
PC2Bytes8 = nueva matriz (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
PC2BYTES9 = nueva matriz (0,0x10000000,0x8,0x1000000008,0,0x10000000,0x8,0x1000000008,0x400,0x10000400,0x408,0x10000408,0x400,0x100400,0x408,0x1000040808);
PC2Bytes10 = nueva matriz (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020202000,0x202020,0x102000,0x1020202020202000,0x1020202020);
PC2Bytes11 = nueva matriz (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x400000000,0x500000000,0x4000200200,0x5000200,0x4200000,0x5200000,0x4200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200200.
PC2Bytes12 = nueva matriz (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x800000010,0x800001010,0x80010,0x810,0x808001010,0x80810101010101010101.
PC2Bytes13 = nueva matriz (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
// cuántas iteraciones (1 para des, 3 para triple des)
var iterations = key.length> 8? 3: 1; // Cambiado por Paul 16/6/2007 para usar Triple DES para 9+ Byte Keys
// almacena las teclas de retorno
varillas var = nueva matriz (32 * iteraciones);
// ahora defina los cambios a la izquierda que deben hacerse
Var cambia = nueva matriz (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
// otras variables
var Lefttemp, Righttemp, M = 0, n = 0, temp;
para (var j = 0; j <iterations; j ++) {// 1 o 3 iteraciones
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 = ((izquierda >>> 4) ^ derecha) y 0x0f0f0f0f; recto ^= temp; izquierda ^= (temperatura << 4);
temp = ((derecha >>> -16) ^ izquierda) y 0x0000ffff; izquierda ^= temp; recto ^= (temprP << -16);
temp = ((izquierda >>> 2) ^ derecha) y 0x33333333; recto ^= temp; izquierda ^= (temperatura << 2);
temp = ((derecha >>> -16) ^ izquierda) y 0x0000ffff; izquierda ^= temp; recto ^= (temprP << -16);
temp = ((izquierda >>> 1) ^ derecha) y 0x555555555; recto ^= temp; izquierda ^= (temperatura << 1);
temp = ((derecha >>> 8) ^ izquierda) y 0x00ff00ff; izquierda ^= temp; recto ^= (temperatura << 8);
temp = ((izquierda >>> 1) ^ derecha) y 0x555555555; recto ^= temp; izquierda ^= (temperatura << 1);
// El lado derecho debe desplazarse y obtener los últimos cuatro bits del lado izquierdo
temp = (izquierda << 8) | ((derecho >>> 20) y 0x000000f0);
// La izquierda necesita ser puesto al revés
izquierda = (derecha << 24) | ((derecha << 8) y 0xff0000) | ((derecha >>> 8) y 0xff00) | ((derecho >>> 24) y 0xf0);
Right = temp;
// ahora pasa y realiza estos cambios en las teclas izquierda y derecha
para (var i = 0; i <shifts.length; i ++) {
// desplaza las teclas uno o dos bits a la izquierda
if (shifts [i]) {izquierda = (izquierda << 2) | (izquierda >>> 26); Derecha = (derecha << 2) | (derecho >>> 26);}
else {izquierda = (izquierda << 1) | (izquierda >>> 27); Derecha = (derecha << 1) | (correcto >>> 27);}
izquierda & = -0xf; Right & = -0xf;
// ahora aplica PC-2, de tal manera que E sea más fácil al cifrar o descifrar
// Esta conversión se verá como PC-2, excepto que solo se usan los últimos 6 bits de cada byte
// en lugar de 48 bits consecutivos y el orden de las líneas estará de acuerdo con
// Cómo se aplicarán las funciones de selección S: S2, S4, S6, S8, S1, S3, S5, S7
LeftTemp = PC2Bytes0 [izquierda >>> 28] | PC2Bytes1 [(izquierda >>> 24) y 0xf]
| PC2Bytes2 [(izquierda >>> 20) y 0xf] | pc2bytes3 [(izquierda >>> 16) y 0xf]
| PC2Bytes4 [(izquierda >>> 12) y 0xf] | pc2bytes5 [(izquierda >>> 8) y 0xf]
| pc2bytes6 [(izquierda >>> 4) y 0xf];
righttemp = pc2bytes7 [derecha >>> 28] | pc2bytes8 [(derecha >>> 24) y 0xf]
| pc2bytes9 [(derecha >>> 20) y 0xf] | pc2bytes10 [(derecha >>> 16) y 0xf]
| pc2bytes11 [(derecha >>> 12) y 0xf] | pc2bytes12 [(derecha >>> 8) y 0xf]
| pc2bytes13 [(derecha >>> 4) y 0xf];
temp = ((RightTemp >>> 16) ^ Lefttemp) y 0x0000ffff;
claves [n ++] = LeftTemp ^ temp; claves [n ++] = righttemp ^ (temp << 16);
}
} // para cada iteración
// Devuelve las claves que hemos creado
Revuelve las llaves;
} // fin de des_createkeys
////////////////////////////// PRUEBA /////////////////// /////////
función stringToHex (s) {
var r = "0x";
var hexes = nueva matriz ("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "b", "c", "d", "e", "f");
para (var i = 0; i <s.length; i ++) {r += hexes [s.charcodeat (i) >> 4] +hexes [s.charcodeat (i) & 0xf];}
regresar r;
}
función HexToString (H) {
var r = "";
for (var i = (h.substr (0, 2) == "0x")? 2: 0; i <h.length; i += 2) {r += StromCharCode (parseInt (H.Substr (I , 2), 16));}
regresar r;
}
var key = "Esta es una tecla de 24 bytes!";
VAR Message = "Este es un mensaje de prueba";
var ciphertext = des (clave, mensaje, 1, 0);
document.writeLn ("DES Test:" + StringToHex (cifrado));