mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-04-22 19:42:31 +00:00
* feat: add (rsa)pubKey.encrypt and (rsa)privKey.decrypt nodeJS only for now * feat: browser enc/dec * fix: browser rsa enc/dec * refactor: cleanup * fix: lint * fix: use direct buffers instead of converting to hex * fix: padding error * test: add interop test * feat: use forge to convert jwk2forge * fix: jwk var naming * fix: missing cbwrap
110 lines
2.4 KiB
JavaScript
110 lines
2.4 KiB
JavaScript
'use strict'
|
|
|
|
const crypto = require('crypto')
|
|
const randomBytes = require('../random-bytes')
|
|
const nextTick = require('async/nextTick')
|
|
|
|
let keypair
|
|
try {
|
|
if (process.env.LP2P_FORCE_CRYPTO_LIB === 'keypair') {
|
|
throw new Error('Force keypair usage')
|
|
}
|
|
|
|
const ursa = require('ursa-optional') // throws if not compiled
|
|
keypair = ({ bits }) => {
|
|
const key = ursa.generatePrivateKey(bits)
|
|
return {
|
|
private: key.toPrivatePem(),
|
|
public: key.toPublicPem()
|
|
}
|
|
}
|
|
} catch (e) {
|
|
if (process.env.LP2P_FORCE_CRYPTO_LIB === 'ursa') {
|
|
throw e
|
|
}
|
|
|
|
keypair = require('keypair')
|
|
}
|
|
const pemToJwk = require('pem-jwk').pem2jwk
|
|
const jwkToPem = require('pem-jwk').jwk2pem
|
|
|
|
exports.utils = require('./rsa-utils')
|
|
|
|
exports.generateKey = function (bits, callback) {
|
|
nextTick(() => {
|
|
let result
|
|
try {
|
|
const key = keypair({ bits: bits })
|
|
result = {
|
|
privateKey: pemToJwk(key.private),
|
|
publicKey: pemToJwk(key.public)
|
|
}
|
|
} catch (err) {
|
|
return callback(err)
|
|
}
|
|
|
|
callback(null, result)
|
|
})
|
|
}
|
|
|
|
// Takes a jwk key
|
|
exports.unmarshalPrivateKey = function (key, callback) {
|
|
nextTick(() => {
|
|
if (!key) {
|
|
return callback(new Error('Key is invalid'))
|
|
}
|
|
callback(null, {
|
|
privateKey: key,
|
|
publicKey: {
|
|
kty: key.kty,
|
|
n: key.n,
|
|
e: key.e
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
exports.getRandomValues = randomBytes
|
|
|
|
exports.hashAndSign = function (key, msg, callback) {
|
|
nextTick(() => {
|
|
let result
|
|
try {
|
|
const sign = crypto.createSign('RSA-SHA256')
|
|
sign.update(msg)
|
|
const pem = jwkToPem(key)
|
|
result = sign.sign(pem)
|
|
} catch (err) {
|
|
return callback(new Error('Key or message is invalid!: ' + err.message))
|
|
}
|
|
|
|
callback(null, result)
|
|
})
|
|
}
|
|
|
|
exports.hashAndVerify = function (key, sig, msg, callback) {
|
|
nextTick(() => {
|
|
let result
|
|
try {
|
|
const verify = crypto.createVerify('RSA-SHA256')
|
|
verify.update(msg)
|
|
const pem = jwkToPem(key)
|
|
result = verify.verify(pem, sig)
|
|
} catch (err) {
|
|
return callback(new Error('Key or message is invalid!:' + err.message))
|
|
}
|
|
|
|
callback(null, result)
|
|
})
|
|
}
|
|
|
|
const padding = crypto.constants.RSA_PKCS1_PADDING
|
|
|
|
exports.encrypt = function (key, bytes) {
|
|
return crypto.publicEncrypt({ key: jwkToPem(key), padding }, bytes)
|
|
}
|
|
|
|
exports.decrypt = function (key, bytes) {
|
|
return crypto.privateDecrypt({ key: jwkToPem(key), padding }, bytes)
|
|
}
|