Generate Key for signing within nodejs

帅比萌擦擦* 提交于 2019-12-11 17:23:44

问题


I have what seems to be a rather simple problem, but I never had to deal with cryptography in nodejs before.
I want to implement a system which generates a new keypair about every 4 months, which are used for signing and verifying a generated result.
This is my current code:

'use strict';
const fs = require('fs');
const crypto = require('crypto');
const algorithm = 'RSA-SHA512';
const sign = crypto.createSign(algorithm);
const verify = crypto.createVerify(algorithm);
const base64 = 'base64';
const keyDir = './keys/';

const validator = {};

validator.check = function(dataArray, signature, date){
  verify.update(Buffer.from(dataArray));
  return verify.verify(getPublicKey(date), signature);
};

validator.sign = function(dice){
  sign.update(Buffer.from(dice));
  return sign.sign(getPrivateKey(), base64);//Error happens here
};

validator.getPublicKey = function(date){
  date = toDateObject(date);
  for(current of getFilesDescending()){
    if(fileNameToDate(current).getMilliseconds() <= date.getMilliseconds()){
    const prefix = '-----BEGIN RSA PUBLIC KEY-----';
    const suffix = '-----END RSA PUBLIC KEY-----';
      return prefix + fs.readFileSync(keyDir + fileName, 'utf8').split('\n')[0] + suffix;
    }
  }
}

function fileNameToDate(fileName){
  const array = fileName.split("-");
  return new Date(array[0], parseInt(array[1]) - 1);
}

function getPrivateKey(){
  const file = getFilesDescending()[0];
  if(!file || monthDiff(new Date(), fileNameToDate(file)) > 4){
    generateKeys();
    return getPrivateKey();
  }
  const prefix = '-----BEGIN RSA PRIVATE KEY-----';
  const suffix = '-----END RSA PRIVATE KEY-----';
  return prefix + fs.readFileSync(keyDir + file, 'utf8').split('\n')[1] + suffix;
}

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    return months;
}

function getFilesDescending(){
  return fs.readdirSync(keyDir).sort().reverse();
}

function getMonth(date){
  return ('0' + (date.getMonth()+1)).slice(-2)
}

function generateKeys(){
  const fileName = getFileName();
  if(!fs.existsSync(fileName)){
    const diffieHell = crypto.createDiffieHellman(1024);//TODO change this value to a stronger one
    diffieHell.generateKeys(base64);
    fs.writeFileSync(fileName, diffieHell.getPublicKey(base64) + '\n' + diffieHell.getPrivateKey(base64));
    return true;
  }
  return false;
}

function getFileName(){
  const now = new Date();
  return keyDir + now.getFullYear() + '-' + getMonth(now);
}

function toDateObject(date){
  return Date.from(date) || new Date();
}

module.exports = validator;

Basically whenever the sign method is invoked, the code checks if there is a keypair fiñe which was generated within the last 4 months and if it is not generate such a keypair and use that one. The data param is a ISO string which is returned by Date.toISOString().
I'm getting the following error: Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long.
2 Questions: I'm probaly doing something really obvious wrong here, what should I do instead?
And should I dump my attempt entirely and use HTTPS certificates instead?
I'd prefer not to because this makes local testing a lot harder.

来源:https://stackoverflow.com/questions/45363705/generate-key-for-signing-within-nodejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!