我有一个看似相当简单的问题,但我之前从未在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证书吗?
我不愿意,因为这会使本地测试变得更加困难。