​​​​Sending a key securely to a recipient has been a problem for many years. The sender and the receiver must agree on a key and keep it secret between themselves. If they are at different locations, they must use a trusted courier or use some other secure communication to share the key and to prevent its disclosure during transmission. Anyone who has access to the key while in transit can read, modify, and forge the encrypted information without authorization.

The problems of key distribution are solved by Asymmetric Cryptography, also called public key cryptography. This concept was introduced in 1975 by Whitfield Diffie and Martin Hellman. Public key cryptography uses mathematical techniques that are easy to compute in one direction but extremely difficult to compute in the reverse direction. Asymmetric cryptography greatly simplifies the exchange of keys over a non-secure medium. Some commonly used asymmetric algorithms are RSA (Rivest-Shamir-Adleman) and ECC (Elliptic Curve Cryptography). RSA is based on factoring large prime numbers, which is extremely difficult, while ECC uses smaller key sizes and less computation.

AES (Advanced Encryption Standard) is a symmetric encryption algorithm that uses the same key for both encryption and decryption and is widely used for fast data encryption, while asymmetric algorithms such as RSA are typically used for secure key exchange.

In this article, we focus on using RSA together with AES to implement a secure communication system between two embedded devices.

Elektor Green Memebrship 4-2026

Secure Communication Between Two Parties Using AES and RSA

The notes below are based on using the AES-256 cipher in ECB mode and RSA-1024 public/private key generation to establish secure communication between two nodes. You may use the same steps for AES GCM mode and/or longer RSA key sizes if you wish. A complete Raspberry Pi 5 program is given in the next section to establish the communication easily.

1. Sending a Message

• Get the second party’s public key

• Encrypt your plaintext using the AES-256 cipher to generate ciphertext. You may include identification words in the plaintext if you wish.

• Encrypt your AES-256 key using RSA

• Send the AES ciphertext and the RSA-encrypted key to the second party, e.g., using email or some other means of communication

• The second party uses their private key to decrypt the AES-256 key

• The second party uses the AES-256 cipher with the decrypted key to decrypt the ciphertext and generate the plaintext

2. Receiving a Message

• Generate a public and private key using RSA

• Send the public key to the second party, e.g., using email or some other form of communication

• Receive the RSA-encrypted AES-256 key and AES-256 ciphertext from the second party

• Decrypt the AES-256 key using the RSA decryption algorithm

• Use the decrypted AES-256 key to decrypt the ciphertext and obtain the plaintext

Complete Program to Send/Receive Messages

This is a complete secure communication program. The user is given the options to create a private/public key pair, to enter the public key sent by the second party and the plaintext, and also to enter the private key to decrypt the key and the message.

Listing 1 shows the program listing (Program: RSASendReceive.py). The Crypto library is imported into the program. The program is run using PuTTY over the SSH link. The reason for this is that data can easily be copied and pasted using PuTTY, but not in Thonny. 


Listing 1: Program RSASendreceive.py (Excerpt).
 

from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_v1_5
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad
import base64

KEY_SIZE = 1024  # can be changed

 

def aes256_decrypt(key, ciphertext):
    cipher = AES.new(key, AES.MODE_ECB)
    padded = cipher.decrypt(ciphertext)
    pad_len = padded[-1]
    return padded[:-pad_len]

 

def print_red(s):
    print("\033[91m%s\033[0m" % s)

 

# Main program

while True:
    print("\n\nG Generate and display new public/private key")
    print("P Read second party's public key, read plaintext, generate ciphertext using AES-256")
    print("R Read from second party: RSA encrypted key and ciphertext to decrypt plaintext")
    print("X to Exit")

    mode = input("Mode: ")

    if mode == "G":
        key = RSA.generate(KEY_SIZE)
        private_pem = key.export_key()
        public_pem = key.publickey().export_key()

        print(private_pem.decode())
        print(public_pem.decode())

    elif mode == "P":
        rsa_pub_pem = input("Enter PUBLIC KEY:\n")
        rsa_pub_key = RSA.import_key(rsa_pub_pem)

        aes_key = get_random_bytes(32)
        rsa_cipher = PKCS1_v1_5.new(rsa_pub_key)
        encrypted_aes_key = rsa_cipher.encrypt(aes_key)

        plaintext = input("Enter plaintext: ").encode()
        plaintext_padded = pad(plaintext, AES.block_size)

        aes_cipher = AES.new(aes_key, AES.MODE_ECB)
        ciphertext = aes_cipher.encrypt(plaintext_padded)

        print(base64.b64encode(encrypted_aes_key).decode("utf-8"))
        print(ciphertext.hex().upper())

    elif mode == "R":

        ...

        private_pem = input("Enter PRIVATE KEY:\n")
        rsa_key = RSA.import_key(private_pem)
        cipher_rsa = PKCS1_v1_5.new(rsa_key)

        ...

        enc_b64 = input("Enter encrypted AES key (Base64): ")
        encrypted_bytes = base64.b64decode(enc_b64)

        sentinel = b"FAILED"
        aes_key = cipher_rsa.decrypt(encrypted_bytes, sentinel)

        ...

        hex_input = input("Enter ciphertext (Hex): ").replace(" ", "")
        ciphertext = bytes.fromhex(hex_input)

        decrypted = aes256_decrypt(aes_key, ciphertext)
        print(decrypted.decode("utf-8"))

    elif mode == "X":
        break


