//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 = 새 어레이(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,0x8 00,0x200002);
var spfunction8 = 새 배열(0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x 41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000 ,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1 000,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개의 하위 키를 생성합니다.
varkeys = 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 = encrypt ? 새 배열(0, 32, 2) : 새 배열(30, -2, -2);}
else {looping = encrypt ? 새 배열(0, 32, 2, 62, 30, -2, 64, 96, 2) : 새 배열(94, 62, -2, 32, 64, 2, 30, -2, -2);}
//패딩 매개변수에 따라 메시지를 채웁니다.
if (padding == 2) message = " "; //메시지를 공백으로 채웁니다.
else if (padding == 1) {temp = 8-(len%8); message = String.fromCharCode(온도,온도,온도,온도,온도,온도,온도,온도); if (temp==8) len =8;} //PKCS7 패딩
else if (!padding) message = " "; //널 바이트로 메시지를 채웁니다.
//여기에 결과를 저장합니다.
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 );
//Cipher Block Chaining 모드의 경우 이전 결과와 메시지를 xor합니다.
if (mode == 1) {if (encrypt) {left ^= cbcleft; 오른쪽 ^= cbcright;} else {cbcleft2 = cbcleft; cbright2 = cbright; cbcleft = 왼쪽; cbright = 오른쪽;}}
//먼저 각 64개이지만 메시지 덩어리는 IP
temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;에 따라 변경되어야 합니다. 오른쪽 ^= 온도; 왼쪽 ^= (온도 temp = ((왼쪽 >>> 16) ^ 오른쪽) & 0x0000ffff; 오른쪽 ^= 온도; 왼쪽 ^= (온도 temp = ((오른쪽 >>> 2) ^ 왼쪽) & 0x33333333; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((오른쪽 >>> 8) ^ 왼쪽) & 0x00ff00ff; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((왼쪽 >>> 1) ^ 오른쪽) & 0x55555555; 오른쪽 ^= 온도; 왼쪽 ^= (온도
left = ((왼쪽 << 1) | (왼쪽 >>> 31));
right = ((오른쪽 << 1) | (오른쪽 >>> 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) | (오른쪽 | spfunction6[(right1 >> ;> 8) & 0x3f] | spfunction8[right1 & 0x3f]
| spfunction1[(right2 >> 24) & 0x3f] | spfunction3[(right2 >> 16)
| spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
}
온도 = 왼쪽; 왼쪽 = 오른쪽; 오른쪽 = 온도; //왼쪽과 오른쪽 반전
} //1회 또는 3회 반복
//한 비트씩 오른쪽으로 이동
left = ((왼쪽 >>> 1) |(왼쪽 right = ((오른쪽 >>> 1) | (오른쪽 << 31));
//이제 반대 방향의 IP인 IP-1을 수행합니다.
temp = ((left >>> 1) ^ right) & 0x55555555; 오른쪽 ^= 온도; 왼쪽 ^= (온도 temp = ((오른쪽 >>> 8) ^ 왼쪽) & 0x00ff00ff; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((오른쪽 >>> 2) ^ 왼쪽) & 0x33333333; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((왼쪽 >>> 16) ^ 오른쪽) & 0x0000ffff; 오른쪽 ^= 온도; 왼쪽 ^= (온도 temp = ((왼쪽 >>> 4) ^ 오른쪽) & 0x0f0f0f0f; 오른쪽 ^= 온도; 왼쪽 ^= (온도
//Cipher Block Chaining 모드의 경우 이전 결과와 메시지를 xor합니다.
if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = 오른쪽;} else {왼쪽 ^= cbcleft2; right ^= cbcright2;}}
tempresult = String.fromCharCode ((왼쪽>>>24), ((왼쪽>>>16) & 0xff), ((왼쪽>>>8) & 0xff), (왼쪽 & 0xff), (오른쪽>>>24), ((오른쪽>>>16) & 0xff), ((오른쪽>>>8) & 0xff), (오른쪽 & 0xff));
청크 = 8;
if (청크 == 512) {result = 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,0x20000004,0x10000, 0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
pc2bytes1 = 새 배열(0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0 x4000101,0x4100100,0x4100101); pc2bytes3 = 새 배열(0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0 x22000,0x222000,0x8022000,0x8222000); PC2BYTES4 = 새로운 어레이 (0,0X40000,0X10,0X40010,0X40000,0X10,0X40010,0X1000,0X41000,0X10,0X410,0X1000,0X41000,0X1010,0X41010);
pc2bytes5 = 새 배열(0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020 ,0x2000420);
pc2bytes6 = 새 배열(0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x1 0000002,0x80002,0x10080002);
pc2bytes7 = 새 배열(0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x200 20000,0x20030000,0x20020800,0x20030800);
pc2bytes8 = 새 배열(0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0 x2000002,0x2040002);
pc2bytes9 = 새 배열(0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x1000040 0,0x408,0x10000408);
pc2bytes10 = 새 배열(0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0 x102020);
pc2bytes11 = 새 배열(0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x500020 0,0x4200000,0x5200000,0x4200200,0x5200200);
pc2bytes12 = 새 배열(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,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
//반복 횟수(des의 경우 1회, Triple des의 경우 3회)
var iterations = key.length > 8? 3:1; //2007년 6월 16일 Paul이 9바이트 키에 Triple DES를 사용하도록 변경했습니다.
//반환 키를 저장합니다.
varkeys = 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) << 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 = ((오른쪽 >>> -16) ^ 왼쪽) & 0x0000ffff; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((왼쪽 >>>> 2) ^ 오른쪽) & 0x33333333; 오른쪽 ^= 온도; 왼쪽 ^= (온도 temp = ((오른쪽 >>> -16) ^ 왼쪽) & 0x0000ffff; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((왼쪽 >>> 1) ^ 오른쪽) & 0x55555555; 오른쪽 ^= 온도; 왼쪽 ^= (온도 temp = ((오른쪽 >>> 8) ^ 왼쪽) & 0x00ff00ff; 왼쪽 ^= 온도; 오른쪽 ^= (온도 temp = ((왼쪽 >>> 1) ^ 오른쪽) & 0x55555555; 오른쪽 ^= 온도; 왼쪽 ^= (온도
//오른쪽을 이동하고 왼쪽의 마지막 4비트를 가져와야 합니다.
temp = (left << 8) | ((오른쪽 >>> 20) & 0x000000f0);
//left는 거꾸로 놓아야 합니다.
left = (right << 24) | ((오른쪽 << 8) & 0xff0000) | ((오른쪽 >>> 8) & 0xff00) | ((오른쪽>>>24) & 0xf0);
오른쪽 = 온도;
//이제 왼쪽 및 오른쪽 키에서 이러한 Shift 키를 수행합니다.
for (var i=0; i //키 중 하나를 이동합니다. 왼쪽으로 1~2비트
if (shifts[i]) {left = (left << 2) | (왼쪽>>>26); 오른쪽 = (오른쪽 << 2) | (오른쪽 >>> 26);}
else {왼쪽 = (왼쪽 << 1) | (왼쪽>>>27); 오른쪽 = (오른쪽 << 1) | (오른쪽 >>> 27);}
왼쪽 &= -0xf; 오른쪽 &= -0xf;
//이제 암호화 또는 복호화 시 E가 더 쉬운 방식으로 PC-2를 적용합니다.
//이 변환은 각 바이트의 마지막 6비트만 사용된다는 점을 제외하면 PC-2처럼 보입니다.
//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] = 왼쪽온도 ^ 임시; 키[n ] = righttemp ^ (temp << 16);
}
} //각 반복마다
//생성한 키를 반환합니다.
return key;
} //des_createKeys 끝
///////////////////////////// / 테스트 /////////////////////////////
function stringToHex (s) {
var r = "0x" ;
var hexes = 새 배열("0","1","2","3","4","5","6","7","8","9"," a","b","c","d","e","f");
for (var i=0; i>return r;
}
function hexToString (h) {
var r = "";
for (var i= (h.substr(0, 2)=="0x")?2:0; ireturn r;
}
var key = "24바이트 키입니다!!";
var message = "테스트 메시지입니다.";
var ciphertext = des(키, 메시지, 1, 0);
document.writeln("DES 테스트: " stringToHex(암호문));
< 16);
}
} //각 반복마다
//생성한 키를 반환합니다.
return key;
} //des_createKeys 끝
///////////////////////////// / 테스트 /////////////////////////////
function stringToHex (s) {
var r = "0x" ;
var hexes = 새 배열("0","1","2","3","4","5","6","7","8","9"," a","b","c","d","e","f");
for (var i=0; i>