writing an AES cipher text to a JSON file - python

I used AES to excrypt a user's personal information and because I am storing it on the local machine.
from encrypting import *
from Crypto.Cipher import AES
import json
from testingjson import *
with open("users.json", 'r') as file:
users = json.load(file)
username = users["user_details"][0]["username"]
usernameObj = encryption(username)
nonce, cipherText, tag = usernameObj.encrypt()
plainText = usernameObj.decrypt(nonce, cipherText, tag)
print(f"Cipher text: {cipherText}")
if not plainText:
print("Message is corrupted")
else:
print(f"Plaintext: {plainText}")
with open("users.json", 'r') as file:
users = json.load(file)
password = users["user_details"][0]["password"]
passwordObj = encryption(password)
nonce1, cipherText1, tag1 = passwordObj.encrypt()
plainText1 = passwordObj.decrypt(nonce1, cipherText1, tag1)
print(f"Cipher text: {cipherText1}")
if not plainText1:
print("Message is corrupted")
else:
print(f"Plaintext: {plainText1}")
y = {"username":cipherText,
"email": "sharansaha07#gmail.com",
"password" : cipherText1
}
I tried converting bytes into a string but I can not convert the string back to bytes to decrypt it.

Related

fernet: cryptography.fernet.InvalidToken when decrypting a file

I'm trying to decrypt a string using fernet. My code (assume files already exist with pre-filled data):
import hashlib
import bcrypt
from cryptography.fernet import Fernet
import base64
#encrypting
############################################################
file = open('message.txt', 'r+')
message = file.read()
file.close()
password = input("Enter password: ")
file = open('passsalt.txt', 'r+')
salt = file.read()
file.close()
passwordnhash = str(password) + str(salt)
passwordnhash = passwordnhash.encode('utf-8')
hash = hashlib.sha256(passwordnhash).digest()
key = base64.urlsafe_b64encode(hash)
fernet = Fernet(key)
encMessage = fernet.encrypt(message.encode())
file = open('message.ivf', 'w+')
file.write(str(encMessage))
file.close()
############################################################
#decrypting
file = open('message.ivf', 'r+')
token = file.read()
file.close()
token = token.encode('utf-8')
file = open('passsalt.txt', 'r+')
salt = file.read()
file.close()
passwordnhash = str(password) + str(salt)
passwordnhash = passwordnhash.encode('utf-8')
hash = hashlib.sha256(passwordnhash).digest()
key = base64.urlsafe_b64encode(hash)
fernet = Fernet(key)
#token = fernet.encrypt(message)
d = fernet.decrypt(token)
print(d)
This returns the error
cryptography.fernet.InvalidToken
While decrypting. I'm unsure on what to do. I have viewed many questions but none have a fix for me. Links:
Stack Overflow question 1
Stack Overflow question 2
Stack Overflow question 3
Thanks in advance

How do i encrypt and decrypt files with PyCryptodome? (RSA)

