Home > OS >  Can't verify signature with PyCryptodome ECC (ASN1?)
Can't verify signature with PyCryptodome ECC (ASN1?)

Time:11-17

I'm curently working on a small program to automate decryption in python using PyCryptodome

i have a shell version of my test that work just fine but i can't figure out why it won't verify in python (maybe an encode/decode problem?)

private ECC key generation:

openssl ecparam -name prime256v1 -genkey -noout -out key.pem

public key generation:

openssl ec -in key.pem -pubout -out publicKey.pub

data to sign:

echo test > i_am_a_test.txt

generate sign file:

openssl dgst -sign key.pem -out data.sig i_am_a_test.txt

verify the signature:

openssl dgst -verify publicKey.pub -signature data.sig i_am_a_test.txt
Verified OK

the python version:

import base64
from Crypto.Hash import SHA256
from Crypto.PublicKey import ECC
from Crypto.Signature import DSS

if __name__ == "__main__":
    # the pub key from publicKey.pub
    pub = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzlNm3snsI8D4VWf7vwNkR4WG0F/ymFgew1xUIVn6tUL0ln lc/lKxOIUa3O2uFkoCUwEALCTpasWbNUoNGi JQ=="
    # the data to verify
    data = "test"
    # the signature from data.sig
    sig = "MEYCIQCLbTx5uk18vixVZiG/s9bpBso5u3BZcJDNDSUX5bZc6gIhAMbqzdioGmelKIgVlUmZhtaYs9Szs9asATHCJvTIx7G8"
    
    key = ECC.import_key(base64.b64decode(pub))
    h = SHA256.new(base64.b64decode(data))
    verifier = DSS.new(key, 'fips-186-3', encoding="der")
    verifier.verify(h, base64.b64decode(sig))
    print("The message is authentic.")

the verification output

Traceback (most recent call last):
  File "/home/admin/Documents/tests/main.py", line 51, in <module>
    verifier.verify(h, base64.b64decode(sig))
  File "/home/admin/.local/share/virtualenvs/admin-afIRSt_6/lib/python3.8/site-packages/Crypto/Signature/DSS.py", line 169, in verify
    raise ValueError("The signature is not authentic")
ValueError: The signature is not authentic

CodePudding user response:

data is not base64-encoded, but you are trying to decode it before calculating hash.

Also echo adds an '\n' to the output (try xxd i_am_a_test.txt), so the data is actually b'test\n'.

import base64
from Crypto.Hash import SHA256
from Crypto.PublicKey import ECC
from Crypto.Signature import DSS

if __name__ == "__main__":
    # the pub key from publicKey.pub
    pub = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzlNm3snsI8D4VWf7vwNkR4WG0F/ymFgew1xUIVn6tUL0ln lc/lKxOIUa3O2uFkoCUwEALCTpasWbNUoNGi JQ=="
    # the data to verify
    data = b"test\n"
    # the signature from data.sig
    sig = "MEYCIQCLbTx5uk18vixVZiG/s9bpBso5u3BZcJDNDSUX5bZc6gIhAMbqzdioGmelKIgVlUmZhtaYs9Szs9asATHCJvTIx7G8"

    key = ECC.import_key(base64.b64decode(pub))
    h = SHA256.new(data)
    verifier = DSS.new(key, 'fips-186-3', encoding="der")
    verifier.verify(h, base64.b64decode(sig))
    print("The message is authentic.")

Output:

The message is authentic.
  • Related