Skip to content

Commit

Permalink
fix: padding ignored for encryption without iv
Browse files Browse the repository at this point in the history
  • Loading branch information
ayZagen committed Sep 20, 2021
1 parent bc42aa6 commit 703af9a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/keystore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export class KeyStore {
authTagLength,
} = finalOptions

const keys = key ? [ key ] : defaultKeys
const keys = key ? [key] : defaultKeys
if (keys.length === 0) {
throw new Error("keys required for encrypted cookies")
}
Expand All @@ -148,10 +148,12 @@ export class KeyStore {
authTag = Buffer.from(authTag, encoding)
}

if (!iv) {
iv = dataBuff.slice(0, cipherInfo.ivLength)
if (cipherInfo.ivLength !== undefined) {
if (!iv) {
iv = dataBuff.slice(0, cipherInfo.ivLength)
}
dataBuff = dataBuff.slice(cipherInfo.ivLength, dataBuff.length)
}
dataBuff = dataBuff.slice(cipherInfo.ivLength, dataBuff.length)


if (AUTH_TAG_REQUIRED.test(algorithm)) {
Expand All @@ -170,20 +172,21 @@ export class KeyStore {

private static doDecrypt(data: Buffer, options: DecryptOptions): string | null {
const {algorithm, key, iv, authTagLength, authTag} = options
const decipher = crypto.createDecipheriv(algorithm as any, key!, iv as Buffer, {authTagLength});
const decipher = crypto.createDecipheriv(algorithm as any, key!, iv as Buffer || null, {authTagLength});

if (authTag) {
decipher.setAuthTag(authTag as Buffer)
}

const plainText = decipher.update(data)
let final: Buffer
try {
decipher.final()
} catch {
final = decipher.final()
} catch(e:any) {
// authentication failed
return null
}
return plainText.toString('utf-8')
return Buffer.concat([plainText, final]).toString('utf-8')
}

//region: signing
Expand Down
27 changes: 27 additions & 0 deletions tests/keystore.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,20 @@ describe("encryption", () => {
expect(decrypted).toBe(null)
});


it("should allow using different secret key", () => {
const ks = new KeyStore({
encryption: {
keys: ["secretsecretsecretsecret"],
algorithm: "aes-192-cbc",
encoding: "hex"
}
})
jest.spyOn(crypto, 'randomBytes').mockImplementationOnce(() => Buffer.from("1234123412341234", "utf-8"))
const encrypted = ks.encrypt("ohmytext", {key: "necretnecretnecretnecret"})
expect(ks.decrypt(encrypted, { key: "necretnecretnecretnecret" })).toBe("ohmytext")
})

it("should fail if no key exists to decrypt with", () => {
const ks = new KeyStore({
encryption: {keys: [genRandom(24)]}
Expand All @@ -257,6 +271,19 @@ describe("encryption", () => {
}).toThrow(Error)
})


it("should work w/ algorithms without iv", () => {
const ks = new KeyStore({
encryption: {
keys: ["32secretsecretsecretsecretsecret"],
algorithm: "aes-256-ecb",
encoding: "base64"
}
})
const encrypted = ks.encrypt("ohmytext")
expect(ks.decrypt(encrypted)).toBe("ohmytext")
})

it("should accept iv buffer", () => {
const ks = new KeyStore({
encryption: {
Expand Down

0 comments on commit 703af9a

Please sign in to comment.