mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-03-15 08:41:05 +00:00
feat: add marshal and unmarshl methods
This commit is contained in:
parent
f3a22ea5ff
commit
ca0b5305a2
28
README.md
28
README.md
@ -24,3 +24,31 @@ needed for libp2p. This is based on this [go implementation](https://github.com/
|
||||
- `type: String`, only `'RSA'` is currently supported
|
||||
- `bits: Number`
|
||||
- `cb: Function`, with the signature `function (err, privateKey)`
|
||||
|
||||
Generates a keypair of the given type and bitsize.
|
||||
|
||||
### `marshalPublicKey(key[, type])`
|
||||
|
||||
- `key: crypto.rsa.RsaPublicKey`
|
||||
- `type: String`, only `'RSA'` is currently supported
|
||||
|
||||
Converts a public key object into a protobuf serialized public key.
|
||||
|
||||
### `unmarshalPublicKey(buf)`
|
||||
|
||||
- `buf: Buffer`
|
||||
|
||||
Converts a protobuf serialized public key into its representative object.
|
||||
|
||||
### `marshalPrivateKey(key[, type])`
|
||||
|
||||
- `key: crypto.rsa.RsaPrivateKey`
|
||||
- `type: String`, only `'RSA'` is currently supported
|
||||
|
||||
Converts a private key object into a protobuf serialized private key.
|
||||
|
||||
### `unmarshalPrivateKey(buf)`
|
||||
|
||||
- `buf: Buffer`
|
||||
|
||||
Converts a protobuf serialized private key into its representative object.
|
||||
|
61
src/index.js
61
src/index.js
@ -1,5 +1,10 @@
|
||||
'use strict'
|
||||
|
||||
const protobuf = require('protocol-buffers')
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const pbm = protobuf(fs.readFileSync(path.join(__dirname, './crypto.proto')))
|
||||
|
||||
exports.utils = require('./utils')
|
||||
const keys = exports.keys = require('./keys')
|
||||
|
||||
@ -26,3 +31,59 @@ exports.generateEphemeralKeyPair = (curveName, cb) => {
|
||||
exports.keyStretcher = (cipherType, hashType, secret) => {
|
||||
throw new Error('Not implemented')
|
||||
}
|
||||
|
||||
// Converts a protobuf serialized public key into its
|
||||
// representative object
|
||||
exports.unmarshalPublicKey = (buf) => {
|
||||
const decoded = pbm.PublicKey.decode(buf)
|
||||
|
||||
switch (decoded.Type) {
|
||||
case pbm.KeyType.RSA:
|
||||
return keys.rsa.unmarshalRsaPublicKey(decoded.Data)
|
||||
default:
|
||||
throw new Error('invalid or unsupported key type')
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a public key object into a protobuf serialized public key
|
||||
exports.marshalPublicKey = (key, type) => {
|
||||
type = (type || 'rsa').toLowerCase()
|
||||
|
||||
// for now only rsa is supported
|
||||
if (type !== 'rsa') {
|
||||
throw new Error('invalid or unsupported key type')
|
||||
}
|
||||
|
||||
return pbm.PublicKey.encode({
|
||||
Type: pbm.KeyType.RSA,
|
||||
Data: key.marshal()
|
||||
})
|
||||
}
|
||||
|
||||
// Converts a protobuf serialized private key into its
|
||||
// representative object
|
||||
exports.unmarshalPrivateKey = (buf) => {
|
||||
const decoded = pbm.PrivateKey.decode(buf)
|
||||
|
||||
switch (decoded.Type) {
|
||||
case pbm.KeyType.RSA:
|
||||
return keys.rsa.unmarshalRsaPrivateKey(decoded.Data)
|
||||
default:
|
||||
throw new Error('invalid or unsupported key type')
|
||||
}
|
||||
}
|
||||
|
||||
// Converts a private key object into a protobuf serialized private key
|
||||
exports.marshalPrivateKey = (key, type) => {
|
||||
type = (type || 'rsa').toLowerCase()
|
||||
|
||||
// for now only rsa is supported
|
||||
if (type !== 'rsa') {
|
||||
throw new Error('invalid or unsupported key type')
|
||||
}
|
||||
|
||||
return pbm.PrivateKey.encode({
|
||||
Type: pbm.KeyType.RSA,
|
||||
Data: key.marshal()
|
||||
})
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class RsaPublicKey {
|
||||
}
|
||||
|
||||
marshal () {
|
||||
return forge.asn1.toDer(pki.publicKeyToAsn1(this._key)).bytes()
|
||||
return new Buffer(forge.asn1.toDer(pki.publicKeyToAsn1(this._key)).bytes(), 'binary')
|
||||
}
|
||||
|
||||
get bytes () {
|
||||
@ -74,7 +74,7 @@ class RsaPrivateKey {
|
||||
}
|
||||
|
||||
marshal () {
|
||||
return forge.asn1.toDer(pki.privateKeyToAsn1(this._privateKey)).bytes()
|
||||
return new Buffer(forge.asn1.toDer(pki.privateKeyToAsn1(this._privateKey)).bytes(), 'binary')
|
||||
}
|
||||
|
||||
get bytes () {
|
||||
@ -94,12 +94,18 @@ class RsaPrivateKey {
|
||||
}
|
||||
|
||||
function unmarshalRsaPrivateKey (bytes) {
|
||||
if (Buffer.isBuffer(bytes)) {
|
||||
bytes = forge.util.createBuffer(bytes.toString('binary'))
|
||||
}
|
||||
const key = pki.privateKeyFromAsn1(forge.asn1.fromDer(bytes))
|
||||
|
||||
return new RsaPrivateKey(key)
|
||||
}
|
||||
|
||||
function unmarshalRsaPublicKey (bytes) {
|
||||
if (Buffer.isBuffer(bytes)) {
|
||||
bytes = forge.util.createBuffer(bytes.toString('binary'))
|
||||
}
|
||||
const key = pki.publicKeyFromAsn1(forge.asn1.fromDer(bytes))
|
||||
|
||||
return new RsaPublicKey(key)
|
||||
|
@ -4,116 +4,26 @@
|
||||
const expect = require('chai').expect
|
||||
|
||||
const crypto = require('../src')
|
||||
const rsa = crypto.keys.rsa
|
||||
|
||||
describe('libp2p-crypto', () => {
|
||||
describe('generateKeyPair', () => {
|
||||
describe('RSA', () => {
|
||||
let key
|
||||
before((done) => {
|
||||
crypto.generateKeyPair('RSA', 2048, (err, _key) => {
|
||||
if (err) return done(err)
|
||||
key = _key
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('generates a valid key', () => {
|
||||
expect(
|
||||
key
|
||||
).to.be.an.instanceof(
|
||||
rsa.RsaPrivateKey
|
||||
)
|
||||
|
||||
expect(
|
||||
key.hash()
|
||||
).to.have.length(
|
||||
34
|
||||
)
|
||||
})
|
||||
|
||||
it('signs', () => {
|
||||
const pk = key.public
|
||||
const text = key.genSecret()
|
||||
const sig = key.sign(text)
|
||||
|
||||
expect(
|
||||
pk.verify(text, sig)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('encoding', () => {
|
||||
const keyMarshal = key.marshal()
|
||||
const key2 = rsa.unmarshalRsaPrivateKey(keyMarshal)
|
||||
const keyMarshal2 = key2.marshal()
|
||||
|
||||
expect(
|
||||
keyMarshal
|
||||
).to.be.eql(
|
||||
keyMarshal2
|
||||
)
|
||||
|
||||
const pk = key.public
|
||||
const pkMarshal = pk.marshal()
|
||||
const pk2 = rsa.unmarshalRsaPublicKey(pkMarshal)
|
||||
const pkMarshal2 = pk2.marshal()
|
||||
|
||||
expect(
|
||||
pkMarshal
|
||||
).to.be.eql(
|
||||
pkMarshal2
|
||||
)
|
||||
})
|
||||
|
||||
describe('key equals', () => {
|
||||
it('equals itself', () => {
|
||||
expect(
|
||||
key.equals(key)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
|
||||
expect(
|
||||
key.public.equals(key.public)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('not equals other key', (done) => {
|
||||
crypto.generateKeyPair('RSA', 2048, (err, key2) => {
|
||||
if (err) return done(err)
|
||||
|
||||
expect(
|
||||
key.equals(key2)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
expect(
|
||||
key2.equals(key)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
expect(
|
||||
key.public.equals(key2.public)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
expect(
|
||||
key2.public.equals(key.public)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
let key
|
||||
before((done) => {
|
||||
crypto.generateKeyPair('RSA', 2048, (err, _key) => {
|
||||
if (err) return done(err)
|
||||
key = _key
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('marshalPublicKey and unmarshalPublicKey', () => {
|
||||
const key2 = crypto.unmarshalPublicKey(crypto.marshalPublicKey(key.public))
|
||||
|
||||
expect(key2.equals(key.public)).to.be.eql(true)
|
||||
})
|
||||
|
||||
it('marshalPrivateKey and unmarshalPrivateKey', () => {
|
||||
const key2 = crypto.unmarshalPrivateKey(crypto.marshalPrivateKey(key))
|
||||
|
||||
expect(key2.equals(key)).to.be.eql(true)
|
||||
})
|
||||
})
|
||||
|
115
test/rsa.spec.js
Normal file
115
test/rsa.spec.js
Normal file
@ -0,0 +1,115 @@
|
||||
/* eslint-env mocha */
|
||||
'use strict'
|
||||
|
||||
const expect = require('chai').expect
|
||||
|
||||
const crypto = require('../src')
|
||||
const rsa = crypto.keys.rsa
|
||||
|
||||
describe('RSA', () => {
|
||||
let key
|
||||
before((done) => {
|
||||
crypto.generateKeyPair('RSA', 2048, (err, _key) => {
|
||||
if (err) return done(err)
|
||||
key = _key
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
it('generates a valid key', () => {
|
||||
expect(
|
||||
key
|
||||
).to.be.an.instanceof(
|
||||
rsa.RsaPrivateKey
|
||||
)
|
||||
|
||||
expect(
|
||||
key.hash()
|
||||
).to.have.length(
|
||||
34
|
||||
)
|
||||
})
|
||||
|
||||
it('signs', () => {
|
||||
const pk = key.public
|
||||
const text = key.genSecret()
|
||||
const sig = key.sign(text)
|
||||
|
||||
expect(
|
||||
pk.verify(text, sig)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('encoding', () => {
|
||||
const keyMarshal = key.marshal()
|
||||
const key2 = rsa.unmarshalRsaPrivateKey(keyMarshal)
|
||||
const keyMarshal2 = key2.marshal()
|
||||
|
||||
expect(
|
||||
keyMarshal
|
||||
).to.be.eql(
|
||||
keyMarshal2
|
||||
)
|
||||
|
||||
const pk = key.public
|
||||
const pkMarshal = pk.marshal()
|
||||
const pk2 = rsa.unmarshalRsaPublicKey(pkMarshal)
|
||||
const pkMarshal2 = pk2.marshal()
|
||||
|
||||
expect(
|
||||
pkMarshal
|
||||
).to.be.eql(
|
||||
pkMarshal2
|
||||
)
|
||||
})
|
||||
|
||||
describe('key equals', () => {
|
||||
it('equals itself', () => {
|
||||
expect(
|
||||
key.equals(key)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
|
||||
expect(
|
||||
key.public.equals(key.public)
|
||||
).to.be.eql(
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it('not equals other key', (done) => {
|
||||
crypto.generateKeyPair('RSA', 2048, (err, key2) => {
|
||||
if (err) return done(err)
|
||||
|
||||
expect(
|
||||
key.equals(key2)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
expect(
|
||||
key2.equals(key)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
expect(
|
||||
key.public.equals(key2.public)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
expect(
|
||||
key2.public.equals(key.public)
|
||||
).to.be.eql(
|
||||
false
|
||||
)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user