mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-06-27 12:11:55 +00:00
inital commit
This commit is contained in:
13
src/crypto.proto
Normal file
13
src/crypto.proto
Normal file
@ -0,0 +1,13 @@
|
||||
enum KeyType {
|
||||
RSA = 0;
|
||||
}
|
||||
|
||||
message PublicKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
||||
|
||||
message PrivateKey {
|
||||
required KeyType Type = 1;
|
||||
required bytes Data = 2;
|
||||
}
|
29
src/index.js
Normal file
29
src/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
|
||||
const keyGenerators = require('./keys')
|
||||
|
||||
exports.utils = require('./utils')
|
||||
|
||||
// Generates a keypair of the given type and bitsize
|
||||
exports.generateKeyPair = (type, bits) => {
|
||||
let generator = keyGenerators[type.toLowerCase()]
|
||||
if (!generator) {
|
||||
throw new Error('invalid or unsupported key type')
|
||||
}
|
||||
|
||||
return generator(bits)
|
||||
}
|
||||
|
||||
// Generates an ephemeral public key and returns a function that will compute
|
||||
// the shared secret key.
|
||||
//
|
||||
// Focuses only on ECDH now, but can be made more general in the future.
|
||||
exports.generateEphemeralKeyPair = (curveName, cb) => {
|
||||
throw new Error('Not implemented')
|
||||
}
|
||||
|
||||
// Generates a set of keys for each party by stretching the shared key.
|
||||
// (myIV, theirIV, myCipherKey, theirCipherKey, myMACKey, theirMACKey)
|
||||
exports.keyStretcher = (cipherType, hashType, secret) => {
|
||||
throw new Error('Not implemented')
|
||||
}
|
5
src/keys/index.js
Normal file
5
src/keys/index.js
Normal file
@ -0,0 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
rsa: require('./rsa')
|
||||
}
|
114
src/keys/rsa.js
Normal file
114
src/keys/rsa.js
Normal file
@ -0,0 +1,114 @@
|
||||
'use strict'
|
||||
|
||||
const forge = require('node-forge')
|
||||
const protobuf = require('protocol-buffers')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const utils = require('../utils')
|
||||
|
||||
const pki = forge.pki
|
||||
const rsa = pki.rsa
|
||||
|
||||
const pbm = protobuf(fs.readFileSync(path.join(__dirname, '../crypto.proto')))
|
||||
|
||||
class RsaPublicKey {
|
||||
constructor (k) {
|
||||
this._key = k
|
||||
}
|
||||
|
||||
verify (data, sig) {
|
||||
const md = forge.md.sha256.create()
|
||||
md.update(data, 'utf8')
|
||||
|
||||
return this._key.verify(md.digest().bytes(), sig)
|
||||
}
|
||||
|
||||
marshal () {
|
||||
return forge.asn1.toDer(pki.privateKeyToAsn1(this._key)).bytes()
|
||||
}
|
||||
|
||||
get bytes () {
|
||||
return pbm.PublicKey.encode({
|
||||
Type: pbm.KeyType.RSA,
|
||||
Data: this.marhal()
|
||||
})
|
||||
}
|
||||
|
||||
encrypt (bytes) {
|
||||
return this._key.encrypt(bytes, 'RSAES-PKCS1-V1_5')
|
||||
}
|
||||
|
||||
equals (key) {
|
||||
return this.bytes === key.bytes
|
||||
}
|
||||
|
||||
hash () {
|
||||
return utils.keyHash(this.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
class RsaPrivateKey {
|
||||
constructor (privKey, pubKey) {
|
||||
this._privateKey = privKey
|
||||
this._publicKey = pubKey
|
||||
}
|
||||
|
||||
genSecret () {
|
||||
return forge.random.getBytesSync(16)
|
||||
}
|
||||
|
||||
sign (message) {
|
||||
const md = forge.md.sha256.create()
|
||||
md.update(message, 'utf8')
|
||||
|
||||
return this._privateKey.sign(md)
|
||||
}
|
||||
|
||||
get public () {
|
||||
return new RsaPublicKey(this._publicKey)
|
||||
}
|
||||
|
||||
decrypt (bytes) {
|
||||
return this._privateKey.decrypt(bytes, 'RSAES-PKCS1-V1_5')
|
||||
}
|
||||
|
||||
marshal () {
|
||||
return forge.asn1.toDer(pki.privateKeyToAsn1(this._privateKey)).bytes()
|
||||
}
|
||||
|
||||
get bytes () {
|
||||
return pbm.PrivateKey.encode({
|
||||
Type: pbm.KeyType.RSA,
|
||||
Data: this.marshal()
|
||||
})
|
||||
}
|
||||
|
||||
equals (key) {
|
||||
return this.bytes === key.bytes
|
||||
}
|
||||
|
||||
hash () {
|
||||
return utils.keyHash(this.bytes)
|
||||
}
|
||||
}
|
||||
|
||||
function unmarshalRsaPrivateKey (bytes) {
|
||||
const key = pki.privateKeyFromAsn1(forge.asn1.fromDer(bytes))
|
||||
|
||||
return new RsaPrivateKey(key)
|
||||
}
|
||||
|
||||
function unmarshalRsaPublicKey (bytes) {
|
||||
const key = pki.publicKeyFromAsn1(forge.asn1.fromDer(bytes))
|
||||
|
||||
return new RsaPublicKey(key)
|
||||
}
|
||||
|
||||
module.exports = function generateRSAKey (bits, cb) {
|
||||
rsa.generateKeyPair({bits}, (err, keypair) => {
|
||||
if (err) return cb(err)
|
||||
|
||||
cb(null, new RSAKey(keypair.publicKey, keypair.privateKey))
|
||||
})
|
||||
}
|
13
src/utils.js
Normal file
13
src/utils.js
Normal file
@ -0,0 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
const multihashing = require('multihashing')
|
||||
|
||||
// Check the equality of two keys
|
||||
exports.keyEqual = (k1, k2) => {
|
||||
return k1.buffer.equals(k2.buffer)
|
||||
}
|
||||
|
||||
// Hashes a key
|
||||
exports.keyHash = (key) => {
|
||||
return multihashing(key.buffer, 'sha2-256')
|
||||
}
|
Reference in New Issue
Block a user