Skip to content

Commit c4399dc

Browse files
authored
fix: use raw asn1js int value to improve performance (#2788)
When converting an asn1js Integer to a base64url encoded string, use the raw byte value instead of converting it to a string, then a bigint, then bytes.
1 parent d34642d commit c4399dc

File tree

1 file changed

+16
-27
lines changed

1 file changed

+16
-27
lines changed

packages/crypto/src/keys/rsa/utils.ts

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ export function pkcs1ToJwk (bytes: Uint8Array): JsonWebKey {
2424
const values: asn1js.Integer[] = result.valueBlock.value
2525

2626
const key = {
27-
n: uint8ArrayToString(bnToBuf(values[1].toBigInt()), 'base64url'),
28-
e: uint8ArrayToString(bnToBuf(values[2].toBigInt()), 'base64url'),
29-
d: uint8ArrayToString(bnToBuf(values[3].toBigInt()), 'base64url'),
30-
p: uint8ArrayToString(bnToBuf(values[4].toBigInt()), 'base64url'),
31-
q: uint8ArrayToString(bnToBuf(values[5].toBigInt()), 'base64url'),
32-
dp: uint8ArrayToString(bnToBuf(values[6].toBigInt()), 'base64url'),
33-
dq: uint8ArrayToString(bnToBuf(values[7].toBigInt()), 'base64url'),
34-
qi: uint8ArrayToString(bnToBuf(values[8].toBigInt()), 'base64url'),
27+
n: asn1jsIntegerToBase64(values[1]),
28+
e: asn1jsIntegerToBase64(values[2]),
29+
d: asn1jsIntegerToBase64(values[3]),
30+
p: asn1jsIntegerToBase64(values[4]),
31+
q: asn1jsIntegerToBase64(values[5]),
32+
dp: asn1jsIntegerToBase64(values[6]),
33+
dq: asn1jsIntegerToBase64(values[7]),
34+
qi: asn1jsIntegerToBase64(values[8]),
3535
kty: 'RSA',
3636
alg: 'RS256'
3737
}
@@ -78,8 +78,8 @@ export function pkixToJwk (bytes: Uint8Array): JsonWebKey {
7878

7979
return {
8080
kty: 'RSA',
81-
n: uint8ArrayToString(bnToBuf(values[0].toBigInt()), 'base64url'),
82-
e: uint8ArrayToString(bnToBuf(values[1].toBigInt()), 'base64url')
81+
n: asn1jsIntegerToBase64(values[0]),
82+
e: asn1jsIntegerToBase64(values[1])
8383
}
8484
}
8585

@@ -120,26 +120,15 @@ export function jwkToPkix (jwk: JsonWebKey): Uint8Array {
120120
return new Uint8Array(der, 0, der.byteLength)
121121
}
122122

123-
function bnToBuf (bn: bigint): Uint8Array {
124-
let hex = bn.toString(16)
123+
function asn1jsIntegerToBase64 (int: asn1js.Integer): string {
124+
let buf = int.valueBlock.valueHexView
125125

126-
if (hex.length % 2 > 0) {
127-
hex = `0${hex}`
126+
// chrome rejects values with leading 0s
127+
while (buf[0] === 0) {
128+
buf = buf.subarray(1)
128129
}
129130

130-
const len = hex.length / 2
131-
const u8 = new Uint8Array(len)
132-
133-
let i = 0
134-
let j = 0
135-
136-
while (i < len) {
137-
u8[i] = parseInt(hex.slice(j, j + 2), 16)
138-
i += 1
139-
j += 2
140-
}
141-
142-
return u8
131+
return uint8ArrayToString(buf, 'base64url')
143132
}
144133

145134
function bufToBn (u8: Uint8Array): bigint {

0 commit comments

Comments
 (0)