'use strict' const webcrypto = require('../webcrypto.js') const randomBytes = require('../random-bytes') exports.utils = require('./rsa-utils') exports.generateKey = async function (bits) { const pair = await webcrypto.subtle.generateKey( { name: 'RSASSA-PKCS1-v1_5', modulusLength: bits, publicExponent: new Uint8Array([0x01, 0x00, 0x01]), hash: { name: 'SHA-256' } }, true, ['sign', 'verify'] ) const keys = await exportKey(pair) return { privateKey: keys[0], publicKey: keys[1] } } // Takes a jwk key exports.unmarshalPrivateKey = async function (key) { const privateKey = await webcrypto.subtle.importKey( 'jwk', key, { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } }, true, ['sign'] ) const pair = [ privateKey, await derivePublicFromPrivate(key) ] const keys = await exportKey({ privateKey: pair[0], publicKey: pair[1] }) return { privateKey: keys[0], publicKey: keys[1] } } exports.getRandomValues = randomBytes exports.hashAndSign = async function (key, msg) { const privateKey = await webcrypto.subtle.importKey( 'jwk', key, { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } }, false, ['sign'] ) const sig = await webcrypto.subtle.sign( { name: 'RSASSA-PKCS1-v1_5' }, privateKey, Uint8Array.from(msg) ) return Buffer.from(sig) } exports.hashAndVerify = async function (key, sig, msg) { const publicKey = await webcrypto.subtle.importKey( 'jwk', key, { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } }, false, ['verify'] ) return webcrypto.subtle.verify( { name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg ) } function exportKey (pair) { return Promise.all([ webcrypto.subtle.exportKey('jwk', pair.privateKey), webcrypto.subtle.exportKey('jwk', pair.publicKey) ]) } function derivePublicFromPrivate (jwKey) { return webcrypto.subtle.importKey( 'jwk', { kty: jwKey.kty, n: jwKey.n, e: jwKey.e }, { name: 'RSASSA-PKCS1-v1_5', hash: { name: 'SHA-256' } }, true, ['verify'] ) }