hwcrypto / hwcrypto.js

Browser JavaScript library for working with hardware tokens
https://hwcrypto.github.io
MIT License
157 stars 47 forks source link

Is it possible to get determined signature (without random nonce)? #50

Open pavlovdog opened 6 years ago

pavlovdog commented 6 years ago

I'm using hwcrypto for working with Estonian E-residency card. There is no problem with getting certificates and signing messages, but I can't understand one thing: is there any way to get "determined" signature for determined message and options?

For now, each time I'm signing a message some random nonce is used, so the signature is different each time (message and options are the same). Can I somehow pass my own nonce into the sign function?

I've already tried to pass nonce parameter into hash and options and both of them - didn't work, still random nonce appeared.

martinpaljak commented 6 years ago

Not understanding which nonce you are talking about, I assume it is the random element of ECDSA signatures? That part is not changeable (enforced by the card).

Or which nonce are you talking about?

pavlovdog commented 6 years ago

@martinpaljak Well, I think you are right. I'm not tough enough in cryptography as you, so let me just give an example (generated with hwcrypto demo website):

First step. Don't change any standart options like hash, certificate, etc

Clicking sign (E residencde card is already inserted). Choosing card, entering pin, here's a result:

{nonce: "b5u9kg5r63uv77nz", result: "ok", signature: "74cf462a91bfadc5b3d7eff7b7d2dc3b2f43cae491db6f632b…f2f44c87e88e9e4227794f91a85c74733d5913c1d18c56084", src: "background.js", extension: "0.0.29"}

Second step. Just clicking sign one more time. Don't change anything Repeat all the actions. Here's a result:

{nonce: "on3m8h6hqcku9stv", result: "ok", signature: "45121a666193f7b0fca39967b3bf6eb9d91efd6a6f81b023f0…9a46b9f94a45da0144beae356cd7d968962f3a1e7a6d127f7", src: "background.js", extension: "0.0.29"}

Easy to see, that the signature is different and I'm pretty sure it's because of different nonce. So, one more time: it's impossible to get the same signature twice, right?

metsma commented 6 years ago

No nonce is not used in signature, like Martin said

Not understanding which nonce you are talking about, I assume it is the random element of ECDSA signatures? That part is not changeable (enforced by the card).

vadimkim commented 6 years ago

I would probably re-phrase the original question because have the same difficulty -- how to verify ECDSA signature with random element? any example for JAVA, Python or any other language?

vadimkim commented 6 years ago

Answering my own question @pavlovdog You can ignore this nonce, because you don't need it for signature verification. What you should do is to correctly convert signature into ASN1 format and (for hwcrypto demo site) use "NONEwithECDSA" signature instance because your data is already SHA256 encoded. Here is my unit test:


    @Test
    public void verifyHashForIdCardLogin() throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, IOException {
        Security.addProvider(new BouncyCastleProvider());
        X509Certificate x509 = // your public certificate instance here
        Signature signature = Signature.getInstance("NONEwithECDSA");
        signature.initVerify(x509);

        byte[] data = DatatypeConverter.parseHexBinary("413140d54372f9baf481d4c54e2d5c7bcf28fd6087000280e07976121dd54af2");
        signature.update(data);

        byte[] sig = ECDSAUtils.convertXMLDSIGtoASN1(DatatypeConverter.parseHexBinary("b3226e0d4ba7df034f171cd8767e28fd0c7417ed2502efe8b8ac5cd4a2386bf69fb5255eb1adc10799917e3b21c500e421d9f47f17e5bd90efed20e95e032c771c96954028f4620bd33ff2e1072699763b7065a9d6c6b65cdc8fde6be28bb050"));

        boolean verify = signature.verify(sig);
        assertTrue(verify);
    }