-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Crypto: Implement generation of RSA keys
See #3.
- Loading branch information
Showing
7 changed files
with
169 additions
and
19 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,68 @@ | ||
import { generateRsaKeys } from './crypto'; | ||
|
||
describe('generateRsaKeys', () => { | ||
test('Keys should be RSA', async () => { | ||
const keyPair = await generateRsaKeys(); | ||
|
||
expect(keyPair.publicKey.algorithm.name).toMatch(/^RSA-/); | ||
expect(keyPair.privateKey.algorithm.name).toMatch(/^RSA-/); | ||
}); | ||
|
||
test('Keys should be extractable', async () => { | ||
const keyPair = await generateRsaKeys(); | ||
|
||
expect(keyPair.publicKey.extractable).toBe(true); | ||
expect(keyPair.privateKey.extractable).toBe(true); | ||
}); | ||
|
||
describe('Modulus', () => { | ||
test('Default modulus should be 2048', async () => { | ||
const keyPair = await generateRsaKeys(); | ||
// @ts-ignore | ||
expect(keyPair.publicKey.algorithm.modulusLength).toBe(2048); | ||
// @ts-ignore | ||
expect(keyPair.privateKey.algorithm.modulusLength).toBe(2048); | ||
}); | ||
|
||
test('Modulus > 2048 should be supported', async () => { | ||
const modulus = 3072; | ||
const keyPair = await generateRsaKeys({ modulus }); | ||
// @ts-ignore | ||
expect(keyPair.publicKey.algorithm.modulusLength).toBe(modulus); | ||
// @ts-ignore | ||
expect(keyPair.privateKey.algorithm.modulusLength).toBe(modulus); | ||
}); | ||
|
||
test('Modulus < 2048 should not supported', async () => { | ||
await expect(generateRsaKeys({ modulus: 1024 })).rejects.toThrow( | ||
'RSA modulus must be => 2048 per RS-018 (got 1024)' | ||
); | ||
}); | ||
}); | ||
|
||
describe('Hashing algorithm', () => { | ||
test('SHA-256 should be used by default', async () => { | ||
const keyPair = await generateRsaKeys(); | ||
// @ts-ignore | ||
expect(keyPair.publicKey.algorithm.hash.name).toBe('SHA-256'); | ||
// @ts-ignore | ||
expect(keyPair.privateKey.algorithm.hash.name).toBe('SHA-256'); | ||
}); | ||
|
||
['SHA-384', 'SHA-512'].forEach(hashingAlgorithm => { | ||
test(`${hashingAlgorithm} should be supported`, async () => { | ||
const keyPair = await generateRsaKeys({ hashingAlgorithm }); | ||
// @ts-ignore | ||
expect(keyPair.publicKey.algorithm.hash.name).toBe(hashingAlgorithm); | ||
// @ts-ignore | ||
expect(keyPair.privateKey.algorithm.hash.name).toBe(hashingAlgorithm); | ||
}); | ||
}); | ||
|
||
test('SHA-1 should not be supported', async () => { | ||
await expect( | ||
generateRsaKeys({ hashingAlgorithm: 'SHA-1' }) | ||
).rejects.toThrow('SHA-1 is disallowed by RS-018'); | ||
}); | ||
}); | ||
}); |
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,39 @@ | ||
import WebCrypto from 'node-webcrypto-ossl'; | ||
import { CryptoEngine, getAlgorithmParameters, setEngine } from 'pkijs'; | ||
|
||
const webcrypto = new WebCrypto(); | ||
const cryptoEngine = new CryptoEngine({ | ||
crypto: webcrypto, | ||
name: 'nodeEngine', | ||
subtle: webcrypto.subtle | ||
}); | ||
setEngine('nodeEngine', webcrypto, cryptoEngine); | ||
|
||
/** | ||
* Generate an RSA symmetric key | ||
* | ||
* @param modulus The RSA modulus for the keys (2048 or greater). | ||
* @param hashingAlgorithm The hashing algorithm (e.g., SHA-256, SHA-384, SHA-512). | ||
* @throws Error If the modulus or the hashing algorithm is disallowed by RS-018. | ||
*/ | ||
export async function generateRsaKeys({ | ||
modulus = 2048, | ||
hashingAlgorithm = 'SHA-256' | ||
} = {}): Promise<CryptoKeyPair> { | ||
if (modulus < 2048) { | ||
throw new Error(`RSA modulus must be => 2048 per RS-018 (got ${modulus})`); | ||
} | ||
|
||
// RS-018 disallows MD5 and SHA-1, but only SHA-1 is supported in WebCrypto | ||
if (hashingAlgorithm === 'SHA-1') { | ||
throw new Error('SHA-1 is disallowed by RS-018'); | ||
} | ||
|
||
const algorithm = getAlgorithmParameters('RSA-PSS', 'generatekey'); | ||
// tslint:disable-next-line:no-object-mutation | ||
algorithm.algorithm.hash.name = hashingAlgorithm; | ||
// tslint:disable-next-line:no-object-mutation | ||
algorithm.algorithm.modulusLength = modulus; | ||
|
||
return cryptoEngine.generateKey(algorithm.algorithm, true, algorithm.usages); | ||
} |
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,2 @@ | ||
// @types/pkijs didn't work becuase it didn't define the "pkijs" module. | ||
declare module 'pkijs'; |
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