问题
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