kjur / jsrsasign

The 'jsrsasign' (RSA-Sign JavaScript Library) is an opensource free cryptography library supporting RSA/RSAPSS/ECDSA/DSA signing/validation, ASN.1, PKCS#1/5/8 private/public key, X.509 certificate, CRL, OCSP, CMS SignedData, TimeStamp, CAdES and JSON Web Signature/Token in pure JavaScript.
https://kjur.github.io/jsrsasign
Other
3.27k stars 643 forks source link

Is jsrsasign what I need? #516

Closed jumpjack closed 3 years ago

jumpjack commented 3 years ago

Is this library suitable to perform signature validation for these type of data?

• Primary Algorithm: The primary algorithm is Elliptic Curve Digital Signature
Algorithm (ECDSA) as defined in (ISO/IEC 14888–3:2006) section 2.3, using the P–256
parameters as defined in appendix D (D.1.2.3) of (FIPS PUB 186–4) in combination the SHA–256 hash algorithm as defined in (ISO/IEC 10118–3:2004) function 4.
This corresponds to the COSE algorithm parameter ES256.

• Secondary Algorithm: The secondary algorithm is RSASSA-PSS as defined in (RFC
8230) with a modulus of 2048 bits in combination with the SHA–256 hash algorithm
as dfined in (ISO/IEC 10118–3:2004) function 4.
This corresponds to the COSE algorithm parameter: PS256.

The signature I have consists of 64 bytes in P1363 format. I also have a KID, which I used to retrieve the PEM certificate using for signing.

I need to do it in pure javascript, no node.js.

kjur commented 3 years ago
jumpjack commented 3 years ago

After a lot of reverse engineering I figured out that a signature validation process based on cose.js can be sumnmarized, for my specific case, to this:

CONTENTS = cbor.encode(SigStructure);
SIGNATURE = something // 64 bytes, P1363 format

const hash =  crypto.createHash('sha256')
hash.update(CONTENTS);
const msgHash = hash.digest();
const ec = new EC('p256');
const key = ec.keyFromPublic( { 'x': something1, 'y': something2 } );
HalfSignature1 = SIGNATURE.slice(0, SIGNATURE.length / 2);
HalfSignature2 = SIGNATURE.slice(SIGNATURE.length / 2);
key.verify(msgHash,  'r': HalfSignature1, 's': HalfSignature2 } );

How would I "translate" last line in something which uses jsrsasign?

I would like to do some tests with this page, but it does not work for me with Chrome 95. Anyway, in case I can get it working, would it also work with non-printable characters in the mesage? And does the page work if I provide only public key, message and signature of a message of which I don't know private key?

kjur commented 3 years ago

Please see this sample: https://github.com/kjur/jsrsasign/wiki/Tutorial-for-Signature-class

jumpjack commented 3 years ago

Thanks, I studied that example (and many others 1, 2 , 3), I eventually succeeded in getting rid of all errors.... but I still miss a last information: the format to use for certificate and signature, hence the verification result is always false.

I ended up with this code:


<script type="module">
  import {X509} from 'https://cdn.skypack.dev/jsrsasign';
  import * as jsrsasign from 'https://cdn.skypack.dev/jsrsasign';
  var c = new X509();

var myCert = ["MIIBIjBNBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoPNkJzHqbY/6mAjJwb4zUbOiOjvmg3b8fvydYdGXdv04r6vzgn/FD5NPJM7bojAxi6sZ8vV+fYVIQey6HnrLSsdU/QXhT3p22a+kB4ym8SbKsOy2fWqL950nZCPYW/DC9txHy+ceFuKMAarFWAMJRe+MaVIbDIAAi8tMNjZ204GkmqveyAeA6JppzthAuiX69H8Zb3Hbs49CHNwLnSpKz5HBTfcgWqHkar2HlEFccvWC++Kq47MIkEcKScS/oneDb/TiL5ClOas1gMxfwiVtkFI6zNxxJOJDSTlY66oHCVCfTruk2pQbtOtwJEGrOwq6B536QL/EkeEKMgiqlpZJbQIDAQAB"];
var stringToVerify = "aaa";
var signature = "hXyRmdQOCiVBNgDdGtiWF/gJwIk0Hs+MZtfEU4sFMEu05xsBjR9uymOJ/8FwhKCB0p+Kc1jqtsZxQqtxC0Du2EYyvjs0j5bbU9ZugZw0+9VHqKm0UA23djmZ1MT6nXt2ZEUEsS0La9yrfEnig/swAku1fQorsxG5FK5GFRjaacNIF+O0GOr0cbzEvlaAof6T6JFMueIw/iZykivs8XohSlghdPzoNmVueY9JF1XbtHZayau17jGhFTbeNNxbDBanPo593eZdgi5aTZMYHbxHx87cfU1sE5cjSioPQLsG9cQwVaWrrZa9BnB8IhR8Rv0NdRXYNTcVhc+sVHJN/QghNQ==";

let dummy = c.readCertPEM("-----BEGIN CERTIFICATE-----" + myCert + "-----END CERTIFICATE-----"); 
var pubKey = c.getPublicKey();
var signatureNew = jsrsasign.b64tohex(signature); /// ???
var verifier = new jsrsasign.KJUR.crypto.Signature({alg: "SHA1withRSA", prov: "cryptojs/jsrsa"});
try {
    verifier.init(pubKey);
    try {
        verifier.updateString(stringToVerify);
    } catch (err) {
        console.log("===============Err verif:", err);
    }
    console.log(">>>>>>>>>>>>>Validation result:" ,verifier.verify(signatureNew));
} catch (err) {
    console.log("===============Err init:",err);
}

</script>