0

I'm trying to decrypt a value which I'm reading from a CSV file. (I've encrypted the value of an integer and wrote it to a CSV file separately).

Encryption:

from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import scrypt
from Crypto.Util.Padding import pad,unpad
from random import randrange
from Crypto.Hash import SHA256
import binascii
import pandas as pd
import numpy as np
import hashlib

BUFFER_SIZE = 1024 * 1024  # The size in bytes that we read, encrypt and write to at once

password = 'QWERTY123' 
salt = 'QWERTY123'  
print("Salt is created")
key = scrypt(password, salt, key_len=32, N=2**17, r=8, p=1)  # Generate a key using the password and salt
print("Key is created",key)

cipher = AES.new(key, AES.MODE_GCM) # Create a cipher object to encrypt data
nonce = cipher.nonce
print("Nonce is created")

print ("Key is :", type(key))
print ("Nonce is :", type(nonce))

val=100
plain_text =val.to_bytes(2, 'big')
print("Plaintext is ",plain_text)

cipher_decrypt= AES.new(key, AES.MODE_GCM, nonce=nonce)

cipher_text = cipher.encrypt(pad(plain_text,AES.block_size))
print("Encrypted text:", cipher_text)

The generated output is as follows:

Salt is created
Key is created b'\x1eev\xb1\x95,\xa7\xb2&Dk\x12\x88n\xcf\xe1\xe3\xda\xf13p\x8f;\x02>\x99\x82L+\x9a\x8a$'
Nonce is created
Key is : <class 'bytes'>
Nonce is : <class 'bytes'>
Plaintext is  b'\x00d'
Encrypted text: b'\x02(\x0bM\x00I\x07M\xc7J;\xdc\xe7h\xd5\x00'

I copy the value of encrypted text and paste it into a CSV file. The password and the salt are the same (I'm aware that this is not recommended) because the same key has to be generated for the decryption which is happening separately.

Decryption:

from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import scrypt
from Crypto.Util.Padding import pad,unpad
from random import randrange
from Crypto.Hash import SHA256
import binascii
import pandas as pd
import numpy as np
import hashlib
import ast

BUFFER_SIZE = 1024 * 1024  # The size in bytes that we read, encrypt and write to at once

password = 'QWERTY123' 
salt = 'QWERTY123'  
print("Salt is created")
key = scrypt(password, salt, key_len=32, N=2**17, r=8, p=1)  # Generate a key using the password and salt
print("Key is created",key)

cipher = AES.new(key,AES.MODE_GCM) # Create a cipher object to encrypt data
nonce = cipher.nonce
print("Nonce is created")

print ("Key is :", type(key))
print ("Nonce is :", type(nonce))

cipher_decrypt= AES.new(key, AES.MODE_GCM, nonce=nonce)

input_file = pd.read_csv('/path/random.csv')
encrypt_val=input_file.iat[0,1]
print("Remaining are",encrypt_val)
print(type(encrypt_val))

a=ast.literal_eval(encrypt_val)
print(a)
print(type(a))
text = unpad(cipher_decrypt.decrypt(a),AES.block_size)
print(text)
print(type(text))
b=ast.literal_eval(text)

This gives the following output:

Salt is created
Key is created b'\x1eev\xb1\x95,\xa7\xb2&Dk\x12\x88n\xcf\xe1\xe3\xda\xf13p\x8f;\x02>\x99\x82L+\x9a\x8a$'
Nonce is created
Key is : <class 'bytes'>
Nonce is : <class 'bytes'>
Remaining are b"H\x13\x0c\xa0J\x07\x98<QN])z'S\xdc"
<class 'str'>
b"H\x13\x0c\xa0J\x07\x98<QN])z'S\xdc"
<class 'bytes'>
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Untitled-2.ipynb Cell 1 in <module>
     36 print(a)
     37 print(type(a))
---> 38 text = unpad(cipher_decrypt.decrypt(a),AES.block_size)
     39 print(text)
     40 print(type(text))

File /opt/homebrew/lib/python3.9/site-packages/Crypto/Util/Padding.py:92, in unpad(padded_data, block_size, style)
     90 padding_len = bord(padded_data[-1])
     91 if padding_len<1 or padding_len>min(block_size, pdata_len):
---> 92     raise ValueError("Padding is incorrect.")
     93 if style == 'pkcs7':
     94     if padded_data[-padding_len:]!=bchr(padding_len)*padding_len:

ValueError: Padding is incorrect.
rishab ajain445
  • 155
  • 1
  • 10
  • 1
    Can you share the contents of the CSV file? What exactly are you placing in it and why doesn't it match the value of `cipher_text`? – chuckx Sep 06 '22 at 06:41
  • 2
    There are several issues here: Contrary to your code, 1. decryption must use the same nonce as encryption, 2. GCM does not require padding, (1. and 2. are probably causing the problem) and 3. GCM is executed with `encrypt_and_digest()` and `decrypt_and_verify()`, otherwise no authentication takes place and the added value of GCM is lost. – Topaco Sep 06 '22 at 06:43
  • @chuckx the csv contents just the encrypted value. Value b"H\x13\x0c\xa0J\x07\x98 – rishab ajain445 Sep 06 '22 at 06:47
  • 1
    Unfortunately with your testdata no repro is possible since the nonce is missing, thus share also the nonce (for encryption and decryption) to check if there is additionally an I/O issue. – Topaco Sep 06 '22 at 06:50
  • @Topaco I hardcoded the nonce in both encryption and decryption and removed padding- nonce = b'wo\x05\x98\x01\n&On\x7f\x91\x96\xe5T\xbd\x9e' and modified encryption value is - Encrypted text: b'*\x1a' . When I try to decrypt this with padding removed - the decrypted text is - (b'%\x15', 16) – rishab ajain445 Sep 06 '22 at 06:56
  • 2
    Maybe there is also an I/O issue. csv are basically text files, so the ciphertext should actually be Base64 encoded before storing (and Base64 decoded after loading). Post the updated code with the outputs, including both nonces, so that this can be checked. – Topaco Sep 06 '22 at 07:07
  • @Topaco Byte values cannot be encoded right? when I try to encode using base64 library, it says AttributeError Traceback (most recent call last) Untitled-1.ipynb Cell 1 in 37 cipher_text = cipher.encrypt(plain_text) 39 print("Encrypted text:", cipher_text) ---> 41 base64_bytes = cipher_text.encode("ascii") 42 print(base64_bytes) AttributeError: 'bytes' object has no attribute 'encode' – rishab ajain445 Sep 06 '22 at 07:16
  • 2
    Of course byte values can be Base64 encoded (that's what Base64 is for). Note that Base64 encoding is done with `base64.b64encode(...)`. – Topaco Sep 06 '22 at 07:28
  • 2
    I have the impression that several problems are mixed up. Actually, for the hardcoded nonce, the result should be the ciphertext b'\x99L': https://gchq.github.io/CyberChef/#recipe=AES_Encrypt(%7B'option':'Hex','string':'8cf50a2865f720e288752c20e91eab329fcf0c9433907c2dd083b58ff271eba5'%7D,%7B'option':'Hex','string':'776f0598010a264f6e7f9196e554bd9e'%7D,'GCM','Hex','Hex',%7B'option':'Hex','string':''%7D)&input=MDA2NA. Did you really use this nonce in the encryption? Post the updated code plus outputs to avoid misunderstandings. – Topaco Sep 06 '22 at 07:29
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/247812/discussion-between-rishab-ajain445-and-topaco). – rishab ajain445 Sep 06 '22 at 07:37
  • @Topaco Thank you so much for your help. Finally got it working with your help – rishab ajain445 Sep 06 '22 at 12:57

0 Answers0