README
xdv-tools
XDV Platform tools
npm i xdvplatform-tools
Features
crypto
- Supports for JWT, DID, JWE, XmlDsig, CMS (X509)
- Algorithms included:
secp256k1
,secp256r1
,ed25519
,rsa
and upcomingbls
Keystore
,HD Key
,DER
,JWK
andPEM
support out of the box- Support for output to
LD Crypto Suite
key pairs forecdsa
anded25519
- More features planned like
bls
andschnorr
for multi sig scenarios
API
Wallet
Wallet.createHDWallet
Creates a new random HD Wallet
const keystore = await Wallet.createHDWallet({ password: 'password123' });
Wallet.generateMnemonic
Creates a new mnemonic
const mnemonic = Wallet.generateMnemonic();
const selectedWallet = await Wallet.createHDWallet({ mnemonic, password: '123password' });
Wallet.unlock
Unlocks an existing wallet
const wallet = await Wallet.unlock(selectedWallet, '123password');
deriveChild
Creates a new child HD Wallet
const child1 = wallet.deriveChild(1, `m/44'/60'/0'/0`);
const child2 = wallet.deriveChild(2, `m/44'/60'/0'/0`);
const child3 = wallet.deriveChild(3, `m/44'/60'/0'/0`);
deriveFromPath
Creates a new child HD Wallet
const child1 = wallet.deriveFromPath(`m/44'/60'/0'/0/1`);
const child2 = wallet.deriveFromPath(`m/44'/60'/0'/0/2`);
const child3 = wallet.deriveFromPath(`m/44'/60'/0'/0/3`);
getEd25519
Creates a new Ed25519 curve
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const kp = await wallet.getEd25519();
getP256
Creates a new P256/secp256r1 curve
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const kp = await wallet.getP256();
getES256k
Creates a new secp256k1 curve
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const kp = await wallet.getES256k();
getRSA256Standalone
Creates a new RSA key pair. This key pair is not generated from HD Wallet seed.
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const kp = await wallet.getRSA256Standalone();
getBlsMasterKey
Creates a new BLS key pair. Returns an object.
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const kp = wallet.getBlsMasterKey();
const deriveValidatorKey1 = await kp.deriveValidatorKeys(1);
KeyConvert
Handles key pair convertion from / to PEM
, DER
or JWK
. Some algorithm also returns JSON-LD
compatible exports.
KeyConvert.getX509RSA
Converts a RSA key pair. Available exports: JWK, PEM and LD.
const key = await Wallet.getRSA256Standalone();
const issuer: X509Info = {
stateOrProvinceName: 'PA',
organizationName: 'RM',
organizationalUnitName: 'Engineering',
commonName: 'Rogelio Morrell',
countryName: 'Panama',
localityName: 'Panama'
};
const { jwk, pem } = await KeyConvert.getX509RSA(key);
const jwt = await JWTService.sign(pem, {
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
KeyConvert.getP256
Converts a P256 key pair. Available exports: JWK, DER, PEM and LD.
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
expect(JSON.parse(keystore).version).equal(3);
const wallet = await Wallet.unlock(keystore, opts.password);
const key = wallet.getP256();
const pem = (await KeyConvert.getP256(key)).pem;
const jwt = await JWTService.sign(pem, {
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
KeyConvert.getES256K
Converts a ES256K key pair. Available exports: JWK, DER, PEM and LD.
const wallet = await Wallet.unlock(keystore, opts.password);
const pem = (await KeyConvert.getES256K(wallet.getES256K())).pem;
KeyConvert.getRSA
Converts a RSA key pair. Available exports: JWK and PEM as pemAsPrivate and pemAsPublic.
const key = await Wallet.getRSA256Standalone();
const pem = (await KeyConvert.getRSA(key)).pemAsPrivate;
KeyConvert.getEd25519
Converts a Ed25519 key pair. Available exports: DER and PEM.
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const key = wallet.getEd25519();
const pem = (await KeyConvert.getEd25519(key)).pem;
const jwt = await JWTService.sign(pem, {
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
KeyConvert.createLinkedDataJsonFormat
Creates a Linked Data suite json format from a LD Suite export.
const mnemonic = Wallet.generateMnemonic();
const opts = { mnemonic, password: '123password' };
const keystore = await Wallet.createHDWallet(opts);
const wallet = await Wallet.unlock(keystore, opts.password);
const kp = wallet.getP256();
const kpJwk = await KeyConvert.getP256(kp);
// Create LD Crypto Suite - p256 / Sepc256r1
const ldCrypto = await KeyConvert
.createLinkedDataJsonFormat(LDCryptoTypes.Sepc256r1, kpJwk.ldSuite);
// Create IPFS key storage lock
const session = await xdvMethod.createIpldSession(kpJwk.pem);
// Create DID document with an did-ipid based issuer
const did = await DIDDocumentBuilder
.createDID({
issuer: session.key,
verificationKeys: [ldCrypto.toPublicKey()],
authenticationKeys: [ldCrypto.toAuthorizationKey()]
});
// Signing
const signed = await JWTService.sign(kpJwk.pem, {
...did,
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
JWTService
Signs and verifies JWT.
JWTService.decodeWithSignature
Decodes a JWT
// Sign as JWT
let signed = await JWTService.sign(kpJwk.pem, {
...did,
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
// Decoded
const decoded = await JWTService.decodeWithSignature(signed);
expect(!!decoded.signature).equal(true)
expect(!!decoded.data).equal(true)
expect(!!decoded.header).equal(true)
expect(!!decoded.payload).equal(true)
JWTService.sign
Signs a JWT
// Unlock wallet
const wallet = await Wallet.unlock(keystore, opts.password);
// Create key
const kp = wallet.getP256();
const kpJwk = await KeyConvert.getP256(kp);
// Create LD Crypto Suite - p256 / Sepc256r1
const ldCrypto = await KeyConvert
.createLinkedDataJsonFormat(LDCryptoTypes.Sepc256r1, kpJwk.ldSuite);
// Create DID id from PEM keypair and store it variable
const session = await xdvMethod.createIpldSession(kpJwk.pem);
// Set DID
localStorage['recentlyStoreDID'] = session.key;
// Create DID document with an did-ipid based issuer
let did = await DIDDocumentBuilder
.createDID({
issuer: session.key,
verificationKeys: [ldCrypto.toPublicKey()],
authenticationKeys: [ldCrypto.toAuthorizationKey()]
});
// Sign as JWT
let signed = await JWTService.sign(kpJwk.pem, {
...did,
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
JWTService.verify
Verifies a JWT
// get document with a CID and DID
const resolver = await xdvMethod.getResolver(localStorage['recentlyStoreCID']);
const doc = await resolver.xdv(localStorage['recentlyStoreDID']);
// unlock wallet
let wallet = await Wallet.unlock(localStorage['ks'], localStorage['ps']);
// create new key pairs
const kp = wallet.getP256();
const kpJwk = await KeyConvert.getP256(kp);
// decrypt
const obj = await JOSEService.decrypt(kpJwk.jwk, doc.encrypted);
const verified = await JWTService.verify(kpJwk.pem,(<Buffer> obj.plaintext).toString('utf8'), 'receptor');
JOSEService
Encrypts and decrypts JWT.
JOSEService.encrypt
Encrypts a string or buffer payload
// Unlock wallet
const wallet = await Wallet.unlock(keystore, opts.password);
// Create key
const kp = wallet.getP256();
const kpJwk = await KeyConvert.getP256(kp);
// Create LD Crypto Suite - p256 / Sepc256r1
const ldCrypto = await KeyConvert
.createLinkedDataJsonFormat(LDCryptoTypes.Sepc256r1, kpJwk.ldSuite);
// Create DID id from PEM keypair and store it variable
const session = await xdvMethod.createIpldSession(kpJwk.pem);
// Set DID
localStorage['recentlyStoreDID'] = session.key;
// Create DID document with an did-ipid based issuer
let did = await DIDDocumentBuilder
.createDID({
issuer: session.key,
verificationKeys: [ldCrypto.toPublicKey()],
authenticationKeys: [ldCrypto.toAuthorizationKey()]
});
// Sign as JWT
let signed = await JWTService.sign(kpJwk.pem, {
...did,
testing: 'testing'
}, {
iat: (new Date(2020, 10, 10)).getTime(),
iss: '0x4198258023eD0D6fae5DBCF3Af2aeDaaA363571F',
sub: 'document',
aud: 'receptor',
nbf: (new Date(2020, 10, 10)).getTime(),
});
// Encrypt JWT
const encrypted = await JOSEService.encrypt(kpJwk.jwk, signed);
JOSEService.decrypt
Decrypts a cipher
// get document with a CID and DID
const resolver = await xdvMethod.getResolver(localStorage['recentlyStoreCID']);
const doc = await resolver.xdv(localStorage['recentlyStoreDID']);
// unlock wallet
let wallet = await Wallet.unlock(localStorage['ks'], localStorage['ps']);
// create new key pairs
const kp = wallet.getP256();
const kpJwk = await KeyConvert.getP256(kp);
// decrypt
const obj = await JOSEService.decrypt(kpJwk.jwk, doc.encrypted);
const verified = await JWTService.verify(kpJwk.pem,(<Buffer> obj.plaintext).toString('utf8'), 'receptor');
X509
X509.createSelfSignedCertificateFromRSA
Creates a self sign certificate from a RSA key pair
const issuer: X509Info = {
stateOrProvinceName: 'PA',
organizationName: 'RM',
organizationalUnitName: 'Engineering',
commonName: 'Rogelio Morrell',
countryName: 'Panama',
localityName: 'Panama'
};
const rsaKey = await Wallet.getRSA256Standalone();
const rsaKeyExports = await KeyConvert.getX509RSA(rsaKey);
const selfSignedCert = X509.createSelfSignedCertificateFromRSA(
rsaKeyExports.pemAsPrivate, rsaKeyExports.pemAsPublic, issuer);
const signedDocuments = await XmlDsig.signFEDocument(rsaKeyExports.pem, selfSignedCert, latestFEDocument);
XmlDsig (FE specific)
Signs FE XML Documents
XmlDsig.signFEDocument
Signs a Factura Electronica de Panama document
const issuer: X509Info = {
stateOrProvinceName: 'PA',
organizationName: 'RM',
organizationalUnitName: 'Engineering',
commonName: 'Rogelio Morrell',
countryName: 'Panama',
localityName: 'Panama'
};
const rsaKey = await Wallet.getRSA256Standalone();
const rsaKeyExports = await KeyConvert.getX509RSA(rsaKey);
const selfSignedCert = X509.createSelfSignedCertificateFromRSA(
rsaKeyExports.pemAsPrivate, rsaKeyExports.pemAsPublic, issuer);
const signedDocuments = await XmlDsig.signFEDocument(rsaKeyExports.pemAsPrivate, selfSignedCert, latestFEDocument);
CMSSigner
Signs CMS Documents
CMSSigner.sign
Signs a CMS document
const issuer: X509Info = {
stateOrProvinceName: 'PA',
organizationName: 'RM',
organizationalUnitName: 'Engineering',
commonName: 'Rogelio Morrell',
countryName: 'Panama',
localityName: 'Panama'
};
const rsaKey = await Wallet.getRSA256Standalone();
const rsaKeyExports = await KeyConvert.getX509RSA(rsaKey);
const selfSignedCert = X509.createSelfSignedCertificateFromRSA(
rsaKeyExports.pemAsPrivate, rsaKeyExports.pemAsPublic, issuer);
const res = CMSSigner.sign(selfSignedCert,
rsaKeyExports.pemAsPrivate,
fs.readFileSync(__dirname + '/fixtures/cms.pdf'));
did
- Supports for basic DID JSON schemas
DID JWT
signing and validation usingxdvplatform-tools/crypto
API- Includes
did-method-xdv
with resolver
API
DIDMethodXDV - XDV DID Method
XDV DID method is based on IPLD. Before using it, it needs to be initialize. After initializing, generate
a new session key (the DID key) and then use DIDDocumentBuilder
to create a DID document.
Usage
const ipld = new IpldClient();
const xdvMethod = new DIDMethodXDV(ipld);
// create ipld instance
await ipld.initialize();
// ....
const kp = wallet.getP256();
const kpJwk = await KeyConvert.getP256(kp);
// Create LD Crypto Suite - p256 / Sepc256r1
const ldCrypto = await KeyConvert
.createLinkedDataJsonFormat(LDCryptoTypes.Sepc256r1, kpJwk.ldSuite);
// Create IPFS key storage lock
const session = await xdvMethod.createIpldSession(kpJwk.pem);
// Create DID document with an did-ipid based issuer
const did = await DIDDocumentBuilder
.createDID({
issuer: session.key,
verificationKeys: [ldCrypto.toPublicKey()],
authenticationKeys: [ldCrypto.toAuthorizationKey()]
});
// Always store DID in IPLD
cid = await ipld.createNode({
...did,
});
Resolving is a different, you'll ned both CID and DID.
// get document with a CID and DID
const resolver = await xdvMethod.getResolver(cid);
const doc = await resolver.xdv(did);
Wallet.createHDWallet
Creates a new random HD Wallet
const keystore = await Wallet.createHDWallet({ password: 'password123' });
fe
- Includes most of the API specifications for
Factura Electronica DGI Panama
up to September 2018 specification - Planned features:
CUFE
generation andQR
generation
ipld
- IPLD client
storage
- XDV storage schemas for IPLD
comm
- IPNS PubSub
dv
- Digito Verificador for RUC Natural Person based on algorithm from Registro Publico de Panama.
- Client that calls a read only function in a Solidity smart contract
Usage
const nodeUrl = '...node url';
const isMainnet = true;
const account = '...your ethereum accpunt';
const dv = new DV(account, nodeUrl, isMainnet);
// initialize contracts
await dv.initialize();
// call calculate
// input is
// { type, segments 1 to 4}
// For more information, visit https://dv.auth2factor.com
const resp = await dv.calculate(CedulaInputTypes.N,
[0, 8],
[0, 0],
[7, 1, 3],
[2, 2, 3]);
expect(resp).equals('11');
@molekilla, Rogelio Morrell C. Copyright 2020