What is Cryptography?
According to Kaspersky, Cryptography is the study of communications security techniques that allow only the sender and intended recipient of a message to view its contents.
Cryptography is closely associated with encryption, which is the act of scrambling ordinary text into what’s known as ciphertext and then back again upon arrival.
Modern cryptography exists at the intersection of the disciplines of mathematics, computer science, electrical engineering, communication science, and physics. Applications of cryptography include electronic commerce, chip-based payment cards, digital currencies, computer passwords, military communications, etc.
3 Types of Cryptographic Algorithms
According to Kessler, 2021, these are the three types of Cryptographic Algorithms:
- Secret Key Cryptography (SKC): Uses a single key for both encryption and decryption; also called symmetric encryption. Primarily used for privacy and confidentiality.
- Public Key Cryptography (PKC): Uses one key for encryption and another for decryption; also called asymmetric encryption. Primarily used for authentication, non-repudiation, and key exchange.
- Hash Functions: Uses a mathematical transformation to irreversibly “encrypt” information, providing a digital fingerprint. Primarily used for message integrity.
Why use Python for Cryptography?
- Python provides powerful Cryptographic libraries as we will explore them in this article.
- Python is good for rapid prototyping.
Read more here, to see “How Python is Ideal for Solving Mathematically Heavy Problems”:
Delphi adds powerful GUI features and functionalities to Python
In this tutorial, we’ll build Windows Apps with extensive cryptographic capabilities by integrating Python’s Computer Vision libraries with Embarcadero’s Delphi, using Python4Delphi (P4D).
P4D empowers Python users with Delphi’s award-winning VCL functionalities for Windows which enables us to build native Windows apps 5x faster. This integration enables us to create a modern GUI with Windows 10 looks and responsive controls for our Python Computer Vision applications. Python4Delphi also comes with an extensive range of demos, use cases, and tutorials.
We’re going to cover the following…
How to use hashlib, hmac, secrets, PyCryptodome, and One-Time-Pad Python libraries to perform Cryptographic tasks
All of them would be integrated with Python4Delphi to create Windows Apps with Cryptographic capabilities.
What are the pre-requisites for using the cryptography libraries?
Before we begin to work, download and install the latest Python for your platform. Follow the Python4Delphi installation instructions mentioned here. Alternatively, you can check out the easy instructions found in the Getting Started With Python4Delphi video by Jim McKeeth.
Time to get started!
First, open and run our Python GUI using project Demo1 from Python4Delphi with RAD Studio. Then insert the script into the lower Memo, click the Execute button, and get the result in the upper Memo. You can find the Demo1 source on GitHub. The behind the scene details of how Delphi manages to run your Python code in this amazing Python GUI can be found at this link.
1. How do you perform cryptographic tasks with hashlib?
The hashlib module defines an API for accessing different cryptographic hashing algorithms. To work with a specific hash algorithm, use the appropriate constructor function or new() to create a hash object. From there, the objects use the same API, no matter what algorithm is being used.
Since hashlib is “backed” by OpenSSL, all of the algorithms provided by that library are available, including:
Some algorithms are available on all platforms, and some depend on the underlying libraries.
This section will guide you to combine Python4Delphi with the hashlib library, inside Delphi and C++Builder. Since hashlib is a built-in Python library, no further installation is required.
Let’s try an introductory example of hashlib, to obtain the digest of the byte string b’Hello World!’, it’s more condensed version, and try an algorithm provided by OpenSSL:
m = hashlib.sha256()
# More condensed example:
# Using new() with an algorithm provided by OpenSSL:
h = hashlib.new('ripemd160')
h.update(b"Nobody inspects the spammish repetition")
Here is the result of using the cryptography library in the Python GUI
2. How do you perform cryptographic tasks with hmac?
The hmac module implements keyed-hashing for message authentication, as described in RFC 2104. The HMAC algorithm can be used to verify the integrity of information passed between applications or stored in a potentially vulnerable location.
The basic idea is to generate a cryptographic hash of the actual data combined with a shared secret key. The resulting hash can then be used to check the transmitted or stored message to determine a level of trust, without transmitting the secret key.
This section will guide you to combine Python4Delphi with the hmac library inside Delphi and C++Builder, to create Applications of Message Signatures. Since hmac is a built-in Python library, no further installation is required.
How do I implement applications of message signatures using Python’s hmac?
Let’s try an advanced example: Applications of Message Signatures. HMAC authentication should be used for any public network service, and any time data is stored where security is important. For example, when sending data through a pipe or socket, that data should be signed and then the signature should be tested before the data is used.
Here are the steps to implement the Applications of Message Signatures:
- Establish a function to calculate a digest for a string, and a simple class to be instantiated and passed through a communication channel.
- Create a BytesIO buffer to represent the socket or pipe. This example uses a naive, but easy to parse, format for the data stream. The digest and length of the data are written, followed by a new line. The serialized representation of the object, generated by pickle, follows.
- For this example program, write two objects to the stream. The first is written using the correct digest value. The second object is written to the stream with an invalid digest, produced by calculating the digest for some other data instead of the pickle.
- Now that the data is in the BytesIO buffer, it can be read back out again. Start by reading the line of data with the digest and data length. Then read the remaining data, using the length value. pickle.load() could read directly from the stream, but that assumes a trusted data stream, and this data is not yet trusted enough to unpickle it. Reading the pickle as a string from the stream, without actually unpickling the object, is safer.
- Once the pickled data is in memory, the digest value can be recalculated and compared against the data read using compare_digest(). If the digests match, it is safe to trust the data and unpickle it.
The following is the code example of hmac and Python4Delphi to apply the Message Signatures (Run this inside the lower Memo of Python4Delphi Demo01 GUI):
"Return a digest for the message."
hash = hmac.new(
"""Demonstrate checking digests before unpickling.
def __init__(self, name):
self.name = name
# Simulate a writable socket or pipe with a buffer
out_s = io.BytesIO()
# Write a valid object to the stream:
o = SimpleObject('digest matches')
pickled_data = pickle.dumps(o)
digest = make_digest(pickled_data)
header = b'%s %dn' % (digest, len(pickled_data))
# Write an invalid object to the stream
o = SimpleObject('digest does not match')
pickled_data = pickle.dumps(o)
digest = make_digest(b'not the pickled data at all')
header = b'%s %dn' % (digest, len(pickled_data))
# Simulate a readable socket or pipe with a buffer
in_s = io.BytesIO(out_s.getvalue())
# Read the data
first_line = in_s.readline()
if not first_line:
incoming_digest, incoming_length = first_line.split(b' ')
incoming_length = int(incoming_length.decode('utf-8'))
print('nREAD:', incoming_digest, incoming_length)
incoming_pickled_data = in_s.read(incoming_length)
actual_digest = make_digest(incoming_pickled_data)
if hmac.compare_digest(actual_digest, incoming_digest):
obj = pickle.loads(incoming_pickled_data)
print('WARNING: Data corruption')
Here is an example of the hmac for Applications of Message Signatures in the Python GUI:
3. How do you perform cryptographic tasks with the Python secrets library?
secrets is a Python built-in library to generate secure random numbers for managing secrets. The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.
The secrets module provides functions for generating secure tokens, suitable for applications such as password resets, hard-to-guess URLs, and similar tasks.
To be secure against brute-force attacks, tokens need to have sufficient randomness. Unfortunately, what is considered sufficient will necessarily increase as computers get more powerful and able to make more guesses in a shorter period. In 2015, it is believed that 32 bytes (256 bits) of randomness is sufficient for the typical use-case expected for the secrets module.
This section will guide you to combine Python4Delphi with the secrets library, inside Delphi and C++Builder, from installing secrets with pip, to create a Generator for a Hard-to-Guess Temporary URL; Containing a Security Token Suitable for Password Recovery.
After installing Python4Delphi properly, you can get secrets using pip or easy install to your command prompt:
pip install secrets
Don’t forget to put the path where your secrets library installed, to the System Environment Variables:
System Environment Variable Examples
Let’s run this example:
How can we generate a hard-to-guess temporary URL containing a security token suitable for password recovery applications?
url = 'https://pythongui.org/reset=' + secrets.token_urlsafe()
We execute them several times to show you that all the output are unique, random, and hard to guess:
4. How do you perform cryptographic tasks with PyCryptodome?
PyCryptodome is a self-contained Python package of low-level cryptographic primitives.
PyCryptodome is a fork of PyCrypto. It brings the following enhancements with respect to the last official version of PyCrypto (2.6.1):
- Authenticated encryption modes (GCM, CCM, EAX, SIV, OCB)
- Accelerated AES on Intel platforms via AES-NI
- First-class support for PyPy
- Elliptic curves cryptography (NIST P-256, P-384, and P-521 curves only)
- Better and more compact API (nonce and iv attributes for ciphers, automatic generation of random nonces and IVs, simplified CTR cipher mode, and more)
- SHA-3 (including SHAKE XOFs), truncated SHA-512 and BLAKE2 hash algorithms
- Salsa20 and ChaCha20/XChaCha20 stream ciphers
- Poly1305 MAC
- ChaCha20-Poly1305 and XChaCha20-Poly1305 authenticated ciphers
- scrypt, bcrypt and HKDF derivation functions
- Deterministic (EC)DSA
- Password-protected PKCS#8 key containers
- Shamir’s Secret Sharing scheme
- Random numbers get sourced directly from the OS (and not from a CSPRNG in userspace)
- Simplified install process, including better support for Windows
- Cleaner RSA and DSA key generation (largely based on FIPS 186-4)
- Major cleanups and simplification of the codebase
First, here is how you can get PyCryptodome:
pip install pycryptodomex
Run the following code inside the lower Memo of Python4Delphi Demo01 GUI, to generate an RSA key. The following code generates a new RSA key pair (secret) and saves it into a file, protected by a password. We use the scrypt key derivation function to thwart dictionary attacks. In the end, the code prints the RSA public key in ASCII/PEM format:
from Cryptodome.PublicKey import RSA
secret_code = "Unguessable"
key = RSA.generate(2048)
encrypted_key = key.export_key(passphrase=secret_code, pkcs=8,
file_out = open("F:rsa_key.bin", "wb")
PyCryptodome example for generating an RSA Key
5. How do you perform cryptographic tasks with the One-Time-Pad library?
One-Time-Pad Python is a command-line encryption tool, which uses an encryption mechanism very similar to One-time Pad (OTP) encryption technique.
In cryptography, the one-time pad (OTP) is an encryption technique that cannot be cracked, but requires the use of a single-use pre-shared key that is no smaller than the message being sent. In this technique, a plaintext is paired with a random secret key (also referred to as a one-time pad). Then, each bit or character of the plaintext is encrypted by combining it with the corresponding bit or character from the pad using modular addition.
Here is how you can get One-Time-Pad:
pip install onetimepad
The following is a basic code example of One-Time-Pad to encrypt and decrypt “Embarcadero” using “a_random_key” (run this inside the lower Memo of Python4Delphi Demo01 GUI):
# Encrypt message
cipher = onetimepad.encrypt('Embarcadero', 'a_random_key')
# Decrypt message
msg = onetimepad.decrypt(cipher, 'a_random_key')
Here is the One-Time-Pad demo result in the Python GUI:
We already demonstrate 5 powerful Python libraries for Cryptography and their simple-yet powerful real-world implementation (encryption with sha224, sha256, and ripemd160 algorithm, applications of message signatures, create a generator for a hard-to-guess temporary URL, and many more). All of them wrapped well inside a powerful GUI provided by Python4Delphi. We can’t wait to see what you build with Python4Delphi!
Want to know some more? Then check out Python4Delphi which easily allows you to build Python GUIs for Windows using Delphi.