5
5
KEYUTIL ,
6
6
b64utoutf8 ,
7
7
b64utohex ,
8
- utf8tohex
8
+ utf8tohex ,
9
+ b64tohex ,
10
+ ASN1HEX
9
11
} from 'jsrsasign' ;
10
12
11
13
import log from 'loglevel' ;
@@ -28,6 +30,44 @@ export function sign(header,
28
30
}
29
31
}
30
32
33
+ /**
34
+ * This function takes a PEM string with a public key and returns a
35
+ * jsrsasign key object (RSAKey, KJUR.crypto.DSA, KJUR.crypto.ECDSA). It also
36
+ * handles plain RSA keys not wrapped in a X.509 SubjectPublicKeyInfo
37
+ * structure.
38
+ * See: https://stackoverflow.com/questions/18039401/how-can-i-transform-between-the-two-styles-of-public-key-format-one-begin-rsa
39
+ * @param {String } publicKey The public key as a PEM string.
40
+ * @returns {Object } The public key as a jsrsasign key object.
41
+ */
42
+ function getPublicKeyObject ( publicKey ) {
43
+ try {
44
+ const startTag = '-----BEGIN RSA PUBLIC KEY-----' ;
45
+ const endTag = '-----END RSA PUBLIC KEY-----' ;
46
+ const startTagPos = publicKey . indexOf ( startTag ) ;
47
+ const endTagPos = publicKey . indexOf ( endTag ) ;
48
+
49
+ if ( startTagPos !== - 1 && endTagPos !== - 1 ) {
50
+ const plainDataBase64 =
51
+ publicKey . substr ( 0 , endTagPos )
52
+ . substr ( startTagPos + startTag . length ) ;
53
+
54
+ const plainDataDER = b64tohex ( plainDataBase64 ) ;
55
+
56
+ const barePublicKey = {
57
+ n : ASN1HEX . getVbyList ( plainDataDER , 0 , [ 0 ] , '02' ) ,
58
+ e : ASN1HEX . getVbyList ( plainDataDER , 0 , [ 1 ] , '02' )
59
+ } ;
60
+
61
+ return KEYUTIL . getKey ( barePublicKey ) ;
62
+ }
63
+ } catch ( e ) {
64
+ log . error ( 'Failed to make public key into X.509 ' +
65
+ 'SubjectPublicKeyInfo key:' , e ) ;
66
+ }
67
+
68
+ return KEYUTIL . getKey ( publicKey ) ;
69
+ }
70
+
31
71
export function verify ( jwt , secretOrPublicKeyString , base64Secret = false ) {
32
72
if ( ! isToken ( jwt ) ) {
33
73
return false ;
@@ -46,11 +86,12 @@ export function verify(jwt, secretOrPublicKeyString, base64Secret = false) {
46
86
b64utohex ( secretOrPublicKeyString ) :
47
87
utf8tohex ( secretOrPublicKeyString ) ) ;
48
88
} else {
49
- return jws . JWS . verify ( jwt , secretOrPublicKeyString ) ;
89
+ const publicKeyObject = getPublicKeyObject ( secretOrPublicKeyString ) ;
90
+ return jws . JWS . verify ( jwt , publicKeyObject ) ;
50
91
}
51
92
} catch ( e ) {
52
93
log . warn ( 'Could not verify token, ' +
53
- 'probably due to bad data in it or the keys: ' , e ) ;
94
+ 'probably due to bad data in it or the keys: ' , e ) ;
54
95
return false ;
55
96
}
56
97
}
0 commit comments