I'm trying to encrypt and decrypt a file with PyCryptodome but without success. I can encrypt strings and data just fine but when trying to encrypt files it fails. I have 2 problems, first is that I can't encrypt larger strings. Witch i tried to solve by reading the file with a buffer. Second is that when I try to encrypt it as smaller buffers it just gives me an error "raise ValueError("Ciphertext with incorrect length.")"
My code looks like this:
from Crypto.Cipher import PKCS1_OAEP
import binascii
import ast
file_to_encrypt = "file_example_MP3_700KB.mp3"
buffer_size = 65536 # 64kb
input_file = open(file_to_encrypt, "rb")
output_file = open(file_to_encrypt + ".encrypted", "wb")
# Import keys
pub = open("publickey.txt", "rb")
pubKey = RSA.importKey(pub.read())
pub.close()
priv = open("privatekey.txt", "rb")
keyPair = RSA.importKey(priv.read())
priv.close()
# --------------------------------------------------------------
# Encrypt
encryptor = PKCS1_OAEP.new(pubKey)
buffer = input_file.read(buffer_size)
while len(buffer) > 0:
encrypted = encryptor.encrypt(buffer)
output_file.write(encrypted)
buffer = input_file.read(buffer_size)
input_file.close()
output_file.close()
# --------------------------------------------------------------
input_file = open(file_to_encrypt + ".encrypted", "rb")
output_file = open(file_to_encrypt + ".decrypted", "wb")
# Decrypt
decryptor = PKCS1_OAEP.new(keyPair)
buffer = input_file.read(buffer_size)
while len(buffer) > 0:
decrypted = decryptor.decrypt(ast.literal_eval(str(buffer)))
output_file.write(decrypted)
buffer = input_file.read(buffer_size)
input_file.close()
output_file.close()
# --------------------------------------------------------------
And generating the keys looks like this:
from Crypto.Cipher import PKCS1_OAEP
import binascii
import ast
# key generation
keyPair = RSA.generate(3072*2)
pubKey = keyPair.publickey()
# --------------------------------------------------------------
# Export keys
pub = open("publickey.txt", "wb")
pub.write(pubKey.exportKey('PEM'))
pub.close()
priv = open("privatekey.txt", "wb")
priv.write(keyPair.exportKey('PEM'))
priv.close()
# --------------------------------------------------------------
# Import keys
pub = open("publickey.txt", "rb")
pubKey = RSA.importKey(pub.read())
pub.close()
priv = open("privatekey.txt", "rb")
keyPair = RSA.importKey(priv.read())
priv.close()
# --------------------------------------------------------------
# encryption
msg = '550011'
encryptor = PKCS1_OAEP.new(pubKey)
encrypted = encryptor.encrypt(msg.encode())
# --------------------------------------------------------------
# decryption
decryptor = PKCS1_OAEP.new(keyPair)
decrypted = str(decryptor.decrypt(ast.literal_eval(str(encrypted))))[2:-1]
# --------------------------------------------------------------
print("Encrypted:", binascii.hexlify(encrypted))
print("Decrypted:", decrypted)
if msg == decrypted:
print("PASSED!")
else:
print("FAILED!")
Changing buffer_size fixes the first problem (that the data I'm trying to encrypt is too large.)
But I still can't decrypt my file after encrypting it.
Generating and importing keys works just fine. And encrypting and decrypting with them works just fine as well. As long as I'm only encrypting small strings and not files.

How to decrypt config.ini file keeping its original (before encyrpt) format and extension (Python - cryptography fernet)

Here is my code to encrypt the config.ini file which has sql connection details (username and pw) and some file paths.
from cryptography.fernet import Fernet
key = Fernet.generate_key()
i_file = 'conf.ini'
o_file = 'Conf_encry.ini'
with open(i_file,'rb') as f:
data = f.read()
fernet = Fernet(key)
encrypt = fernet.encrypt(data)
with open(o_file,'wb') as f:
f.write(encrypt)
print(key)
This will encrypt my file to Conf_encry.ini
And this is my code to decrypt the Conf_encry.ini file
from cryptography.fernet import Fernet
k_file = 'key.txt'
i_file = 'Conf_encry.ini'
with open(k_file, 'rb') as k:
key = k.read()
with open(i_file, 'rb') as f:
data = f.read()
fernet = Fernet(key)
decry = fernet.decrypt(data)
print(decry)
But problem is after decrypting the i_file its getting converted into usual txt file with lots of \r , \n and spaces. And that's why code (configparser) which reads this conf file as dict gives an error
# Original Configuration file before encrypt
[ABC]
host= a01
port = 1234
database = DB_1
user = DB_u_1
password = DB_p_1
[XYZ]
host = b01
database = DB_2
[URLList]
U1 = http://findbest.com
U2 = http://findall.com
[FPath]
filepath1 = r1.csv
# File after decrypting
b'[ABC]\r\nhost= a01 \r\nport = 1234\r\ndatabase = DB_1\r\nuser = DB_u_1\r\npassword = DB_p_1\r\n\r\n[XYZ]\r\nhost = b01 \r\ndatabase = DB_2\r\n\r\n[URLList]\r\nU1 = http://findbest.com\r\nU2 = http://findall.com\r\n\r\n[FPath]\r\nfilepath1 = r1.csv'
Any clue to resolve this?
Solution was simple. We can just write decrypted output to some file again
with open(o_file,'wb') as f:
f.write(decry)
Thanks for the explanation President James K. Polk

pycrypto encrypt/decrypt, losing part of encrypted string when decrypting

I am trying to encrypt/decrypt with pycrypto in python. for the most part things have worked smooth but I am getting an odd problem when decrypting data.I have tried to encrypt/decrypt some jpgs for testing and although they encrypt/decrypt without issue, the decrypted files cannot be opened/are corrupted. To try to find the problem I saved a textfile with a random sentence similar to "test this file for integrity blah blah blah" and it decrypts correctly only after ".... integrity blah blah blah", everything before integrity is still in garbled characters. I'm not that knowledgable on AES, but im assuming that this is an encoding/decoding or padding error.
Here is my code:
#encryption
iv = Random.new().read( AES.block_size)
filePath = input("Path to file for encryption: ")
selFile = open(filePath, 'rb')
getBytes = bytes(selFile.read())
encPW = input("Enter password: ")
hashpw = hashlib.sha256(encPW.encode('UTF-8').digest())
destination = input("Destination path for encrypted file: ")
aes = AES.new(hashpw, AES.Mode_CFB, iv)
encFile = base65.b64encode(aes.encrypt(getBytes))
writetofile = open(destination, 'wb')
writetofile.write(encFile)
writetofile.close()
print("Encryption successful")
#Decryption
iv = Random.new().read( AES.block_size)
filePath = input("Path to file for decryption: ")
selFile = open(filePath, 'rb')
getBytes = bytes(selFile.read())
decPW = input("Enter password: ")
hashdecpw = hashlib.sha256(encPW.encode('UTF-8').digest())
destination = input("Destination path for decrypted file: ")
aes = AES.new(hashdecpw, AES.Mode_CFB, iv)
decFile = aes.decrypt(getBytes)
writetofile = open(destination, 'wb')
writetofile.write(decFile)
writetofile.close()
print("Decryption successful")
Any ideas on what could be causing the loss of the first characters, and preventing me from encrypting/decrypting files correctly?
You have at least three issues:
You probably mean hashlib.sha256(encPW.encode('UTF-8')).digest() instead of hashlib.sha256(encPW.encode('UTF-8').digest()) (the closing brace is at the wrong position)
You're encoding the ciphertext with Base64 before writing it to a file. You've forgot to decode it after reading it back from the file before decrypting it. For example:
getBytes = base64.b64decode(bytes(selFile.read()))
This is the big one: You need the exact same IV during the decryption that you've used for encryption. The IV is not secret, but it needs to be unique for every encryption that you've done with the same key. Commonly the IV is written in front of the ciphertext and read back for decryption.
#encryption
encFile = base64.b64encode(iv + aes.encrypt(getBytes))
#decryption
getBytes = base64.b64decode(bytes(selFile.read()))
iv = getBytes[:16]
aes = AES.new(hashdecpw, AES.Mode_CFB, iv)
decFile = aes.decrypt(getBytes[16:])
You're generating a new IV for encryption and decryption seperately, which comes to yield such problems. Here's what I recommend doing:
def encrypt(inpath, outpath, password):
iv = Random.new().read(AES.block_size)
with open(inpath, "rb") as f:
contents = f.read()
# A context manager automatically calls f.close()
key = pbkdf2.crypt(password, "")
# See notes
aes = AES.new(key, AES.Mode_CFB, iv)
encrypted = aes.encrypt(contents)
with open(outpath, "wb") as f:
f.write(iv + b":")
f.write(encrypted)
print("Encryption successful")
def decrypt(inpath, outpath, password):
with open(inpath, "rb") as f:
contents = f.read()
iv, encrypted = contents.split(b":")
key = pbkdf2.crypt(password, "")
aes = AES.new(key, AES.Mode_CFB, iv)
decrypted = aes.decrypt(contents)
with open(outpath, "wb") as f:
f.write(decrypted)
print("Decryption successful")
Some notes:
An IV is not meant to be secret, so it can be randomly generated once and then written to a file to be used later for decryption (as shown in this example)
A hashing algorithm is not strong enough for deriving keys, which is why there are special tools called key derivation algorithms (like PBKDF2 in python). Use those instead!
I have not tested this code myself, so it may not work properly.

RSA encryption and decryption in Python

I need help using RSA encryption and decryption in Python.
I am creating a private/public key pair, encrypting a message with keys and writing message to a file. Then I am reading ciphertext from file and decrypting text using key.
I am having trouble with the decryption portion. As you can see in my code below, when I put in decrypted = key.decrypt(message) that the program works, yet the decrypted message is encrypted again. It seems like it is not reading the ciphertext from the file.
Can anyone help me write this code so decryption reads ciphertext from file and then uses key to decrypt ciphertext?
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate public and private keys
publickey = key.publickey # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print 'encrypted message:', encrypted #ciphertext
f = open ('encryption.txt', 'w'w)
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open ('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(message)
print 'decrypted', decrypted
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
In order to make it work you need to convert key from str to tuple before decryption(ast.literal_eval function). Here is fixed code:
import Crypto
from Crypto.PublicKey import RSA
from Crypto import Random
import ast
random_generator = Random.new().read
key = RSA.generate(1024, random_generator) #generate pub and priv key
publickey = key.publickey() # pub key export for exchange
encrypted = publickey.encrypt('encrypt this message', 32)
#message to encrypt is in the above line 'encrypt this message'
print('encrypted message:', encrypted) #ciphertext
f = open ('encryption.txt', 'w')
f.write(str(encrypted)) #write ciphertext to file
f.close()
#decrypted code below
f = open('encryption.txt', 'r')
message = f.read()
decrypted = key.decrypt(ast.literal_eval(str(encrypted)))
print('decrypted', decrypted)
f = open ('encryption.txt', 'w')
f.write(str(message))
f.write(str(decrypted))
f.close()
PKCS#1 OAEP is an asymmetric cipher based on RSA and the OAEP padding
from Crypto.PublicKey import RSA
from Crypto import Random
from Crypto.Cipher import PKCS1_OAEP
def rsa_encrypt_decrypt():
key = RSA.generate(2048)
private_key = key.export_key('PEM')
public_key = key.publickey().exportKey('PEM')
message = input('plain text for RSA encryption and decryption:')
message = str.encode(message)
rsa_public_key = RSA.importKey(public_key)
rsa_public_key = PKCS1_OAEP.new(rsa_public_key)
encrypted_text = rsa_public_key.encrypt(message)
#encrypted_text = b64encode(encrypted_text)
print('your encrypted_text is : {}'.format(encrypted_text))
rsa_private_key = RSA.importKey(private_key)
rsa_private_key = PKCS1_OAEP.new(rsa_private_key)
decrypted_text = rsa_private_key.decrypt(encrypted_text)
print('your decrypted_text is : {}'.format(decrypted_text))
# coding: utf-8
from __future__ import unicode_literals
import base64
import os
import six
from Crypto import Random
from Crypto.PublicKey import RSA
class PublicKeyFileExists(Exception): pass
class RSAEncryption(object):
PRIVATE_KEY_FILE_PATH = None
PUBLIC_KEY_FILE_PATH = None
def encrypt(self, message):
public_key = self._get_public_key()
public_key_object = RSA.importKey(public_key)
random_phrase = 'M'
encrypted_message = public_key_object.encrypt(self._to_format_for_encrypt(message), random_phrase)[0]
# use base64 for save encrypted_message in database without problems with encoding
return base64.b64encode(encrypted_message)
def decrypt(self, encoded_encrypted_message):
encrypted_message = base64.b64decode(encoded_encrypted_message)
private_key = self._get_private_key()
private_key_object = RSA.importKey(private_key)
decrypted_message = private_key_object.decrypt(encrypted_message)
return six.text_type(decrypted_message, encoding='utf8')
def generate_keys(self):
"""Be careful rewrite your keys"""
random_generator = Random.new().read
key = RSA.generate(1024, random_generator)
private, public = key.exportKey(), key.publickey().exportKey()
if os.path.isfile(self.PUBLIC_KEY_FILE_PATH):
raise PublicKeyFileExists('Файл с публичным ключом существует. Удалите ключ')
self.create_directories()
with open(self.PRIVATE_KEY_FILE_PATH, 'w') as private_file:
private_file.write(private)
with open(self.PUBLIC_KEY_FILE_PATH, 'w') as public_file:
public_file.write(public)
return private, public
def create_directories(self, for_private_key=True):
public_key_path = self.PUBLIC_KEY_FILE_PATH.rsplit('/', 1)
if not os.path.exists(public_key_path):
os.makedirs(public_key_path)
if for_private_key:
private_key_path = self.PRIVATE_KEY_FILE_PATH.rsplit('/', 1)
if not os.path.exists(private_key_path):
os.makedirs(private_key_path)
def _get_public_key(self):
"""run generate_keys() before get keys """
with open(self.PUBLIC_KEY_FILE_PATH, 'r') as _file:
return _file.read()
def _get_private_key(self):
"""run generate_keys() before get keys """
with open(self.PRIVATE_KEY_FILE_PATH, 'r') as _file:
return _file.read()
def _to_format_for_encrypt(self, value):
if isinstance(value, int):
return six.binary_type(value)
for str_type in six.string_types:
if isinstance(value, str_type):
return value.encode('utf8')
if isinstance(value, six.binary_type):
return value
And use
KEYS_DIRECTORY = settings.SURVEY_DIR_WITH_ENCRYPTED_KEYS
class TestingEncryption(RSAEncryption):
PRIVATE_KEY_FILE_PATH = KEYS_DIRECTORY + 'private.key'
PUBLIC_KEY_FILE_PATH = KEYS_DIRECTORY + 'public.key'
# django/flask
from django.core.files import File
class ProductionEncryption(RSAEncryption):
PUBLIC_KEY_FILE_PATH = settings.SURVEY_DIR_WITH_ENCRYPTED_KEYS + 'public.key'
def _get_private_key(self):
"""run generate_keys() before get keys """
from corportal.utils import global_elements
private_key = global_elements.request.FILES.get('private_key')
if private_key:
private_key_file = File(private_key)
return private_key_file.read()
message = 'Hello мой friend'
encrypted_mes = ProductionEncryption().encrypt(message)
decrypted_mes = ProductionEncryption().decrypt(message)
Here is my implementation for python 3 and pycrypto
from Crypto.PublicKey import RSA
key = RSA.generate(4096)
f = open('/home/john/Desktop/my_rsa_public.pem', 'wb')
f.write(key.publickey().exportKey('PEM'))
f.close()
f = open('/home/john/Desktop/my_rsa_private.pem', 'wb')
f.write(key.exportKey('PEM'))
f.close()
f = open('/home/john/Desktop/my_rsa_public.pem', 'rb')
f1 = open('/home/john/Desktop/my_rsa_private.pem', 'rb')
key = RSA.importKey(f.read())
key1 = RSA.importKey(f1.read())
x = key.encrypt(b"dddddd",32)
print(x)
z = key1.decrypt(x)
print(z)
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
secret_message = b'ATTACK AT DAWN'
### First, make a key and save it
key = RSA.generate(2048)
with open( 'mykey.pem', 'wb' ) as f:
f.write( key.exportKey( 'PEM' ))
### Then use key to encrypt and save our message
public_crypter = PKCS1_OAEP.new( key )
enc_data = public_crypter.encrypt( secret_message )
with open( 'encrypted.txt', 'wb' ) as f:
f.write( enc_data )
### And later on load and decode
with open( 'mykey.pem', 'r' ) as f:
key = RSA.importKey( f.read() )
with open( 'encrypted.txt', 'rb' ) as f:
encrypted_data = f.read()
public_crypter = PKCS1_OAEP.new( key )
decrypted_data = public_crypter.decrypt( encrypted_data )
You can use simple way for genarate RSA . Use rsa library
pip install rsa
Watch out using Crypto!!!
It is a wonderful library but it has an issue in python3.8 'cause from the library time was removed the attribute clock(). To fix it just modify the source in /usr/lib/python3.8/site-packages/Crypto/Random/_UserFriendlyRNG.pyline 77 changing t = time.clock() int t = time.perf_counter()

Categories

Resources