Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1x 1x 1x 5x 5x 5x 1x 1x 3x 3x 3x 3x 3x 3x 1x 2x 2x 2x 2x 2x 2x 2x 1x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 1x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x | import { createCipheriv, createDecipheriv, randomBytes, scryptSync, } from "crypto"; import { SecretString } from "./Secret"; const ALGORITHM = "aes-256-cbc"; const DELIMITER = "#"; function makeKey(password: SecretString, salt: Buffer): Buffer { return scryptSync(password.value(), salt, 32); } export class EncryptedValue { cipherText: string; iv: Buffer; salt: Buffer; static makeFromPlainText( plainText: string, password: SecretString ): EncryptedValue { const { cipherText, iv, salt } = encrypt(plainText, password); return new EncryptedValue(cipherText, iv, salt); } static makeFromSerializedText(serializedText: string): EncryptedValue { const splited = serializedText.split(DELIMITER); if (splited.length != 3) { throw new Error( `invalid serializedText, splited length is not 3, original:${serializedText}, splited:${splited}` ); } const iv = Buffer.from(splited[0] || "", "hex"); const salt = Buffer.from(splited[1] || "", "hex"); const cipherText = splited[2] || ""; return new EncryptedValue(cipherText, iv, salt); } constructor(cipherText: string, iv: Buffer, salt: Buffer) { this.cipherText = cipherText; this.iv = iv; this.salt = salt; } serialize(): string { return ( this.iv.toString("hex") + DELIMITER + this.salt.toString("hex") + DELIMITER + this.cipherText ); } decrypt(password: SecretString): SecretString { return decrypt(this.cipherText, password, this.salt, this.iv); } } function encrypt( plainText: string, password: SecretString ): { cipherText: string; iv: Buffer; salt: Buffer; } { const iv = randomBytes(16); const salt = randomBytes(16); const key = makeKey(password, salt); const cipher = createCipheriv(ALGORITHM, key, iv); let cipherText = cipher.update(plainText, "utf8", "hex"); cipherText += cipher.final("hex"); return { cipherText, iv, salt, }; } function decrypt( cipherText: string, password: SecretString, salt: Buffer, iv: Buffer ): SecretString { const key = makeKey(password, salt); const decipher = createDecipheriv(ALGORITHM, key, iv); let plainText = decipher.update(cipherText, "hex", "utf8"); plainText += decipher.final("utf8"); return new SecretString(plainText); } |