-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #268 from auth0/temp-idtv-2
Refactor RSA verification: Replace jsrsasign with crypto-js
- Loading branch information
Showing
8 changed files
with
212 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import * as base64 from '../base64'; | ||
|
||
describe('helpers base64 url', function() { | ||
describe('padding', function() { | ||
it('does not add to multiple of 4', function() { | ||
expect(base64.padding('')).toBe(''); | ||
expect(base64.padding('abcd')).toBe('abcd'); | ||
}); | ||
it('adds to non multiple of 4', function() { | ||
expect(base64.padding('a')).toBe('a==='); | ||
expect(base64.padding('ab')).toBe('ab=='); | ||
expect(base64.padding('abc')).toBe('abc='); | ||
expect(base64.padding('abced')).toBe('abced==='); | ||
}); | ||
it('does not change already padded value', function() { | ||
const padded = base64.padding('abc'); | ||
expect(padded).toBe('abc='); | ||
const again = base64.padding(padded); | ||
expect(again).toBe('abc='); | ||
}); | ||
}); | ||
|
||
describe('decoding to hex', function() { | ||
it('should convert base64 input into hex output', function() { | ||
expect(base64.decodeToHEX('AQAB')).toBe('010001'); | ||
expect(base64.decodeToHEX('uGbXWiK3dQTyCbX5')).toBe( | ||
'b866d75a22b77504f209b5f9', | ||
); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"keys": [ | ||
{ | ||
"use": "sig", | ||
"alg": "RS256", | ||
"kty": "RSA", | ||
"e": "AQAB", | ||
"kid": "1234", | ||
"n": "uGbXWiK3dQTyCbX5xdE4yCuYp0AF2d15Qq1JSXT_lx8CEcXb9RbDddl8jGDv-spi5qPa8qEHiK7FwV2KpRE983wGPnYsAm9BxLFb4YrLYcDFOIGULuk2FtrPS512Qea1bXASuvYXEpQNpGbnTGVsWXI9C-yjHztqyL2h8P6mlThPY9E9ue2fCqdgixfTFIF9Dm4SLHbphUS2iw7w1JgT69s7of9-I9l5lsJ9cozf1rxrXX4V1u_SotUuNB3Fp8oB4C1fLBEhSlMcUJirz1E8AziMCxS-VrRPDM-zfvpIJg3JljAh3PJHDiLu902v9w-Iplu1WyoB2aPfitxEhRN0Yw" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/** | ||
* Borrowed from IDToken-verifier package | ||
* https://github.com/auth0/idtoken-verifier/blob/master/src/helpers/base64.js | ||
*/ | ||
import base64 from 'base64-js'; | ||
|
||
export function padding(str) { | ||
const paddingLength = 4; | ||
const mod = str.length % paddingLength; | ||
const pad = paddingLength - mod; | ||
|
||
if (mod === 0) { | ||
return str; | ||
} | ||
|
||
return str + new Array(1 + pad).join('='); | ||
} | ||
|
||
function byteArrayToHex(raw) { | ||
let HEX = ''; | ||
|
||
for (let i = 0; i < raw.length; i++) { | ||
const _hex = raw[i].toString(16); | ||
HEX += _hex.length === 2 ? _hex : '0' + _hex; | ||
} | ||
|
||
return HEX; | ||
} | ||
|
||
export function decodeToHEX(str) { | ||
return byteArrayToHex(base64.toByteArray(padding(str))); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
Based on the work of Tom Wu | ||
http://www-cs-students.stanford.edu/~tjw/jsbn/ | ||
http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE | ||
*/ | ||
|
||
import {BigInteger} from 'jsbn'; | ||
import SHA256 from 'crypto-js/sha256'; | ||
|
||
const digestInfoHead = { | ||
sha256: '3031300d060960864801650304020105000420', | ||
}; | ||
|
||
const digestAlgs = { | ||
sha256: SHA256, | ||
}; | ||
|
||
function RSAVerifier(modulus, exp) { | ||
this.n = null; | ||
this.e = 0; | ||
|
||
if (modulus && modulus.length > 0 && exp && exp.length > 0) { | ||
this.n = new BigInteger(modulus, 16); | ||
this.e = parseInt(exp, 16); | ||
} else { | ||
throw new Error('Invalid key data'); | ||
} | ||
} | ||
|
||
function getAlgorithmFromDigest(hDigestInfo) { | ||
for (let algName in digestInfoHead) { | ||
const head = digestInfoHead[algName]; | ||
const len = head.length; | ||
|
||
if (hDigestInfo.substring(0, len) === head) { | ||
return { | ||
alg: algName, | ||
hash: hDigestInfo.substring(len), | ||
}; | ||
} | ||
} | ||
return []; | ||
} | ||
|
||
RSAVerifier.prototype.verify = function(msg, encodedSignature) { | ||
const decodedSignature = encodedSignature.replace(/[^0-9a-f]|[\s\n]]/gi, ''); | ||
|
||
const signature = new BigInteger(decodedSignature, 16); | ||
if (signature.bitLength() > this.n.bitLength()) { | ||
//Signature does not match with the key modulus. | ||
return false; | ||
} | ||
|
||
const decryptedSignature = signature.modPowInt(this.e, this.n); | ||
const digest = decryptedSignature.toString(16).replace(/^1f+00/, ''); | ||
|
||
const digestInfo = getAlgorithmFromDigest(digest); | ||
if (digestInfo.length === 0) { | ||
//Hashing algorithm is not found | ||
return false; | ||
} | ||
|
||
if (!digestAlgs.hasOwnProperty(digestInfo.alg)) { | ||
//Hashing algorithm is not supported | ||
return false; | ||
} | ||
|
||
const msgHash = digestAlgs[digestInfo.alg](msg).toString(); | ||
return digestInfo.hash === msgHash; | ||
}; | ||
|
||
export default RSAVerifier; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters