diff --git a/src/ssn/decryption/decryptFile.ts b/src/ssn/decryption/decryptFile.ts index 53071a4..69f8d36 100644 --- a/src/ssn/decryption/decryptFile.ts +++ b/src/ssn/decryption/decryptFile.ts @@ -1,16 +1,16 @@ -import getCrc from './getCrc'; -import int32Mul from './int32Mul'; +import updateKeys from './updateKeys'; export default function decryptFile(dv: DataView, length: number, [key0, key1, key2]: [number, number, number]) { - for (let j = 0; j < length; j += 1) { - let testChar = dv.getUint8(j); - const keyPart = (key2 | 2) & 0xFFFF; - const decryptedByte = (keyPart * (keyPart ^ 1)) >>> 8; - testChar ^= decryptedByte & 0xFF; - key0 = getCrc(key0, testChar); - key1 = ((int32Mul(((key1 + (key0 & 0xFF)) >>> 0), 134775813) >>> 0) + 1) >>> 0; - key2 = getCrc(key2, key1 >>> 24); - dv.setUint8(j, testChar); + for (let i = 0; i < length; i += 1) { + //read and decrypt byte + let curChar = dv.getUint8(i); + const keyPart = (key2 | 2) & 0xFFFF; + const decryptedByte = (keyPart * (keyPart ^ 1)) >>> 8; + curChar ^= decryptedByte & 0xFF; + dv.setUint8(i, curChar); + + //update keys + [key0, key1, key2] = updateKeys([key0, key1, key2], curChar); } //if it was decrypted, we skip the first 12 bytes (random encryption header) return new DataView(dv.buffer, 12); diff --git a/src/ssn/decryption/getDecryptionKeys.ts b/src/ssn/decryption/getDecryptionKeys.ts index d97db62..c796a6f 100644 --- a/src/ssn/decryption/getDecryptionKeys.ts +++ b/src/ssn/decryption/getDecryptionKeys.ts @@ -1,22 +1,19 @@ -import getCrc from './getCrc'; -import int32Mul from './int32Mul'; +import updateKeys from './updateKeys'; -export default function getDecryptionKeys(password: Uint8Array) { - const keys: [number, number, number] = [0x12345678, 0x23456789, 0x34567890]; +export default function getDecryptionKeys(password: Uint8Array): [number, number, number] { + let [key0, key1, key2] = [0x12345678, 0x23456789, 0x34567890]; const passwordLength = password.length; - //update keys + //read through password for (let i = 0; i < passwordLength; i++) { - if (password[i] === 0) { break; } - keys[0] = getCrc(keys[0], password[i]); - keys[1] = - (( - int32Mul(( - ((keys[1] >>> 0) + (keys[0] & 0xFF)) >>> 0 - ), 134775813) >>> 0 - ) + 1) >>> 0; - keys[2] = getCrc(keys[2] >>> 0, keys[1] >>> 24); + const curChar = password[i]; + + //Exit early if there's a zero byte in the password + if (curChar === 0) { break; } + + //update keys + [key0, key1, key2] = updateKeys([key0, key1, key2], curChar); } - return keys; + return [key0, key1, key2]; } diff --git a/src/ssn/decryption/updateKeys.ts b/src/ssn/decryption/updateKeys.ts new file mode 100644 index 0000000..986bd0d --- /dev/null +++ b/src/ssn/decryption/updateKeys.ts @@ -0,0 +1,10 @@ +import getCrc from './getCrc'; +import int32Mul from './int32Mul'; + +export default function updateKeys([key0, key1, key2]: [number, number, number], curChar: number): [number, number, number] { + key0 = getCrc(key0, curChar); + key1 = ((int32Mul(((key1 + (key0 & 0xFF)) >>> 0), 134775813) >>> 0) + 1) >>> 0; + key2 = getCrc(key2, key1 >>> 24); + + return [key0, key1, key2]; +}