Let’s practice Python TwoFish Encryption! ✨✨ In the following example, we will encrypt a file on disk using TwoFish encryption and decrypt the same file on disk. Let’s go! 🙌🙌
Introduced in 1998, Twofish is a symmetric key block cipher with a block size of 128 bits (16 bytes) and key sizes up to 256 bits. This cipher is a Feistel Network, which is a cryptographic technique which works by splitting the data block into two equal pieces and applying encryption in multiple rounds. In each round, half of the text block is sent through a function, and then “XORed” with the other half of the text block.
We will be using Python 3.8.10. Also, you will need to install the twofish python library. You can do this with the following command: pip install twofish
Let’s write our code:
from twofish import Twofish
def tfencrypt(infile, outfile, password):
bs = 16 #block size 16 bytes or 128 bits
plaintext=infile.read()
if len(plaintext)%bs: #add padding
padded_plaintext=str(plaintext+'%'*(bs-len(plaintext)%bs)).encode('utf-8')
else:
padded_plaintext=plaintext.encode('utf-8')
T = Twofish(str.encode(password))
ciphertext=b''
for x in range(int(len(padded_plaintext)/bs)):
ciphertext += T.encrypt(padded_plaintext[x*bs:(x+1)*bs])
outfile.write(ciphertext)
def tfdecrypt(infile, outfile, password):
bs = 16 #block size 16 bytes or 128 bits
ciphertext = infile.read()
T = Twofish(str.encode(password))
plaintext=b''
for x in range(int(len(ciphertext)/bs)):
plaintext += T.decrypt(ciphertext[x*bs:(x+1)*bs])
outfile.write(str.encode(plaintext.decode('utf-8').strip('%'))) #remove padding
password = '12345'
with open('infile.txt', 'r') as infile, open('outfile.txt', 'wb') as outfile:
tfencrypt(infile, outfile, password)
with open('outfile.txt', 'rb') as infile, open('outfile_decrypted.txt', 'wb') as outfile:
tfdecrypt(infile, outfile, password)
Let’s explain what’s going on here:
- We import our library twofish.
- We define our encryption function tfencrypt(). This function accepts 3 arguments: infile, outfile and password. We read the infile as plaintext and we pad it with a special character to ensure that its entire length is a multiple of the bs, which is our block size. In this case we used the ‘%’ symbol but it can be anything unique and different from the rest of the plaintext. We then define our cipher T by calling the function TwoFish() and supplying our password in bytes as an argument. Finally we encrypt the plaintext in equally size chunks or parts and save to the disk as the outfile. The object outfile will have encrypted ciphertext after this function executes.
- We define our decryption function tfdecrypt(). This simply does the encryption process in reverse. We supply the infile, outfile and the password, as before. The infile is the encrypted file that contains the ciphertext. We decrypt this in chunks or parts of equal size as before with our password and make sure to remove any padding from the final chunk that we inserted when we encrypted it. We then write the entire decrypted plaintext to the outfile. When this function executes, the outfile will have our original, decrypted plaintext.
- The password we define here is CRITICAL. In practice your password should be something more complex and isn’t easy to guess. We used a simple one for this example.
- We use a with statement to open the plaintext file for encryption and we do the same with the ciphertext to decrypt it.
Before running this example code you must prepare a file called infile.txt which must exist in the same folder as this script and should contain some text. When the script executes you will have 2 new files on the desktop:
- outfile.txt which will contain the ciphertext. This text will not be readable.
- outfile_decrypted.txt which will contain the plaintext after it has been successfully decrypted. We know the decryption worked if this file contains the exact same text as the original infile.txt.
Voila! We have successfully encrypted and decrypted a file in Python using TwoFish. Word of caution though, this is only an example. In practice you should absolutely use stronger and more robust means to encrypt your data, along with a stronger password. Use this code at your own risk! This was for demonstration purposes only.
Check out our Python AES Encryption Tutorial. Thanks for reading!