I am coding an encryption library that allows you generate either symmetric or asymmetric key/key pair and use it within Either of these 4 classes: TextEncA
, TextEncS
, ImageEncA
and ImageEncS
. The code looks to be syntactically correct however while testing the code I am getting an error with the testing of the TextEncS
class using unittest - namely an assertion error.
Here is the code for testing the TextEncS
class:
class TestTextEncS(unittest.TestCase):
def setUp(self):
self.message = b"This is a test message"
self.key = tienc.generate_key_s()
self.text_enc = tienc.TextEncS(self.key)
def test_encrypt_decrypt(self):
ciphertext, tag = self.text_enc.encrypt(self.message)
result = self.text_enc.decrypt(ciphertext, tag)
self.assertEqual(self.message, result)
def test_decrypt_failure(self):
wrong_key = os.urandom(32)
ciphertext, tag = self.text_enc.encrypt(self.message)
self.assertRaises(Exception, self.text_enc.decrypt, ciphertext, tag, wrong_key)
Here is the code for the TextEncS
class itself:
class TextEncS:
""" symmetric text encryption """
def __init__(self, key):
self.key = key
def encrypt(self, plaintext):
cipher = AES.new(self.key, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
return ciphertext, tag
def decrypt(self, ciphertext, tag):
cipher = AES.new(self.key, AES.MODE_EAX, tag)
return cipher.decrypt(ciphertext)
The key for the symmetric keys are generated as follows:
def generate_key_s():
key = os.urandom(32)
return key
And the error as seen in the terminal is presented like this:
======================================================================
FAIL: test_encrypt_decrypt (Test_TIENC.TestTextEncS)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\Users\*****\Desktop\tienc\tests\Test_TIENC.py", line 38, in test_encrypt_decrypt
self.assertEqual(self.message, result)
AssertionError: b'This is a test message' != b'\x1c\x83\x8cJ\xa7\x1b\x02g\xfet\xf1XOP\x9c\xa6\xa8\x99k\xabC\x01'
----------------------------------------------------------------------
How would I go about solving this issue and what should I try?
I have tried changing the code about have read up on the documentation however nothing I have tried seems to have worked.
CodePudding user response:
Modifications to your class TextEncS
You have to modify your production code as below:
from Cryptodome.Cipher import AES
class TextEncS:
""" symmetric text encryption """
def __init__(self, key):
self.key = key
def encrypt(self, plaintext):
cipher = AES.new(self.key, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(plaintext)
return ciphertext, tag, cipher.nonce
def decrypt(self, ciphertext, tag, nonce):
cipher = AES.new(self.key, AES.MODE_EAX, nonce)
data = cipher.decrypt_and_verify(ciphertext, tag)
return data
The modification are:
encrypt()
that return 3 values (I have addchiper.once
)decrypt()
that has 3 arguments (I have addonce
); furthermore the body ofdecrypt()
is a bit different from your code
In your question you have not include the import
. In my code the import is:
from Cryptodome.Cipher import AES
Modifications to your test code
The test code is modified accordly (see the comments inside the code):
class TestTextEncS(unittest.TestCase):
def setUp(self):
self.message = b"This is a test message"
self.key = tienc.generate_key_s()
self.text_enc = tienc.TextEncS(self.key)
def test_encrypt_decrypt(self):
# encrypt() return ---> ciphertext, tag, nonce
ciphertext, tag, nonce = self.text_enc.encrypt(self.message)
# pass 3 arguments to decrypt()
result = self.text_enc.decrypt(ciphertext, tag, nonce)
self.assertEqual(self.message, result)
def test_decrypt_failure(self):
# encrypt() return ---> ciphertext, tag, nonce
ciphertext, tag, nonce = self.text_enc.encrypt(self.message)
wrong_key = os.urandom(32)
# create a new instance the class TextEncS with the wrong key
self.text_enc = tienc.TextEncS(wrong_key)
# change a bit the test
with self.assertRaises(Exception):
self.text_enc.decrypt(ciphertext, tag, nonce)
Useful links
For details about Encrypt data with AES see this documentations.
To know why I have use Cryptodome
instead Crypto
module see this link.