复制代码代码如下:
// Пол Теро, июль 2001 г.
//http://www.tero.co.uk/des/
//
// Оптимизирован для производительности с большими блоками Майкла Хейворта, ноябрь 2001 г.
//http://www.netdealing.com
//
// это программное обеспечение предоставляется «как есть» и
// любые явные или подразумеваемые гарантии, включая, помимо прочего,
// подразумеваемые гарантии торговцев и пригодности для определенной цели
// отказываются. Ни в коем случае автор или участники не несут ответственности
// для любых прямых, косвенных, случайных, особых, образцовых или последовательных
// ущерб (включая, но не ограничиваясь, закупку заместительных товаров
// или услуги; Потеря использования, данные или прибыль; Или прерывание бизнеса)
// однако вызвали и по любой теории ответственности, будь то в контракте, строго
// ответственность или деликт (включая халатность или иное), возникающее каким -либо образом
// вне использования этого программного обеспечения, даже если он сообщил о возможности
// такой урон.
// des
// это берет ключ, сообщение и зашифровать или расшифровать
Функция des (ключ, сообщение, Encrypt, Mode, IV, Padding) {
// объявление этого локально ускоряет ситуацию
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,0x10004,0x10400,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,0x108000,0x8020, -0x7fef8000, -0x7ff00000,0x80200102080805050505050505000, -0x7ff00000,0x20202020808000, -0x7ff00000,0x20202020808000. 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 = новый массив (0x208,0x8020200,0x8020008,0x8000200,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000050202080x20008,0x800008,0x20000008020208,0X20008,0x800008,0x20000000202020208,0x20008,0x800000000000000000505020202020800800800008,0x200000002020208008008,0x800008,0x2000000020202080x20008,0x8008,0x2000000020202020800800800008,0x200000002020208008008 000 020200,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, 0x420800000x42080100,0x80100,0x42000000 0x42080100,0x2080000,00x4008000000002000000000X80100,0x200010000000000100000000000000001000080000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000н.
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 = новый массив (0x200000,0x4200002,0x4000802,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,00 0x4000002,0x2,0x4000000002002020,0x4000002,0x4000020020,0x4000002,0X40002,002,0X4000002,0X40002,05,0X4000002 000 200802,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,0x2,0x4200802,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800002);
var spfunction8 = новый массив (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000000100410404005 10040000,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,0x1004104040x40040,0x10000040,0x1004000000,0x10001000,0x10001040,0,0x100410404041000,0X41000,0x104005
// Создать 16 или 48 подказков, которые нам понадобятся
var keys = des_createkeys (key);
var m = 0, i, j, temp, temp2, rright1, right2, слева, справа, петля;
var cbcleft, cbcleft2, cbcright, cbcright2
var endloop, loopinc;
var len = message.length;
var Chunk = 0;
// Установите петли для одиночного и тройного DES
var iterations = keys.length == 32? 3: 9; // Одиночный или тройной DES
if (iterations == 3) {looping = incrypt? Новый массив (0, 32, 2): новый массив (30, -2, -2);}
else {looping = incrypt? Новый массив (0, 32, 2, 62, 30, -2, 64, 96, 2): новый массив (94, 62, -2, 32, 64, 2, 30, -2, -2);}
// Направление сообщением в зависимости от параметра накладки
if (padding == 2) сообщение += ""; // подать сообщение с пробелами
иначе if (padding == 1) {temp = 8- (Len%8); Сообщение += String.fromCharcode (температура, температура, температура, температура, температура, темп, темп, темп); if (temp == 8) len+= 8;} // pkcs7.
else if (! Padding) Сообщение += "/0/0/0/0/0/0/0/0"; // заполнить сообщение с помощью нулевых байтов
// хранить результат здесь
result = "";
tempresult = "";
if (mode == 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;
}
// пройти через каждую 64 -битную кусок сообщения
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 ++);
// для режима цепочки блоков шифров, xor Сообщение с предыдущим результатом
if (mode == 1) {if (encrypt) {Left ^= cbcleft; справа ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = оставлен; cbcright = right;}}
// сначала каждый 64, но кусок сообщения должен быть перестановлен в соответствии с IP
temp = ((слева >>> 4) ^ справа) & 0x0f0f0f0f; справа ^= темп; слева ^= (темп << 4);
temp = ((слева >>> 16) ^ справа) и 0x0000ffff; справа ^= темп; слева ^= (темп << 16);
temp = ((справа >>> 2) ^ слева) & 0x333333333; слева ^= темп; справа ^= (темп << 2);
temp = ((справа >>> 8) ^ слева) & 0x00ff00ff; слева ^= темп; справа ^= (Temp << 8);
temp = ((слева >>> 1) ^ справа) & 0x555555555; справа ^= темп; слева ^= (темп << 1);
слева = ((слева << 1) | (слева >>> 31));
справа = ((справа << 1) | (справа >>> 31));
// Сделайте это либо 1 или 3 раза за каждый кусок сообщения
for (j = 0; j <итерации; j+= 3) {
endloop = looping [j+1];
loopinc = петчик [j+2];
// теперь пройдите и выполняйте шифрование или дешифрование
for (i = loping [j]; i! = endloop; i+= loopinc) {// Для эффективности
Справа1 = справа ^ Ключи [i];
right2 = ((справа >>> 4) | (справа << 28)) ^ Keys [i+1];
// Результат достигается путем прохождения этих байтов через функции выбора S
темп = оставлен;
влево = справа;
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]);
}
темп = оставлен; влево = справа; справа = темп; // Неуправляемая слева и справа
} // для 1 или 3 итераций
// двигаться, затем каждый бит вправо
слева = ((слева >>> 1) | (слева << 31));
справа = ((справа >>> 1) | (справа << 31));
// теперь выполнять IP-1, который является IP в противоположном направлении
temp = ((слева >>> 1) ^ справа) & 0x555555555; справа ^= темп; слева ^= (темп << 1);
temp = ((справа >>> 8) ^ слева) & 0x00ff00ff; слева ^= темп; справа ^= (Temp << 8);
temp = ((справа >>> 2) ^ слева) & 0x333333333; слева ^= темп; справа ^= (темп << 2);
temp = ((слева >>> 16) ^ справа) и 0x0000ffff; справа ^= темп; слева ^= (темп << 16);
temp = ((слева >>> 4) ^ справа) & 0x0f0f0f0f; справа ^= темп; слева ^= (темп << 4);
// для режима цепочки блоков шифров, xor Сообщение с предыдущим результатом
if (mode == 1) {if (encrypt) {cbcleft = Left; cbcright = right;} else {left ^= cbcleft2; справа ^= cbcright2;}}
Tempresult += String.fromCharcode ((слева >>> 24), ((слева >>> 16) & 0xff), ((слева >>> 8) & 0xff), (слева и 0xff), (справа >>>>> 24), ((справа >>> 16) & 0xff), ((справа >>> 8) & 0xff), (справа и 0xff));
Chunk += 8;
if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 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,0x1000000,0x1000008,0x1000800,0x1000808,0x8,0x800,0x808,0x100000000000008 000
pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
pc2bytes4 = новый массив (0,0x40000,0x10,0x40010,0X40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010x1000,0x41000,0x1010,0x4101010101010,0x1000,0x41000 0x1010,0x4101010101010101010101ц.
pc2bytes5 = новый массив (0,0x400,0x20,0x420,0x400,0x20,0x420,0x2000000 0x2000400,0x20020,0x2000420,0x2000000 0x2000400,0x20020,0x2000420);
pc2bytes6 = новый массив (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0x1000000000,0x80000,0x10080000000X2,0x1002,0x8002,0x100800800008000000002,0x2,0x1002,0x8002,0x1008008000000002,0x1002,0x8002,0X1008000000000000000080000002,0x100002,0x800002,0X100800000000000080002,0x10000002,0x1002,0x10080000000020002,0x100002,0x800008);
pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
pc2bytes8 = новый массив (0,0x40000,0x4000000,0x2,0x40002,0x2,0x40002,0x2000000 0x204000000000000000000204000000200002,0x2040002,0X2002,0X2040002);
pc2bytes9 = новый массив (0,0x10000000,0x8,0x10000008,0x10000000,0x8,0x10000008,0x400,0x10040040808,0x100408,0x400,0x1004000508,08);
pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
pc2bytes11 = новый массив (0,0x100000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x40000000000000000005000200,0X5000200500500000000505000200,0020020020050050000505000,00200500020020050050000505000,002005000200200500500005000,0X20002005000200200500500005000200,00500020020050000000;
pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
pc2bytes13 = новый массив (0,0x4,0x100,0x104,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
// сколько итераций (1 для DES, 3 для Triple DES)
var iterations = key.length> 8? 3: 1; // Изменено Павлом 16/6/2007, чтобы использовать тройной DES для 9+ байтовых ключей
// хранит клавиши возврата
var keys = new Array (32 * итерации);
// теперь определите левые сдвиги, которые необходимо сделать
var shifts = новый массив (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0);
// другие переменные
var Leftemp, righttemp, m = 0, n = 0, temp;
for (var j = 0; j <итерации; j ++) {// либо 1, либо 3 итерации
слева = (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; справа ^= темп; слева ^= (темп << 4);
temp = ((справа >>> -16) ^ слева) & 0x0000ffff; слева ^= темп; справа ^= (Temp << -16);
temp = ((слева >>> 2) ^ справа) & 0x333333333; справа ^= темп; слева ^= (темп << 2);
temp = ((справа >>> -16) ^ слева) & 0x0000ffff; слева ^= темп; справа ^= (Temp << -16);
temp = ((слева >>> 1) ^ справа) & 0x555555555; справа ^= темп; слева ^= (темп << 1);
temp = ((справа >>> 8) ^ слева) & 0x00ff00ff; слева ^= темп; справа ^= (Temp << 8);
temp = ((слева >>> 1) ^ справа) & 0x555555555; справа ^= темп; слева ^= (темп << 1);
// правая сторона должна быть сдвинута и получить последние четыре бита левой стороны
temp = (слева << 8) | ((справа >>> 20) & 0x000000f0);
// слева нужно поставить с ног на голову
влево = (справа << 24) | ((справа << 8) & 0xff0000) | ((справа >>> 8) & 0xff00) | ((справа >>> 24) & 0xf0);
справа = темп;
// Теперь пройдите и выполняйте эти смены на левой и правой клавиши
for (var i = 0; i <shifts.length; i ++) {
// Сдвиг клавиши один или два бита влево
if (сдвиг [i]) {left = (слева << 2) | (слева >>> 26); справа = (справа << 2) | (справа >>> 26);}
else {left = (слева << 1) | (слева >>> 27); справа = (справа << 1) | (справа >>> 27);}
слева & = -0xf; справа и = -0xf;
// теперь применить PC-2, таким образом, что E проще при шифровании или расшифровке
// это преобразование будет выглядеть как ПК-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] | 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", "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 message = "Это тестовое сообщение";
var ciphertext = des (ключ, сообщение, 1, 0);
document.writeln ("des test:" + stringtohex (ciphertext));