UNPKG

rsa-key

Version:

Converts between RSA key formats, detecting input format (PEM, DER, PKCS1, PKCS8). No OpenSSL needed.

158 lines (129 loc) 6.27 kB
const { assert } = require('chai'); const { BASE64 } = require('../src/constants'); const NodeRSA = require('node-rsa'); const pkcs8 = require('../src/formats/pkcs8'); const RSAKeyError = require('../src/error'); const { get32IntFromBuffer } = require('../src/util'); describe('Format: PKCS8', function() { describe('decodePrivatePKCS8DER', function() { let testKey, testComponents; before(function() { testKey = new NodeRSA({ b: 256 }); testComponents = testKey.exportKey('components'); }); it('should decode private PKCS8 DER key', function() { const testEncoded = testKey.exportKey('pkcs8-private-der'); const decoded = pkcs8.decodePrivatePKCS8DER(testEncoded); assert.isObject(decoded, 'should return an object'); assert.equal(decoded.n, testComponents.n.toString(BASE64), 'decoded modulus should match original'); assert.equal(get32IntFromBuffer(Buffer.from(decoded.e, BASE64)), testComponents.e, 'decoded public exponent should match original'); assert.equal(decoded.d, testComponents.d.toString(BASE64), 'decoded private exponent should match'); assert.equal(decoded.p, testComponents.p.toString(BASE64), 'decoded prime1 should match'); assert.equal(decoded.q, testComponents.q.toString(BASE64), 'decoded prime2 should match'); assert.equal(decoded.dp, testComponents.dmp1.toString(BASE64), 'decoded exponent1 should match'); assert.equal(decoded.dq, testComponents.dmq1.toString(BASE64), 'decoded exponent2 should match'); assert.equal(decoded.qi, testComponents.coeff.toString(BASE64), 'decoded coefficient should match'); }); it('should fail with private PKCS1 DER key', function() { assert.throws(() => { pkcs8.decodePrivatePKCS8DER(testKey.exportKey('pkcs1-private-der')); }, RSAKeyError); }); it('should fail with public PKCS1 DER key', function() { assert.throws(() => { pkcs8.decodePrivatePKCS8DER(testKey.exportKey('pkcs1-public-der')); }, RSAKeyError); }); it('should fail with public PKCS8 DER key', function() { assert.throws(() => { pkcs8.decodePrivatePKCS8DER(testKey.exportKey('pkcs8-public-der')); }, RSAKeyError); }); it('should fail with non-DER key', function() { assert.throws(() => { pkcs8.decodePrivatePKCS8DER(testKey.exportKey('pkcs8-public-pem')); }, RSAKeyError); }); }); describe('decodePublicPKCS8DER', function() { let testKey, testComponents; before(function() { testKey = new NodeRSA({ b: 256 }); testComponents = testKey.exportKey('components'); }); it('should decode public PKCS8 DER key', function() { const testEncoded = testKey.exportKey('pkcs8-public-der'); const decoded = pkcs8.decodePublicPKCS8DER(testEncoded); assert.isObject(decoded, 'should return an object'); assert.equal(decoded.n, testComponents.n.toString(BASE64), 'decoded modulus should match original'); assert.equal(get32IntFromBuffer(Buffer.from(decoded.e, BASE64)), testComponents.e, 'decoded public exponent should match original'); }); it('should fail with private PKCS8 DER key', function() { assert.throws(() => { pkcs8.decodePublicPKCS8DER(testKey.exportKey('pkcs8-private-der')); }, RSAKeyError); }); it('should fail with private PKCS1 DER key', function() { assert.throws(() => { pkcs8.decodePublicPKCS8DER(testKey.exportKey('pkcs1-private-der')); }, RSAKeyError); }); it('should fail with public PKCS1 DER key', function() { assert.throws(() => { pkcs8.decodePublicPKCS8DER(testKey.exportKey('pkcs1-public-der')); }, RSAKeyError); }); it('should fail with non-DER key', function() { assert.throws(() => { pkcs8.decodePublicPKCS8DER(testKey.exportKey('pkcs8-public-pem')); }, RSAKeyError); }); }); describe('encodePrivatePKCS8DER', function() { it('should encode private PKCS8 DER key', function() { const testEncoded = new NodeRSA({ b: 256 }).exportKey('pkcs8-private-der'); const decoded = pkcs8.decodePrivatePKCS8DER(testEncoded); const encoded = pkcs8.encodePrivatePKCS8DER(decoded); assert.instanceOf(encoded, Buffer, 'result should be a buffer'); assert.equal(encoded.toString(BASE64), testEncoded.toString(BASE64), 'encoded key should match original'); }); it('should fail if private components are missing', function() { const testEncoded = new NodeRSA({ b: 256 }).exportKey('pkcs8-public-der'); const decoded = pkcs8.decodePublicPKCS8DER(testEncoded); assert.throws(() => { pkcs8.encodePrivatePKCS8DER(decoded); }, RSAKeyError); }); it('should fail if components are invalid', function() { const testEncoded = new NodeRSA({ b: 256 }).exportKey('pkcs8-private-der'); const decoded = pkcs8.decodePrivatePKCS8DER(testEncoded); assert.throws(() => { pkcs8.encodePrivatePKCS8DER({ ...decoded, n: null}); }, RSAKeyError); }); }); describe('encodePublicPKCS8DER', function() { it('should encode public PKCS8 DER key', function() { const testEncoded = new NodeRSA({ b: 256 }).exportKey('pkcs8-public-der'); const decoded = pkcs8.decodePublicPKCS8DER(testEncoded); const encoded = pkcs8.encodePublicPKCS8DER(decoded); assert.instanceOf(encoded, Buffer, 'result should be a buffer'); assert.equal(encoded.toString(BASE64), testEncoded.toString(BASE64), 'encoded key should match original'); }); it('should fail if components are missing', function() { const testEncoded = new NodeRSA({ b: 256 }).exportKey('pkcs8-public-der'); const decoded = pkcs8.decodePublicPKCS8DER(testEncoded); assert.throws(() => { pkcs8.encodePublicPKCS8DER({ ...decoded, e: undefined }); }, RSAKeyError); }); it('should fail if components are invalid', function() { const testEncoded = new NodeRSA({ b: 256 }).exportKey('pkcs8-private-der'); const decoded = pkcs8.decodePrivatePKCS8DER(testEncoded); assert.throws(() => { pkcs8.encodePublicPKCS8DER({ ...decoded, n: null}); }, RSAKeyError); }); }); });