The following menu is displayed when the program is run:

 

while True:

    print("\n\nG Generate and display new public/private key")

    print("P Read second party's public key,read plaintext,generate ciphertext using AES-256")

    print("R Read from second party: RSA encrypted key and ciphertext to decrypt plaintext")

    print("X to Exit")

    print()

    mode = input("Mode: ")

 

Selecting option G generates an RSA public/private key pair with the key length set by KEY_SIZE. Although the KEY_SIZE is set to 1024, it can be increased for greater security. Both the generated public and private keys are displayed in PEM format on the screen so that they can be copied and pasted if required later.

Selecting option P firstly prompts the user to enter the public key in PEM format. This is the public key sent by the second party. Then the plaintext is read from the keyboard and an AES-256 32-byte key is generated. The plaintext is encrypted using the AES-256 cipher. The AES-256 key is then encrypted using RSA. The encrypted ciphertext and encrypted AES-256 key are displayed on the screen so that they can be copied and pasted if required later.

Selecting option R prompts the user to enter the private key and the encrypted AES-256 key. The AES key is decrypted using the private key. Then the ciphertext is decrypted using the AES-256 cipher with the decrypted key. The resulting plaintext is displayed on the screen. Important outputs from the program are displayed with red-coloured headings so that they can easily be identified.

Finally, selecting X terminates the program.

Figure 1, Figure 2, and Figure 3 show example runs of the program with different options.

Example program: Secure Communication with RSA and AES
Figure 1: Example program run 1. Figure 2: Example program run 2. Figure 3: Example program run 3.

Case study – Communicating secretly and securely

In this case study, we will assume that Mary wants to send a secure and secret message to John. Further assume that they both have the Raspberry Pi 5 and have loaded the program RSASendReceive.py (Listing 1). The procedure is as follows:

 

• John creates a public/private key pair by selecting option G in the program (Figure 4) and sends his public key to Mary, e.g., using email or some other communication method available.

John creates a public/private key pair. Secure Communication with RSA and AES
Figure 4: John creates a public/private key pair.

• Mary selects option P, writes her secret message as plaintext, generates ciphertext using AES-256, generates an encrypted AES-256 key, and an RSA-encrypted AES key (Figure 5). Mary can agree with John in advance to include, e.g. the date and/or time (or a counter) at the beginning of her plaintext to ensure that John knows the message comes from her.

Mary writes her secret message. Secure Communication with RSA and AES
Figure 5: Mary writes her secret message.

• Mary sends the ciphertext and the encrypted AES-256 key to John, e.g., using email or some other means of communication.

• John selects option R to decrypt the AES-256 key and finally decrypt the ciphertext to produce the readable plaintext (Figure 6).

John produces the plaintext.
Figure 6: John produces the plaintext.

This article has demonstrated how secure communication can be implemented in practice using a combination of asymmetric and symmetric cryptography. By using RSA for key exchange and AES-256 for data encryption, a reliable and efficient method of transmitting confidential information between embedded devices can be achieved. The Raspberry Pi 5 implementation shows that even relatively simple systems can support modern cryptographic techniques using straightforward software. Although the example uses AES in ECB mode and RSA-1024 for simplicity, the same approach can be extended to more secure configurations, such as AES-GCM and larger key sizes, making it suitable for a wide range of embedded and IoT applications.


Questions or Comments?

Do you have any questions or comments related to this article? Email the authors at d.ibrahim@btinternet.com or Elektor at editor@elektor.com.


Editor’s Note: This article (260216-01) is an excerpt from the book, Practical Microcontroller Cryptography (Elektor, 2026). It was formatted and lightly edited to match Elektor’s conventions and page layout. 

Subscribe
Tag alert: Subscribe to the tag Cryptography and you will receive an e-mail as soon as a new item about it is published on our website!