Перейти к основному содержимому
clawam tools
Инструменты Документы Daoark EN Главная Главная / Verschlüsselung & Codierung › Главная manifest.json > (7-j)) & 1; return bits; } function bitsToBytes(bits) { var arr = new Uint8Array(bits.length >> 3); for (var i = 0; i < bits.length; i++) if (bits[i]) arr[i>>3] |= 1 << (7-(i&7)); return arr; } function permute(bits, table) { var r = new Array(table.length); for (var i = 0; i < table.length; i++) r[i] = bits[table[i]-1]; return r; } function genSubkeys(keyBytes) { var bits = bytesToBits(keyBytes); var cd = permute(bits, PC1); var C = cd.slice(0, 28), D = cd.slice(28); var subs = []; for (var r = 0; r < 16; r++) { var s = SHIFTS[r]; C = C.slice(s).concat(C.slice(0, s)); D = D.slice(s).concat(D.slice(0, s)); subs.push(permute(C.concat(D), PC2)); } return subs; } function sboxLookup(xb) { var out = new Array(32); for (var i = 0; i < 8; i++) { var b = xb.slice(i*6, i*6+6); var row = (b[0] << 1) | b[5]; var col = (b[1] << 3) | (b[2] << 2) | (b[3] << 1) | b[4]; var v = SBOX[i][row][col]; for (var j = 0; j < 4; j++) out[i*4 + j] = (v >> (3-j)) & 1; } return out; } function feistel(R, subkey) { var er = permute(R, E); var xr = new Array(48); for (var i = 0; i < 48; i++) xr[i] = er[i] ^ subkey[i]; return permute(sboxLookup(xr), P); } function desBlock(block, subs, decrypt) { var bits = bytesToBits(block); var ip = permute(bits, IP); var L = ip.slice(0, 32), R = ip.slice(32); for (var r = 0; r < 16; r++) { var f = feistel(R, decrypt ? subs[15-r] : subs[r]); var newR = new Array(32); for (var i = 0; i < 32; i++) newR[i] = L[i] ^ f[i]; L = R; R = newR; } return bitsToBytes(permute(R.concat(L), FP)); } function pkcs5PadD(d) { var p = 8 - (d.length % 8); var o = new Uint8Array(d.length + p); for (var i = 0; i < d.length; i++) o[i] = d[i]; for (var i = 0; i < p; i++) o[d.length + i] = p; return o; } function pkcs5UnpadD(d) { if (d.length === 0) return d; var p = d[d.length - 1]; if (p < 1 || p > 8) return d; return d.slice(0, d.length - p); } function desCryptD(data, key, iv, mode, decrypt) { var subs = genSubkeys(key); if (mode === 'ECB') { var out = new Uint8Array(data.length); for (var i = 0; i < data.length; i += 8) { var r = desBlock(data.slice(i, i+8), subs, decrypt); for (var j = 0; j < 8; j++) out[i+j] = r[j]; } return out; } else { if (iv.length !== 8) throw new Error('IV 8 bytes'); var out2 = new Uint8Array(data.length); var prev = iv; for (var i = 0; i < data.length; i += 8) { var block = data.slice(i, i+8); if (decrypt) { var dec = desBlock(block, subs, true); var x = new Uint8Array(8); for (var j = 0; j < 8; j++) x[j] = dec[j] ^ prev[j]; for (var j = 0; j < 8; j++) out2[i+j] = x[j]; prev = block; } else { var x2 = new Uint8Array(8); for (var j = 0; j < 8; j++) x2[j] = block[j] ^ prev[j]; var enc = desBlock(x2, subs, false); for (var j = 0; j < 8; j++) out2[i+j] = enc[j]; prev = enc; } } return out2; } } function tryDes(op) { var key = hexToBytes(getVal('key')); if (key.length !== 8) { showError('密钥必须 8 字节(16 hex)'); return; } var iv = getVal('iv') ? hexToBytes(getVal('iv')) : new Uint8Array(8); var mode = getVal('mode'); if (mode === 'CBC' && iv.length !== 8) { showError('IV 必须 8 字节(16 hex)'); return; } var input = getVal('text'); if (op === 'enc') { var data = new TextEncoder().encode(input); var padded = pkcs5PadD(data); var ct = desCryptD(padded, key, iv, mode, false); showResult(bytesToHex(ct), 'DES-' + mode + ' 加密,明文 ' + data.length + ' 字节,密文 ' + ct.length + ' 字节'); } else { var ct2 = hexToBytes(input); if (ct2.length % 8 !== 0) { showError('密文长度必须 8 字节倍数'); return; } var pt = desCryptD(ct2, key, iv, mode, true); var unpadded = pkcs5UnpadD(pt); showResult(new TextDecoder().decode(unpadded), 'DES-' + mode + ' 解密,明文 ' + unpadded.length + ' 字节'); } } function try3des(op) { var keyHex = getVal('key').replace(/\\s+/g, ''); if (keyHex.length !== 48 && keyHex.length !== 32) { showError('3DES 密钥必须 48 hex 或 32 hex(EDE2)'); return; } var key = hexToBytes(keyHex); var k1 = key.slice(0, 8), k2 = key.length === 8 ? key : key.slice(8, 16), k3 = key.length === 8 ? key : key.slice(16, 24); var iv = getVal('iv') ? hexToBytes(getVal('iv')) : new Uint8Array(8); var mode = getVal('mode'); if (mode === 'CBC' && iv.length !== 8) { showError('IV 必须 8 字节'); return; } var input = getVal('text'); if (op === 'enc') { var data = new TextEncoder().encode(input); var padded = pkcs5PadD(data); var ct = desCryptD(padded, k1, iv, mode, false); ct = desCryptD(ct, k2, iv, mode, true); ct = desCryptD(ct, k3, iv, mode, false); showResult(bytesToHex(ct), '3DES-EDE-' + mode + ' 加密,明文 ' + data.length + ' 字节,密文 ' + ct.length + ' 字节'); } else { var ct2 = hexToBytes(input); if (ct2.length % 8 !== 0) { showError('密文长度必须 8 字节倍数'); return; } var pt = desCryptD(ct2, k3, iv, mode, true); pt = desCryptD(pt, k2, iv, mode, false); pt = desCryptD(pt, k1, iv, mode, true); var unpadded = pkcs5UnpadD(pt); showResult(new TextDecoder().decode(unpadded), '3DES-EDE-' + mode + ' 解密,明文 ' + unpadded.length + ' 字节'); } } function hexToBytes(h) { h = (h||'').replace(/\\s+/g, ''); if (h.length % 2 !== 0) throw new Error('hex even'); var o = new Uint8Array(h.length / 2); for (var i = 0; i < o.length; i++) o[i] = parseInt(h.substring(i*2, i*2+2), 16); return o; } function bytesToHex(b) { var s = ''; for (var i = 0; i < b.length; i++) { var h = b[i].toString(16); s += h.length===1?'0'+h:h; } return s; } try3des(getVal("op")); return; showResult(result, meta); } catch (e) { showError('处理失败: ' + (e.message || e)); } } $('btn-main').addEventListener('click', function(e) { e.preventDefault(); doProcess(); }); $('btn-clear').addEventListener('click', function() { var inputs = document.querySelectorAll('input,textarea,select'); for (var i=0; i