diff --git a/duniterpy/key/verifying_key.py b/duniterpy/key/verifying_key.py index 6105fa76a1f40fed19faaae7d6f685c10301b02e..5821bcc160fd61972cf6c3964c9040972276a5c0 100644 --- a/duniterpy/key/verifying_key.py +++ b/duniterpy/key/verifying_key.py @@ -4,10 +4,12 @@ duniter public and private keys @author: inso """ -import base58 import base64 import libnacl.sign -from pylibscrypt import scrypt +import libnacl.encode + +from duniterpy.documents import Document +from duniterpy.documents.ws2p.heads import HeadV2 from .base58 import Base58Encoder @@ -15,7 +17,7 @@ class VerifyingKey(libnacl.sign.Verifier): """ Class to verify documents """ - def __init__(self, pubkey): + def __init__(self, pubkey: str) -> None: """ Creates a Verify class from base58 pubkey :param pubkey: @@ -23,7 +25,7 @@ class VerifyingKey(libnacl.sign.Verifier): key = libnacl.encode.hex_encode(Base58Encoder.decode(pubkey)) super().__init__(key) - def verify_document(self, document, **kwargs): + def verify_document(self, document: Document, **kwargs) -> bool: """ Check specified document :param duniterpy.documents.Document document: @@ -38,10 +40,10 @@ class VerifyingKey(libnacl.sign.Verifier): except ValueError: return False - def verify_ws2p_head(self, head): + def verify_ws2p_head(self, head: HeadV2) -> bool: """ Check specified document - :param duniterpy.documents.Document document: + :param HeadV2 head: :return: """ signature = base64.b64decode(head.signature) @@ -53,3 +55,15 @@ class VerifyingKey(libnacl.sign.Verifier): return True except ValueError: return False + + def verify_message(self, message: bytes) -> str: + """ + Check specified signed message signature and return message + + Return error message if signature is invalid + + :param bytes message: Message + signature + :return str: + """ + return self.verify(message).decode('utf-8') + diff --git a/examples/save_binary_signed_message.py b/examples/save_binary_signed_message.py new file mode 100644 index 0000000000000000000000000000000000000000..d873ff00a1391e03b03c56cbf4f0f906422c4fe0 --- /dev/null +++ b/examples/save_binary_signed_message.py @@ -0,0 +1,38 @@ +import getpass +from duniterpy.key import SigningKey +import libnacl.sign + +################################################ + +SIGNED_MESSAGE_FILENAME = 'duniter_signed_message.bin' + +if __name__ == '__main__': + + # prompt hidden user entry + salt = getpass.getpass("Enter your passphrase (salt): ") + + # prompt hidden user entry + password = getpass.getpass("Enter your password: ") + + # Create key object + key = SigningKey(salt, password) + + # Display your public key + print("Public key for your credentials: %s" % key.pubkey) + + message = input("Enter your message: ") + + # Sign the message, the signed string is the message itself plus the + # signature + signed_message = key.sign(bytes(message, 'utf-8')) # type: bytes + + # To create a verifier pass in the verify key: + veri = libnacl.sign.Verifier(key.hex_vk()) + # Verify the message! + verified = veri.verify(signed_message) + + # save signed message in a file + with open(SIGNED_MESSAGE_FILENAME, 'wb') as file_handler: + file_handler.write(signed_message) + + print("Signed message saved in file ./{0}".format(SIGNED_MESSAGE_FILENAME)) diff --git a/examples/verify_binary_signed_message.py b/examples/verify_binary_signed_message.py new file mode 100644 index 0000000000000000000000000000000000000000..ed7c7c3e3fbdf8f0f114a0a4d0fcb988f42cc808 --- /dev/null +++ b/examples/verify_binary_signed_message.py @@ -0,0 +1,31 @@ +import sys + +from duniterpy.key import VerifyingKey + +if __name__ == '__main__': + + if len(sys.argv) < 2: + print(""" + Usage: + python verify_signed_message.py SIGNED_MESSAGE_FILEPATH + """) + + # capture signed message filepath argument + signed_message_path = sys.argv[1] + + # ask public key of the signer + pubkeyBase58 = input("Enter public key of the message issuer: ") + + # open signed message file + with open(signed_message_path, 'rb') as file_handler: + signed_message = file_handler.read() + + # Verify the message! + verifier = VerifyingKey(pubkeyBase58) + try: + message = verifier.verify_message(signed_message) + print("Signature valid for this message:") + except ValueError as error: + message = str(error) + + print(message)