crypto-forge.ts 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import bs58 from 'bs58';
  2. import { asn1, md, pki, util } from 'node-forge';
  3. import { ICrypto } from './crypto';
  4. import { IKeyPair } from './key-pair';
  5. export default class CryptoForge implements ICrypto {
  6. public generateRsaKeyPair(bits: number): Promise<IKeyPair> {
  7. return new Promise((resolve, reject) => {
  8. pki.rsa.generateKeyPair({bits, workers: 2}, (err, {privateKey, publicKey}) => {
  9. if (err) {
  10. reject(err);
  11. return;
  12. }
  13. resolve({
  14. export: () => this.export(privateKey, publicKey),
  15. getPublicHash: () => this.getPublicHash(publicKey),
  16. getPublicKey: () => this.getPublicKey(publicKey),
  17. sign: (data: Buffer) => this.sign(privateKey, data),
  18. });
  19. });
  20. });
  21. }
  22. public async sign(privateKeyObj: any, data: Buffer): Promise<string> {
  23. const sha256 = md.sha256.create();
  24. const buf = util.hexToBytes(data.toString('hex'));
  25. sha256.update(buf);
  26. const signature = privateKeyObj.sign(sha256);
  27. const hexed = util.bytesToHex(signature);
  28. return hexed;
  29. }
  30. public async importRsaKeyPair(serialized: any): Promise<IKeyPair> {
  31. const { privateKey, publicKey } = JSON.parse(bs58.decode(serialized).toString('utf-8'));
  32. const privateKeyObj = pki.privateKeyFromPem(privateKey);
  33. const publicKeyObj = pki.publicKeyFromPem(publicKey);
  34. return {
  35. export: () => this.export(privateKeyObj, publicKeyObj),
  36. getPublicHash: () => this.getPublicHash(publicKeyObj),
  37. getPublicKey: () => this.getPublicKey(publicKeyObj),
  38. sign: (data: Buffer) => this.sign(privateKeyObj, data),
  39. };
  40. }
  41. private getPublicHash(publicKeyObj: any): string {
  42. const publicKeyHexString = this.getPublicKey(publicKeyObj);
  43. const sha256 = md.sha256.create();
  44. const buf = util.hexToBytes(publicKeyHexString);
  45. sha256.update(buf);
  46. const digested = sha256.digest().bytes();
  47. const pubHash = bs58.encode(Buffer.from(digested, 'binary'));
  48. return pubHash;
  49. }
  50. private getPublicKey(publicKeyObj: any): string {
  51. const pk = asn1.toDer(pki.publicKeyToAsn1(publicKeyObj)).toHex();
  52. return pk;
  53. }
  54. private async export(privateKeyObj: any, publicKeyObj: any): Promise<string> {
  55. const privateKey = pki.privateKeyToPem(privateKeyObj);
  56. const publicKey = pki.publicKeyToPem(publicKeyObj);
  57. const jsonString = JSON.stringify({privateKey, publicKey});
  58. return bs58.encode(Buffer.from(jsonString, 'utf-8'));
  59. }
  60. }