help
help copied to clipboard
How can I sign a message and verify it using ED25519 keys?
- Node.js Version: 12.8.0
- OS: Windows 10 (deployment will be on CentOS 7)
- Scope (install, code, runtime, meta, other?): Code?
- Module (and version) (if relevant): crypto
I am trying to have servers connect to a centralized server. To validate their identity, I am opting to use encryption/signing keys. I would prefer to use ED25519 if possible, but if I'm mistaking their ability for this, please let me know.
Also, please note that this is not SSL/SSH. This is just general data that will be passed along an application that also accepts clients (hence the verification necessity). The keys will serve to prove the server really is a server, and give it the necessary rights/access for more methods.
I've tried RSA and I can get it partially working, but I cannot get it to load the public key properly.
Here's what I've got so far. Only dependencies are the keys, which anyone can generate. I am using ed25519 and RSA 4096-bit for this test.
"use strict"
const fs = require("fs"),
crypto = require("crypto");
// Let's set up some key files that can be easily rotated for testing
const keys = [
{algorithm: 'ed25519', name: 'ed25519', passphrase: 'password', pem: false, ppk: false, pub: false, public: false, private: false},
{algorithm: 'ed25519', name: 'ed25519_2', passphrase: 'password', pem: false, ppk: false, pub: false, public: false, private: false},
{algorithm: 'rsa', name: 'rsa', passphrase: 'password', pem: false, ppk: false, pub: false, public: false, private: false},
];
// Select our key from the list above
const key = keys[2];
// Set a message to sign
const message = 'Hello world!';
// Load the files (that exist)
key.pem = (fs.existsSync("./" + key.name + ".pem")) ? fs.readFileSync("./" + key.name + ".pem") : false;
key.ppk = (fs.existsSync("./" + key.name + ".ppk")) ? fs.readFileSync("./" + key.name + ".ppk") : false;
key.pub = (fs.existsSync("./" + key.name + ".pub")) ? fs.readFileSync("./" + key.name + ".pub") : false;
// Verify what was loaded
console.log(key.pem.toString(), "\n\n", key.ppk.toString(), "\n\n", key.pub.toString(), "\n\n");
// At this point, we have our key data and messages. Let's continue
// Create the public/private key objecs for sign/verify
key.private = crypto.createPrivateKey({key: key.pem, passphrase: key.passphrase});
// key.public = crypto.createPublicKey(key.private);
key.public = crypto.createPublicKey({key: key.pub});
// Sign message with private key
const sign = crypto.createSign('RSA-SHA512');
sign.update(message);
const sig = sign.sign(key.private);
console.log('Signed!');
console.log(sig);
// Verify signature with public key
console.log('Verifying signature...');
const verify = crypto.createVerify('RSA-SHA512');
verify.update(message);
const verified = verify.verify(key.public, sig);
// Results?
console.log('Match:', verified);
If I use the private key object to create the public key object, it works. If I use the public key to ry and create the public key object, it fails. Obviously I need to be able to have the public key on a separate server to verify without the private key, so that's where I'm stumped. This is for RSA. ED25519, can't even get the private key object.
RSA public key object error:
internal/crypto/keys.js:321
handle.init(data, format, type);
^
Error: error:0909006C:PEM routines:get_name:no start line
at Object.createPublicKey (internal/crypto/keys.js:321:10)
at Object.<anonymous> (C:\Users\...\Desktop\test_signing\exec.js:24:21)
at Module._compile (internal/modules/cjs/loader.js:868:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:879:10)
at Module.load (internal/modules/cjs/loader.js:731:32)
at Function.Module._load (internal/modules/cjs/loader.js:644:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:931:10)
at internal/main/run_main_module.js:17:11 {
library: 'PEM routines',
function: 'get_name',
reason: 'no start line',
code: 'ERR_OSSL_PEM_NO_START_LINE'
}
ED25519 private key object error:
internal/crypto/keys.js:329
handle.init(data, format, type, passphrase);
^
Error: error:0909006C:PEM routines:get_name:no start line
at Object.createPrivateKey (internal/crypto/keys.js:329:10)
at Object.<anonymous> (C:\Users\...\Desktop\test_signing\exec.js:30:22)
at Module._compile (internal/modules/cjs/loader.js:868:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:879:10)
at Module.load (internal/modules/cjs/loader.js:731:32)
at Function.Module._load (internal/modules/cjs/loader.js:644:12)
at Function.Module.runMain (internal/modules/cjs/loader.js:931:10)
at internal/main/run_main_module.js:17:11 {
library: 'PEM routines',
function: 'get_name',
reason: 'no start line',
code: 'ERR_OSSL_PEM_NO_START_LINE'
}
They error with the same reason, but I have no idea what that is. Any help would be greatly appreciated!!!