I am attempting to verify a signature with a certificate. We have to download the required certificate from the CA, verify the certificate, then verify the signature. I have no idea, and I'm hoping someone can shed some light. Here's what I have / know so far.
To sign a message, I used the following code:
function sign(sk, m, certname) {
var key = new RSAKey();
key.setPrivate(sk.n, sk.e, sk.d);
var h = CryptoJS.SHA256(JSON.stringify(m)).toString(CryptoJS.enc.Hex);
h = new BigInteger(h, 16);
var sig = key.doPrivate(h).toString(16);
var obj = { "type": "SIGNED", "msg": m, "certname": certname, "sig": sig };
return JSON.stringify(obj);
}
To verify a signature, I used the following code:
function verify(pk, signed) {
var key = new RSAKey();
var s = JSON.stringify(signed.sig).toString(CryptoJS.enc.Hex);
s = new BigInteger(s, 16);
key.setPublic(pk.n, pk.e);
var v = key.doPublic(s).toString(16);
var h = CryptoJS.SHA256(JSON.stringify(signed.msg)).toString(CryptoJS.enc.Hex);
return (v == h);
}
To verify a certificate, I used the following code: (EDIT: this is the new certificate verification function).
function verifyCertificate(signedCert, certname) {
var key = new RSAKey();
var s = JSON.stringify(signedCert.sig).toString(CryptoJS.enc.Hex);
s = new BigInteger(s, 16);
key.setPublic(CApk.n, CApk.e);
var v = key.doPublic(s).toString(16);
var h = CryptoJS.SHA256(JSON.stringify(signedCert.msg)).toString(CryptoJS.enc.Hex);
return (v == h);
}
And that's that. Can anyone please help. I don't know how to go about this.
EDIT: Okay, I think I have solved my own question (with assistance from the responses). This is the code that returns all positive results:
function verifyWithCert(sig) {
// 1. Download the required certificate from the CA
// 2. Verify the certificate
// 3. Verify the message
var certKey = new RSAKey();
var loadedCert = loadCert(sig.certname);
var certS = JSON.stringify(loadedCert.sig).toString(CryptoJS.enc.Hex);
certS = new BigInteger(certS, 16);
certKey.setPublic(CApk.n, CApk.e);
var certV = certKey.doPublic(certS).toString(16);
var certH = CryptoJS.SHA256(JSON.stringify(loadedCert.msg)).toString(CryptoJS.enc.Hex);
var verifyResult;
if (certV == certH) {
verifyResult = true;
}
var Sigkey = new RSAKey();
var s = JSON.stringify(sig.sig).toString(CryptoJS.enc.Hex);
s = new BigInteger(s, 16);
Sigkey.setPublic(loadedCert.msg.subject.pk.n, loadedCert.msg.subject.pk.e);
var v = Sigkey.doPublic(s).toString(16);
var h = CryptoJS.SHA256(JSON.stringify(sig.msg)).toString(CryptoJS.enc.Hex);
var verifySignature;
if (v == h) {
verifySignature = true;
}
var result = { "certificateFound": loadedCert ,"certificateVerified": verifyResult ,"signatureVerified": verifySignature };
return result;
}
(A note to other members of StackOverflow, I am also in this class so there's a bit of stuff that I mention that comes out of nowhere in regards to variables and other references.)
In the verifyCertificate function:
function verifyCertificate(signedCert, certname) {
var loadedCert = loadCert(certname);
// signedCert is the same as loadedCert above, the button runs the
// loadCert function and outputs the contents into the textarea,
// so the following will always be true.
var originalSig = JSON.stringify(signedCert.sig);
var loadedSig = JSON.stringify(loadedCert.sig);
log(loadedSig);
return (originalSig == loadedSig);
}
How am I supposed to verify the certificate then? What am I comparing the loaded CA certificate to? I thought maybe compare the public key in the certificate to the public key used to sign the message but... I don't know. I'm very confused.
You're on the right track with that though, think about the verify() function, and the details contained in the CApk variable at the top of the file. Can you hash the message from the loadCert() JSON response and match it against the output from:
function verify() {
//[...]
key.setPublic(pk.n, pk.e);
//[...]
}
Assuming you change a few variables?
It's similar to the method I used at least, so I'm hoping it's right. I figure if you can hash the message using the details in CApk, and compare it to a hash of the message contained in the JSON response, that verifies the certificate. Hopefully.