生成用于在nodejs内签名的密钥

时间:2017-07-28 02:02:31

标签: node.js cryptography signing

我有一个看似相当简单的问题,但我之前从未在nodejs中处理加密问题。
我想实现一个大约每4个月生成一个新密钥对的系统,用于签署和验证生成的结果。
这是我目前的代码:

'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;

基本上,无论何时调用sign方法,代码都会检查是否存在在过去4个月内生成的密钥对,以及是否生成了这样的密钥对并使用该密钥对。数据参数是一个ISO字符串,由Date.toISOString()返回 我收到以下错误:Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
2问题:我可能在这里做了一些非常明显错误的事情,我该怎么做呢? 我应该完全转储我的尝试并使用HTTPS证书吗? 我不愿意,因为这会使本地测试变得更加困难。

0 个答案:

没有答案