1

So i'm using pycryptodome packages and one of my assignment objective is to verify a message if its authentic in P2PKH

    try:
    verifier.verify(hash_obj, signature)
      print("The message is authentic")
    except ValueError:
      print("The message is not authentic")

But my assignment does not provide me with a publickey.pem file and only a json file containing a hex version of the public key. Everytime i tried to input my public key for verification, i kept getting the same error

 raise ValueError("Unsupported key type " + str(type(key)))
ValueError: Unsupported key type <class 'bytes'>

How the key was constructed:

key = DSA.generate(1024)
tup = [key.y, key.g, key.p, key.q]

and heres the JSON file:

{
    "DSA.g": "0x51c14de29b5c81c9c29ffdd4280056cb20404f61c12bc73590dfe063bb37e4b78d01c8a8f6e0fcd6ec1a4333b22189ef2620de8ed85a50713b3e4207e0aa75307cef4b3b6247098a1338274e917e13d499ffeb7d0e4f74ade48ca2bf9a4e1b10e98fa8ac49a31db5335515fac4ea1321c2306288e4dc1e3cbe6bb6702fd43847",
    "DSA.p": "0xb6a4798e05f0eae447b4a1ee2730bccaad8265db78e47dfb369dd7a2888b2e45dd8c414119dc0650c74fb246fe3355e45e4ed5deddcd1f82c235a062b7c94fb222879e4ff93f4a4e43e9e55c413cf394babe4d191bf868341b00b1b7b032adf135e00b27eee796c29e3a60fbe969c158b140515bb975a8fdc34319b6c9ed2659",
    "DSA.q": "0xc016e206bd5e9058577dbbaf5ed49841d74d1b37",
    "Pubkey": "0x9691cdb1532469a93f91e74801d82ef5ad7adee0fe5c262c0130dcb602a609b0eba7c718ff799f4fbdd6f0b8a53f24245428fe7d95cee10a22321d59ebe68a372537aa606dca56fef8f1a4e7a2e04b7c653681846c0842cdec067a3cc335285118a3073774b67f198a027d8e8ce6a66d7b1eddc811a84e4fc3f9b128e8fd75d3",
    "PubkeyHash": "15b5efdbe33ff9d7f20842eb5f3dc256ad571dde",
    "Signature": "0x3c3d45c14ee56eef28035d4ad068b65cef79a05e27bb1271acdb4fc6a68ac8f0c308b11d769698a6"
}

Is there any advice for me to import they publickey via this json file instead of .pem? I'm sorry i really new to this and i'm still trying get a grasp on the whole P2PKH

Heres my code for the function:

def check_sig(pub_key, signature):
    pub_key_ascii = pub_key.encode('utf-8')
    print(type(pub_key_ascii))
    message = "CSCI301_Assignment2"
    hash_obj = SHA256.new(message)
    hash_obj.update(message.encode('utf-8'))
    verifier = DSS.new(pub_key_ascii, 'fips-186-3')
    try:
        verifier.verify(hash_obj, signature)
        print("The message is authentic")
    except ValueError:
        print("The message is not authentic")

1 Answers1

0

You do not show how you call check_sig(). My guess is that pub_key is a string. Then pub_key_ascii is a byte object, which is rejected by Crypto.Signature.DSS.new(key, ...):

key (a key object) – ... it must be either Crypto.PublicKey.DSA or Crypto.PublicKey.ECC

You may use for example Crypto.PublicKey.ECC.import_key() to create a valid key from bytes.

Wolfgang Kuehn
  • 12,206
  • 2
  • 33
  • 46
  • Apologies, sorry for not including this in, the function is called with a string arg after extracting from the JSON file, check_sig(pub_key, signature). the public key is in a hex format after being generated. key = DSA.generate(1024) tup = [hex(key.y), hex(key.g), hex(key.p), hex(key.q)] – Jonathan Chee Jul 25 '21 at 10:56
  • Try `Crypto.PublicKey.DSA.construct()` to resurrect a `DsaKey` object from its components. These components seem to be encoded in the JSON file, of which the details you do not provide. – Wolfgang Kuehn Jul 25 '21 at 11:20
  • I've included the JSON file within the question, i've loaded them into the program and extracted them followed by adding them into tup but somehow i'm still not able to construct the DSAkey, is it because the values are in hex format? – Jonathan Chee Jul 25 '21 at 11:27
  • Yes, `construct()` expects long ints. Do something like `int(d["DSA.g"], 16)`. – Wolfgang Kuehn Jul 26 '21 at 18:47