Link Search Menu Expand Document

Digital signature with cryptography

Let us explore how to protect information to ensure that the author is who they claim to be. In the past, handwritten signatures were used, with each person having a signature that was recognizable and difficult to copy.

Today, we use digital signatures, where the integrity of the information is ensured by cryptography. A digital signature is a cryptographic proof that involves two mathematically related keys:

  • πŸ—οΈ A public key, accessible by anyone, which allows for the verification of a signature.
  • πŸ”‘ A private key, which must be kept secret, and is used to create a signature.

With a digital signature, we can verify the origin or integrity of a message. If you sign a message with your private key, anyone can verify its authenticity using your public key.

Let us look at an example where you sign a message with your private key. The private key is akin to your handwritten signature, something that only you can create. We start by importing the necessary modules.

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.exceptions import InvalidSignature

We create a private key as follows. The public key is derived from the private key.

private = ec.generate_private_key(ec.SECP256R1())
public = private.public_key()

You can view the private key like this. In real applications, you should not show this key to anyone, as they could impersonate you.

pem = private.private_bytes(
    serialization.Encoding.PEM,
    serialization.PrivateFormat.PKCS8,
    serialization.NoEncryption())

We can sign a message using the sign method. This is widely used in blockchain transactions. This signature verifies that the message was created by the holder of the private key. This process is similar to authorizing a transaction.

signature = private.sign(
    b"Send 1 Euro to IBAN 123",
    ec.ECDSA(hashes.SHA256()))

Now, a third party could verify that the message was indeed created by the holder of the private key. For this, only the public key is needed. We can verify that the message has not been altered.

try:
    public.verify(
        signature,
        b"Send 1 Euro to IBAN 123",
        ec.ECDSA(hashes.SHA256()))
    print("Verification OK")
except InvalidSignature:
    print("Verification NOK")
# Verification OK

Now, let us say someone intercepts the communication and makes the following changes:

  • πŸ˜ˆπŸ’Ά Changes the amount to 100 Euro.
  • 😈🏦 Changes the account to 456.

If we now try to verify the signature with verify, we will get an InvalidSignature error. We have protected ourselves from an attacker modifying the message.

try:
    public.verify(
        signature,
        b"Send 100 Euro to IBAN 456",
        ec.ECDSA(hashes.SHA256()))
    print("Verification OK")
except InvalidSignature:
    print("Verification NOK")
# Verification NOK

In summary, the digital signature prevents someone from impersonating your identity and making statements you have not made, as long as the private key is known only to you.

✏️ Exercises:

  • Try using a different public key to verify the signature with verify and explain what happens.