使用RSA Javascript证书验证签名

使用RSA Javascript证书验证签名,javascript,json,cryptography,rsa,cryptojs,Javascript,Json,Cryptography,Rsa,Cryptojs,我正在尝试用证书验证签名。我们必须从CA下载所需的证书,验证证书,然后验证签名。我不知道,我希望有人能给我一些启示。这是我到目前为止所知道的 要签署消息,我使用了以下代码: 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

我正在尝试用证书验证签名。我们必须从CA下载所需的证书,验证证书,然后验证签名。我不知道,我希望有人能给我一些启示。这是我到目前为止所知道的

要签署消息,我使用了以下代码:

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);
}
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);
}
为了验证签名,我使用了以下代码:

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);
}
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);
}
为了验证证书,我使用了以下代码:(编辑:这是新的证书验证函数)

就这样。谁能帮忙吗。我不知道该怎么办

编辑:好的,我想我已经解决了我自己的问题(在回答的帮助下)。这是返回所有肯定结果的代码:

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;
}
(StackOverflow的其他成员注意,我也在这个类中,所以我提到了一些关于变量和其他引用的东西。)

在verifyCertificate函数中:

功能验证证书(signedCert,certname){
var loadedCert=loadCert(certname);
//signedCert与上面loadedCert相同,按钮运行
//loadCert函数并将内容输出到文本区域,
//所以下面的话永远是正确的。
var originalSig=JSON.stringify(signedCert.sig);
var loadedSig=JSON.stringify(loadedCert.sig);
日志(加载的SIG);
返回(originalSig==loadedSig);
}
那么我该如何验证证书呢?我将加载的CA证书与什么进行比较?我想可以将证书中的公钥与用于签名消息的公钥进行比较,但是。。。我不知道。我很困惑

不过,考虑一下verify()函数,以及文件顶部的CApk变量中包含的详细信息,这是正确的。能否对loadCert()JSON响应中的消息进行散列,并将其与以下消息的输出进行匹配:

函数验证(){
//[...]
密钥setPublic(pk.n,pk.e);
//[...]
}
假设你改变了几个变量


至少和我用的方法相似,所以我希望它是正确的。我想如果您可以使用CApk中的详细信息对消息进行散列,并将其与验证证书的JSON响应中包含的消息散列进行比较。希望如此。

在“验证证书”方法中存在错误。 您需要使用355a3_main中给出的CA公钥测试证书的签名以进行验证,此处给出的代码将仅验证您的证书,其余代码将给出s假阳性

我认为这应该行得通

var loadedCert = loadCert(certname);
var originalSig = JSON.stringify(signedCert.sig);
var loadedSig = JSON.stringify(loadedCert.sig);
log(loadedSig,originalSig);

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);

if (originalSig == loadedSig && v==h)
return true;
else
return false;

那么任意长度的长消息呢


我在RSA签名验证与证书功能中再次使用了函数verify和verifycertificate。这将使您的代码相当简短。我非常感谢这篇帖子,你们都是我的救星。

什么样的课程教JavaScript加密?这是你最不希望任何人做的事@我知道,对吗?我讨厌这个。我已经调整了verify certificate函数,它可以工作了,但是现在我试图将它应用到verify RSA签名和证书上,但它不起作用。所以我又迷路了。我讨厌javascript。我几乎没有这方面的经验,这只是折磨。注意:刚刚编辑了原始问题,添加了新的证书验证功能。好的,我想我已经成功了。它说它正在验证一切,没有错误等等,所以我认为它是正确的。除了你知道他怎么说他的核心任务解决方案在5到10行之间吗?这是大约20行代码,所以我不知道我是否应该怀疑我的代码。我会把它加到原来的问题上。是的,不。我只是被卡在那个问题上了。我收到短信了,但是是的。。。无长消息Hahai如果我们对长消息取s的模,那么n应该这样做吗??ar m=asciiToHex(msg);var key=new RSAKey();var s=JSON.stringify(m).toString(CryptoJS.enc.Hex);s=新的大整数(s,16);我们可以,但是。。。。他妈的怎么会这样?你得把所有的数学题都写进去。我们认为可能将消息拆分为单独的块,然后将单独的块enc/dec连接在一起返回会起作用,但是。。。哇,对于一个不是“编程单元”(或“数学单元”)的单元,他们一直在告诉我们有很多工作要做。所以是的。。。现在我们也在尝试一些完全不同的对称密码。但它不起作用(加密是……但是描述,不是那么多)。我们迷路了哈哈