Skip to content

Commit 96f6744

Browse files
committed
iv and message check
1 parent 73b6ae6 commit 96f6744

File tree

1 file changed

+35
-27
lines changed

1 file changed

+35
-27
lines changed

src/primitives/SymmetricKey.ts

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ export default class SymmetricKey extends BigNumber {
2222
* @example
2323
* const symmetricKey = SymmetricKey.fromRandom();
2424
*/
25-
static fromRandom (): SymmetricKey {
26-
return new SymmetricKey(Random(32))
25+
static fromRandom(): SymmetricKey {
26+
return new SymmetricKey(Random(32));
2727
}
2828

2929
/**
@@ -40,25 +40,20 @@ export default class SymmetricKey extends BigNumber {
4040
* const key = new SymmetricKey(1234);
4141
* const encryptedMessage = key.encrypt('plainText', 'utf8');
4242
*/
43-
encrypt (msg: number[] | string, enc?: 'hex'): string | number[] {
44-
const iv = Random(32)
45-
msg = toArray(msg, enc)
46-
const keyBytes = this.toArray('be', 32)
47-
const { result, authenticationTag } = AESGCM(
48-
msg,
49-
[],
50-
iv,
51-
keyBytes
52-
)
53-
const totalLength = iv.length + result.length + authenticationTag.length
54-
const combined = new Array(totalLength)
55-
let offset = 0
43+
encrypt(msg: number[] | string, enc?: 'hex'): string | number[] {
44+
const iv = Random(32);
45+
msg = toArray(msg, enc);
46+
const keyBytes = this.toArray('be', 32);
47+
const { result, authenticationTag } = AESGCM(msg, [], iv, keyBytes);
48+
const totalLength = iv.length + result.length + authenticationTag.length;
49+
const combined = new Array(totalLength);
50+
let offset = 0;
5651
for (const chunk of [iv, result, authenticationTag]) {
5752
for (let i = 0; i < chunk.length; i++) {
58-
combined[offset++] = chunk[i]
53+
combined[offset++] = chunk[i];
5954
}
6055
}
61-
return encode(combined, enc)
56+
return encode(combined, enc);
6257
}
6358

6459
/**
@@ -77,22 +72,35 @@ export default class SymmetricKey extends BigNumber {
7772
*
7873
* @throws {Error} Will throw an error if the decryption fails, likely due to message tampering or incorrect decryption key.
7974
*/
80-
decrypt (msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
81-
msg = toArray(msg, enc)
82-
const iv = msg.slice(0, 32)
83-
const tagStart = msg.length - 16
84-
const ciphertext = msg.slice(32, tagStart)
85-
const messageTag = msg.slice(tagStart)
75+
decrypt(msg: number[] | string, enc?: 'hex' | 'utf8'): string | number[] {
76+
msg = toArray(msg, enc);
77+
78+
if (msg.length < 48) {
79+
throw new Error('Ciphertext too short');
80+
}
81+
82+
const ivLength = 32;
83+
const tagLength = 16;
84+
85+
const iv = msg.slice(0, ivLength);
86+
const tagStart = msg.length - tagLength;
87+
const ciphertext = msg.slice(ivLength, tagStart);
88+
const messageTag = msg.slice(tagStart);
89+
90+
if (tagStart < ivLength) {
91+
throw new Error('Malformed ciphertext');
92+
}
93+
8694
const result = AESGCMDecrypt(
8795
ciphertext,
8896
[],
8997
iv,
9098
messageTag,
91-
this.toArray('be', 32)
92-
)
99+
this.toArray('be', 32),
100+
);
93101
if (result === null) {
94-
throw new Error('Decryption failed!')
102+
throw new Error('Decryption failed!');
95103
}
96-
return encode(result, enc)
104+
return encode(result, enc);
97105
}
98106
}

0 commit comments

Comments
 (0)