From 55569c55235c0a82525b142ea9a4f8a2669654ce Mon Sep 17 00:00:00 2001 From: haotianlong Date: Tue, 9 Jul 2024 15:14:34 +0800 Subject: [PATCH] fix(asn1): correct the implementation of the long version of L encoding in asn.1 --- src/sm2/asn1.ts | 8 +++++++- test/sm2.test.ts | 25 +++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/sm2/asn1.ts b/src/sm2/asn1.ts index 9fedc19..e2534d3 100755 --- a/src/sm2/asn1.ts +++ b/src/sm2/asn1.ts @@ -113,7 +113,13 @@ class DERSequence extends ASN1Object { */ function getLenOfL(str: string, start: number) { if (+str[start + 2] < 8) return 1 // l 以0开头,则表示短格式,只占一个字节 - return +str.substring(start + 2, start + 4) & 0x7f + 1 // 长格式,取第一个字节后7位作为长度真正占用字节数,再加上本身 + // 长格式,取第一个字节后7位作为长度真正占用字节数,再加上本身 + const encoded = str.slice(start + 2, start + 6); + const headHex = encoded.slice(0, 2); + const head = parseInt(headHex, 16); + const nHexLength = (head - 128) * 2; + + return nHexLength; } /** diff --git a/test/sm2.test.ts b/test/sm2.test.ts index ddf17a1..c0170c5 100644 --- a/test/sm2.test.ts +++ b/test/sm2.test.ts @@ -96,17 +96,38 @@ describe('sm2: encrypt and decrypt data', () => { describe('sm2: encrypt and decrypt data using asn1 encoding', () => { - it('decrypted data should be correct', () => { + it('decrypted data should be correct (non asn.1)', () => { const input = 'aabbccdd' const res = sm2.doEncrypt(hexToArray(input), '049812a275eca335e85998eb4030a6cc9e88a098010bdbfc134b26e29c43253439d3821ef18e69e0813bcc55eee7dc9163f1edb81ad2032b20cbdf1408897faaac', 1, { - asn1: true, + asn1: false, }) // console.log('res', res) + const dec = sm2.doDecrypt(res, '75b25a5d6101013e9be25816f81cf1f64bf78ea8383b32d61f5b26e6f1429e70', 1, { + output: 'array', + asn1: false, + }) + expect(arrayToHex([...dec])).toBe(input) + }) + it('decrypted data should be correct (asn.1)', () => { + const input = 'aabbccdd' + const res = sm2.doEncrypt(hexToArray(input), '049812a275eca335e85998eb4030a6cc9e88a098010bdbfc134b26e29c43253439d3821ef18e69e0813bcc55eee7dc9163f1edb81ad2032b20cbdf1408897faaac', 1, { + asn1: true, + }) const dec = sm2.doDecrypt(res, '75b25a5d6101013e9be25816f81cf1f64bf78ea8383b32d61f5b26e6f1429e70', 1, { output: 'array', asn1: true, }) expect(arrayToHex([...dec])).toBe(input) + const input2 = 'xxxxx{"xx": "111","t": "1"}' + const res2 = sm2.doEncrypt(input2, '049812a275eca335e85998eb4030a6cc9e88a098010bdbfc134b26e29c43253439d3821ef18e69e0813bcc55eee7dc9163f1edb81ad2032b20cbdf1408897faaac', 1, { + asn1: true, + }) + console.log(res2) + const dec2 = sm2.doDecrypt(res2, '75b25a5d6101013e9be25816f81cf1f64bf78ea8383b32d61f5b26e6f1429e70', 1, { + output: 'string', + asn1: true, + }) + expect(dec2).toBe(input2) }) it('decrypted data should be correct: c1c2c3', () => { const input = 'aabbccdd'