Ensuring Security and Authenticity Through Digital Signatures and Hash Functions
In this article, we’re going to build a client-server application to show socket programming, hash functions, and digital signatures.
The server generates RSA public and private keys, sending the public key securely to the client.
Upon connection, the client sends a challenge text to the server.
The server calculates the SHA256 hash of the challenge text and signs it with its private key before sending it back to the client.
The client receives the signed hash and verifies it using the server’s public key.
What is a hash function?
A hash function is an algorithm that maps data of any size to a fixed, usually smaller, value known as a “hash” or "digest.” This function is designed to be efficient in terms of execution time and to generate distinct hashes for various types of data. Hash functions are commonly used in cryptography, databases, information security, and other areas of computing.
SHA-256 (Secure Hash Algorithm, 256 bits)
SHA-256 is a more secure version of the SHA algorithm, which produces a digest of 256 bits (32 bytes). It is widely used in information security and cryptography applications.
A simple Python example to show how the hash function works?
Digital Signature
Digital signatures ensure that digital information is true and secure. They are created by calculating a hash of the message content, which is then encrypted using the sender’s private key. The sender’s public key can be used to perform a mathematical verification of this signature. The integrity and authenticity of the information are confirmed if the decrypted hash of the signature matches the calculated hash of the original message. Otherwise, the signature or the message indicates that there has been a modification.
PyCryptodome
PyCryptodome is a Python library that aids in implementing hash and encryption algorithms. It’s an extension of PyCrypto that provides a more user-friendly API and enhanced security.
In this introduction, we’ll discuss the features of PyCryptodome, including hash algorithms, symmetric and asymmetric encryption, and digital signatures.
Asymmetric Encryption
Asymmetric encryption involves using both a private key and a public key. PyCryptodome can encrypt, decrypt, and generate keys using algorithms like RSA.
Key Features:
- Symmetric and Asymmetric Encryption Algorithms: PyCryptodome supports various encryption algorithms like AES, DES, RSA, and ECC.
- Hash Algorithms: It provides execution of various hash algorithms, including SHA-256, SHA-512, and MD5, used for generating cryptographic digests of data.
- Cryptographically Secure Random Number Generation: PyCryptodome offers a secure random number generator, crucial for various cryptographic processes.
- Key Management: It facilitates the creation and manipulation of cryptographic keys.
- Digital Signatures: PyCryptodome simplifies the creation and verification of digital signatures, ensuring data authenticity and security.
Why Use PyCryptodome?
- Security: It offers reliable cryptographic algorithm implementations.
- Ease of Use: PyCryptodome provides an easy-to-use API and detailed documentation for development.
- Flexibility: A large number of algorithms are supported to meet the specific security needs of each application.
- Open Source: Available under the Apache 2.0 Open Source License, it can be used in both commercial and non-commercial projects.
The setup is where the server and client use digital signatures with an RSA public key and SHA256 hash. To securely send a message to the server and ensure its authenticity and integrity, the client must follow these steps:
- Creation of a Digital Signature:
- The client calculates the SHA256 hash of the message.
- Then, it signs the hash using its RSA private key.
- The result is the digital signature of the message.
2. Sending the message and signature to the server:
- The client sends the message and its digital signature to the server.
Upon receiving the message and digital signature, the server performs the following steps:
- Verification of a Digital Signature:
- The server calculates the SHA256 hash of the received message.
- It uses the client’s RSA public key to verify the received digital signature.
- If the verification is successful, it confirms that the message was indeed sent by the client and hasn’t been altered since.
2. Message Processing:
- If the digital signature is valid, the server processes the message.
By allowing only the client to use its private key to create the digital signature, this technique ensures that the message is genuine and trustworthy. Moreover, as the signature is based on the SHA256 hash of the message, any changes to the message would be detected during the signature verification.
Now, let’s create the public-private key pair with a Python script:
# Output
# -----BEGIN PUBLIC KEY-----
# MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIwVpFBwp83YsLBpZen+j5bP/d
# io/guJA1YtdyRIkERqjkeySaoRNCqSnhuZfLN26gdyxGxuarCtJ4o02a/aRCeBgX
# gyFjf/HIqKu/gZnd2csSLR8BPKpRMc91iLou1utZ2o6vSdesEfQR5NczovBAKUx6
# 7kLjXGdF/Vhtfi1lAQIDAQAB
# -----END PUBLIC KEY-----%
# -----BEGIN RSA PRIVATE KEY-----
# MIICXAIBAAKBgQDIwVpFBwp83YsLBpZen+j5bP/dio/guJA1YtdyRIkERqjkeySa
# oRNCqSnhuZfLN26gdyxGxuarCtJ4o02a/aRCeBgXgyFjf/HIqKu/gZnd2csSLR8B
# PKpRMc91iLou1utZ2o6vSdesEfQR5NczovBAKUx67kLjXGdF/Vhtfi1lAQIDAQAB
# AoGAPCa2+ezIpy4oTabtIjAOucF/jq1IO+CBEQXrIOlJFpdnXoJJLu2pXDVcf65A
# vZp/0qOyiAhrr/8fnhbsF079SodRc+qgJR/6odo2bnVaFWf4H0sDjNeN38rEbETv
# IktoXOcei9dKUcwIQvzFIHI8cz/VuAgcO6MT9LKvjMRJKDsCQQDcOZZZi4OCwndF
# vxMXICekCwlTkvBglginmpIbbh9X5ifAXxqZJ5dHi9aT35NH7oLMxJkNOSM89+FA
# 4SL23g6jAkEA6V4WajcegY1XssWogErO17OEA7rvgNgHUhlrR8IsGu8AtkjOzfQj
# s0kNuBngzjCHjDhpLcAkAgDFe0WA7xJsCwJABqdGv5XTd1Pgvp6zOPOjvvUGZxv9
# Xy2pPUcSOvnswH8XnFxDNXVYwLSc2wLaNEYkdYNLDHc5dVIX4BntMIAs+QJAB5Ea
# bvU8kvzPRCeukAJc9JeIh0pva6EVk67pUJlWLsVjI4X21qy835pVzItiQ61FJ+HI
# X0hkon/950JYrOfPAwJBAJEB9r9jiCYm/rloJOcHksmAXcX1E3DOsR4Wa5eq/FCg
# 7D+4eKHUepnUnz9/Gd6+XjxPsri/BrXjd/PUqFAbWa4=
# -----END RSA PRIVATE KEY-----%
- The server’s public key has been previously shared with the client.
- The server initializes and waits for a connection.
Now, let’s write the code for the server:
Running the code above, we get:
As seen above, the server is waiting for the client’s connection. Now, let’s write the code for the client:
Below, we can see that after the client sends the message to the server, the server sends the signature to the client.
With the challenge, it’s necessary to calculate the hash of the challenge that will be used to verify the signature with the server’s public key.
Finally, an effective method to ensure the authenticity and integrity of exchanged messages is using digital signatures with RSA public key and SHA256 hash between client and server.
By signing a message using its private key, the client ensures that only it could have generated the signature using the corresponding private key. Furthermore, as the SHA256 hash of the message serves as the basis for the signature, any alteration to the message would be detected by the server during the signature verification.
This technique is reliable, robust, and adds security to the client-server communication.
PyCryptodome provides the tools you need to implement this system efficiently and securely in Python.
To make things more understandable about the differences between RSA (Rivest-Shamir-Adleman) and DSA (Digital Signature Algorithm), below I will highlight the main differences for both algorithms:
RSA:
Purpose:
- RSA is a versatile algorithm used for encryption, digital signatures, and key exchange.
Key Generation:
- RSA key generation involves selecting two large prime numbers, computing their product, and selecting an encryption exponent and a decryption exponent.
- Security relies on the difficulty of factoring the product of two large primes.
Performance:
- RSA encryption and decryption operations are relatively slow compared to symmetric encryption algorithms like AES. The computational cost increases with larger key sizes.
- RSA signature generation and verification are also computationally expensive, especially with larger key sizes.
Security:
- RSA security is based on the difficulty of factoring large numbers, which has been extensively analyzed over the years.
- As of now, RSA is considered secure if used with sufficiently large key sizes and proper implementation.
DSA:
Purpose:
- DSA is specifically designed for digital signatures.
Key Generation:
- DSA key generation involves selecting parameters, generating a private key, and deriving a public key from the private key.
- Security relies on the discrete logarithm problem in a finite field.
Performance:
- DSA is efficient for signature generation and verification, especially with its smaller key sizes.
- Signature generation and verification are faster compared to RSA operations.
Security:
- DSA security relies on the discrete logarithm problem, which is considered computationally difficult.
- However, some weaknesses have been discovered in certain implementations of DSA.
In summary, RSA is a flexible technique that may be used for encryption, digital signatures, and key exchange, whereas DSA is only focused on digital signatures. Although RSA uses bigger key sizes and is slower than DSA, it is widely accepted and utilized in a variety of applications. In contrast, DSA is more efficient for signature processes and is widely used for authentication.
Now I think things are easier to understand; if not, comment below! This will help me to improve the quality of my articles.
That’s it for now.
Thanks for reading the article. If you like the content, I will continue to create content about Linux, cryptography, machine learning, deep learning and data science in general!
Keep going! and coding :)