Daffy
Daffy

Reputation: 851

How can I get a certificate to verify my RSA digital signature using jsrsasign?

I am using jsrsasign and I have an RSA public and private key that I generated earlier. I used the following code to generate a signature.

var key = new RSAKey();
key.readPrivateKeyFromPEMString($("#private")[0].value); // "private" is a textarea containing the PEM encoded private key.
var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA", "prov": "cryptojs/jsrsa"});
sig.initSign(key);
sig.updateString('message');
var sigValueHex = sig.sign();

This produced the expected hex signature. The documentation for jsrsasign provides the following code to verify signatures.

var sig = new KJUR.crypto.Signature({"alg": "SHA1withRSA", "prov": "cryptojs/jsrsa"});
sig.initVerifyByCertificatePEM("-----BEGIN CERTIFICATE-----(snip)");
sig.updateString('message');
var isValid = sig.verify(sigValueHex);

My problem is that I do not have a certificate to verify with. sig.sign() only gives the signature, no certificate. There is also sig.initVerifyByPublicKey(RSAKey) which seemed promising at first. However, RSAKey only has ways to get the private key, not public key.

So, my question is how can I get this certificate? And if I can't, how can I get an RSAKey object from my public key? And if I can't do that, is there a better way to do digital signatures with javascript?

I am using jsrsasign and jQuery. http://kjur.github.io/jsrsasign/

If there is no way to do this with the methods I am using, is there a better way? My main goal here is to be able to send a message to a server and be sure that the message wasn't tampered with and that it came from the correct place. SSL is not an option here. The message does not need to be encrypted, only protected.

Upvotes: 3

Views: 5141

Answers (2)

supl
supl

Reputation: 114

You could generate an X.509 self-signed key/certificate pair by using openssl.

openssl req -newkey rsa:4096 -x509 -nodes -keyout key.pem -out certificate.pem

Then upload certificate.pem to the server, and use key.pem to sign messages on the client.

The message and signature can be verified on the server.

Here is the sample code of using jsrsasign:

const jsrsasign = require("jsrsasign");
const fs = require('fs');

// sign
let key = fs.readFileSync("./key.pem", "utf-8");
let sig = new jsrsasign.KJUR.crypto.Signature({"alg": "SHA1withRSA"});
sig.init(key);
sig.updateString("message");
const signature = sig.sign();

// verify
let certificate = fs.readFileSync("./certificate.pem", "utf-8");
let ver = new jsrsasign.KJUR.crypto.Signature({"alg": "SHA1withRSA"});
ver.init(certificate);
ver.updateString("message");
ver.verify(signature); // return true

For your reference.

Upvotes: 2

Sloy
Sloy

Reputation: 2974

You can create the public key with KEYUTIL.getKey(param), where "param" can be a string with either your certificate or your public key. Here are the docs for that method

Example:

    var publicKey = KEYUTIL.getKey(publicKeyString);
    var sig = new r.Signature({"alg": "SHA256withRSA", "prov": "cryptojs/jsrsa"});
    sig.initVerifyByPublicKey(publicKey);
    sig.updateString(message);
    var isValid = sig.verify(signature);

Hope that helps.

Upvotes: 2

Related Questions