python decrypt AES - python

This is my code:
from Crypto.Cipher import AES
from Crypto import Random
import base64
Plain_text = "Text"
random = Random.new()
IV = random.read(AES.block_size)
KEY = base64.b64encode(random.read(AES.key_size[0]))
Cipher = AES.AESCipher(KEY, AES.MODE_CFB, IV)
print "Key:", KEY
Encrypting = Cipher.encrypt(Plain_text)
print "Encrypting:\n",Encrypting
#KEY2 = base64.b64decode(KEY)
#IV2 = random.read(AES.block_size)
#print "KEY2:", KEY2
Cipher2 = AES.AESCipher(base64.b64decode(KEY), AES.MODE_CFB, IV)
Decrypting = Cipher2.decrypt(Encrypting)
print "Decrypting:\n", Decrypting
Script output:
Output is:
Key: VYy9unePPuKiQHwVcqkJzA==
Encrypting:
�F!C
Decrypting:
���
Why script can not decrypt?
OS = Ubuntu 16.04
Python Version = 2.7.12

The key supplied to the AES function should be in binary format. In your case you are encoding the key to base-64 first. In the encryption, it seems that you accidentally use this encoded string as the key.
Fixed code snippet:
from Crypto.Cipher import AES
from Crypto import Random
import base64
plaintext = "Text"
random = Random.new()
iv = random.read(AES.block_size)
key = random.read(AES.key_size[0])
cipher = AES.AESCipher(key, AES.MODE_CFB, iv)
key_b64 = base64.b64encode(key)
print ("Key: {}".format(key_b64))
ciphertext = cipher.encrypt(plaintext)
print("Encrypting: {}".format(ciphertext))

Related

Python Incorrect AES key length despite passing the a 32 bytes bytearray

I have a specific AES key that I have to work with which is 10h,10h,10h,"A",10h,10h,10h,"AAA",10h,10h,10h,10h,10h,10h,10h,10h,10h,"A",10h,"A",10h,10h,"AA",10h,"A",10h,"A",10h,"A"
I have to use this key to encrypt a message. In python I covert it to "\x10,\x10,\x10,A,\x10,\x10,\x10,AAA,\x10,\x10,\x10,\x10,\x10,\x10,\x10,\x10,\x10,A,\x10,A,\x10,\x10,AA,\x10,A,\x10,A,\x10,A" but I get ValueError: Incorrect AES key length (60 bytes).
I tried encoding the key in a different way like key = bytearray("\x10,\x10,\x10,A,\x10,\x10,\x10,AAA,\x10,\x10,\x10,\x10,\x10,\x10,\x10,\x10,\x10,A,\x10,A,\x10,\x10,AA,\x10,A,\x10,A,\x10,A".encode('utf-8')) but I still get a same key length error.
What can I do in this case?
This is my code:
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
msg = b"<input><type=\"update\"/></input>"
key = bytearray("\x10,\x10,\x10,A,\x10,\x10,\x10,AAA,\x10,\x10,\x10,\x10,\x10,\x10,\x10,\x10,\x10,A,\x10,A,\x10,\x10,AA,\x10,A,\x10,A,\x10,A".encode('utf-8'))
print(key)
cipher = AES.new(key, AES.MODE_GCM)
encrypted_msg = cipher.encrypt(msg)
print(encrypted_msg)
How about using bytes instead?
#pip install pycryptodome
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
msg = b"<input><type=\"update\"/></input>"
key = bytearray(b"\x10\x10\x10A\x10\x10\x10AAA\x10\x10\x10\x10\x10\x10\x10\x10\x10A\x10A\x10\x10AA\x10A\x10A\x10A")
print(key)
cipher = AES.new(key, AES.MODE_GCM)
encrypted_msg = cipher.encrypt(msg)
print(encrypted_msg)
This seems to be working.
Please note that you can also use bytes.fromhex, which is more readable
#pip install pycryptodome
from Crypto.Cipher import AES
msg = b"<input><type=\"update\"/></input>"
key = bytearray(bytes.fromhex("1010104110101041414110101010101010101041104110104141104110411041"))
print(key)
cipher = AES.new(key, AES.MODE_GCM)
encrypted_msg = cipher.encrypt(msg)
print(encrypted_msg)
Now, the good question: why does this happen?
Well, utf-8 encodes the non ascii characters differently, pseudocode:
'\x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf '.encode()
b'\xc2\x80\xc2\x81\xc2\x82\xc2\x83\xc2\x84\xc2\x85\xc2\x86\xc2\x87\xc2\x88\xc2\x89\xc2\x8a\xc2\x8b\xc2\x8c\xc2\x8d\xc2\x8e\xc2\x8f\xc2\x90\xc2\x91\xc2\x92\xc2\x93\xc2\x94\xc2\x95\xc2\x96\xc2\x97\xc2\x98\xc2\x99\xc2\x9a\xc2\x9b\xc2\x9c\xc2\x9d\xc2\x9e\xc2\x9f\xc2\xa0\xc2\xa1\xc2\xa2\xc2\xa3\xc2\xa4\xc2\xa5\xc2\xa6\xc2\xa7\xc2\xa8\xc2\xa9\xc2\xaa\xc2\xab\xc2\xac\xc2\xad\xc2\xae\xc2\xaf\xc2\xb0\xc2\xb1\xc2\xb2\xc2\xb3\xc2\xb4\xc2\xb5\xc2\xb6\xc2\xb7\xc2\xb8\xc2\xb9\xc2\xba\xc2\xbb\xc2\xbc\xc2\xbd\xc2\xbe\xc2\xbf'

Python3 Incorrect AES key length (256 bytes)

I want to write a script that encrypts the content of a text file (key.k3y). When i execute it, i get the error: Incorrect AES key length (256 Bytes). Obviously that should not be invalid for AES. here is my code:
import base64
import pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
# Set a password and encode it (to Byte type)
password_provided = "NHW!He2-vxxYWF7va23LzjnqFTyvP#dAPGHChXmmSY4YYzJ*HDX_HzRZ-7M8c*2t" #64chars
password = password_provided.encode()
print(len(password))
# Set the hashing parameters for the pw hashing
salt = b'\x08\xfc\xe4e\x89\xc2\xa8\xfe\xe2UsS\xbb#\xbe\x8d\xec\x9b\xb1\xf9\x9d]\xa6D?\xc7\x89\x1b\xdf\xb7\xa3\x19m\x13\xca"i\xbbd\x07b\x8al\x80#xm>Coa\xcc\x88X\xc7#\x99\xd5\xf8\xcf\x86\x04\xbf9'
kdf = PBKDF2HMAC(
algorithm=hashes.SHA512(),
length=192,
salt=salt,
iterations=100000,
backend=default_backend()
)
# Hash and encode the key with SHA512 and base64
key = base64.urlsafe_b64encode(kdf.derive(password))
print("The key (hashed pw) is: ")
print(len(key))
# Get the message or, as in this case, the content of the file key.k3y
messagefile = open('key.k3y', 'rb')
data = messagefile.read()
messagefile.close()
# Encrypting the message with AES, mode CBC
cipher = AES.new(key, AES.MODE_CBC)
encdata = cipher.encrypt(pad(data, AES.block_size))
print(encdata)

AES encrypt in Cryptojs, decrypt in Pycrypto

I've tried md5 and sha256 when converting key to 16 bit but after encrypting, the result doesnt work if I'm going to validate it via third party decryptor https://www.browserling.com/tools/aes-decrypt
My goal is to decrypt the js version using python.
Added another link for js version.
https://jsfiddle.net/korvacs/4obfkxm7/17/
Python code:
from Crypto.Cipher import AES
from Crypto import Random
import hashlib
from base64 import b64encode
key = "lazydog".encode("utf-8")
key = hashlib.sha256(key).digest()
iv = Random.new().read(AES.block_size)
cipher = AES.new(key, AES.MODE_CBC, iv)
msg = iv + cipher.encrypt('Attack at dawn')
print(b64encode(msg).decode('utf-8'))
Can someone help me? I'm not really good in encryptions.
I am using PBKDF2 to generate IV and key. This is good practice. We don't need to transfer IV:
Javascript:
let password = "lazydog";
let salt = "salt";
let iterations = 128;
let bytes = CryptoJS.PBKDF2(password, salt, { keySize: 48, iterations: iterations });
let iv = CryptoJS.enc.Hex.parse(bytes.toString().slice(0, 32));
let key = CryptoJS.enc.Hex.parse(bytes.toString().slice(32, 96));
let ciphertext = CryptoJS.AES.encrypt("Attack at dawn", key, { iv: iv });
console.log(ciphertext.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.js"></script>
Python:
from base64 import b64decode
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
data = b64decode("ibirgCQu8TwtJOaKKtMLxw==")
bytes = PBKDF2("lazydog".encode("utf-8"), "salt".encode("utf-8"), 48, 128)
iv = bytes[0:16]
key = bytes[16:48]
cipher = AES.new(key, AES.MODE_CBC, iv)
text = cipher.decrypt(data)
text = text[:-text[-1]].decode("utf-8")

Trouble with AES Cryptography (specifically encrypting with CryptoSwift and decrypting with PyCryptodome

I am currently trying to use AES cryptography to encrypt and decrypt a string that always has a length of 9 characters. What I am trying to do is to encrypt the string in swift and then decrypt that encrypted string in python. I am using AES encryption with CryptoSwift and decrypting with PyCryptodome.
This is what my function in swift looks like:
import CryptoSwift
func crypto_testing() {
print("Cryptography!")
let ivString = "0000000000000000"
let keyString = "This is a key123"
let key = [UInt8](keyString.utf8)
let iv = [UInt8](ivString.utf8)
let stringToEncrypt = "123456789"
let enc = try! aesEncrypt(stringToEncrypt: stringToEncrypt, key: key, iv: iv)
print("ENCRYPT:",enc)
}
func aesEncrypt(stringToEncrypt: String, key: Array<UInt8>, iv: Array<UInt8>) throws -> String {
let data = stringToEncrypt.data(using: String.Encoding.utf8)
let encrypted = try AES(key: key, blockMode: CFB(iv: iv), padding: .noPadding).encrypt((data?.bytes)!)
return encrypted.toHexString() //result
}
The result I get from running the crypto_testing function is:
Cryptography!
ENCRYPT: 5d02105a49e55d2ff7
Furthermore, this is what my decryption function looks like in python:
import binascii
from Crypto.Cipher import AES
KEY = b'This is a key123'
IV = b'0000000000000000'
MODE = AES.MODE_CFB
def decrypt(key, iv, encrypted_text):
aes = AES.new(key, MODE, iv)
encrypted_text_bytes = binascii.a2b_hex(encrypted_text)
decrypted_text = aes.decrypt(encrypted_text_bytes)
return decrypted_text
decrypted_text = decrypt(KEY, IV, encrypted_text)
print(decrypted_text)
And the result from plugging in the encrypted message into the decrypt function like so:
>>> decrypt(b'This is a key123', b'0000000000000000', '5d02105a49e55d2ff7')
b'1%\xdc\xc8\xa0\r\xbd\xb8\xf0'
If anyone has any clue as to what is going wrong here that would be a great help.
Try this:
let stringToEncrypt = "123456789"
var aes: AES
var encrypted: [UInt8]
do {
aes = try AES(key: key, blockMode: CBC(iv: iv), padding: . noPadding)
encrypted = try aes.encrypt(stringToEncrypt.bytes)
}
let base64Encypted = encrypted.toBase64()```

Unable to decrypt using Blowfish

I am using Python3 and PyCrypto module for Blowfish Algorithm. I am able to encrypt when i give the key and plaintext via command line but i am unable to decrypt. However, the code is working correctly if I use it in Python Interpreter.
ENCRYPTION (blowfish_encr.py)
from Crypto.Cipher import Blowfish
from Crypto import Random
from struct import pack
import sys
bs = Blowfish.block_size
key = sys.argv[1].encode()
iv = Random.new().read(bs)
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
plaintext = sys.argv[2].encode()
plen = bs - divmod(len(plaintext),bs)[1]
padding = [plen]*plen
padding = pack('b'*plen, *padding)
msg = iv + cipher.encrypt(plaintext + padding)
print(msg)
DECRYPTION (blowfish_decr.py)
from Crypto.Cipher import Blowfish
from struct import pack
import sys
bs = Blowfish.block_size
ciphertext = sys.argv[2].encode()
key = sys.argv[1].encode()
iv = ciphertext[:bs]
ciphertext = ciphertext[bs:]
cipher = Blowfish.new(key, Blowfish.MODE_CBC, iv)
msg = cipher.decrypt(ciphertext)
last_byte = msg[-1]
msg = msg[:- (last_byte if type(last_byte) is int else ord(last_byte))]
print(repr(msg))
OUTPUT:
$python3 blowfish_encr.py key 'Test it!'
b'\xf8\x1eK)\x81?\xa2\x88\x01\x16\x8e\xdc\xe5\xb9\xd8_K\xce\x03\xe4\x88g\xf8\xa1'
$python3 blowfish_decr.py key '\xf8\x1eK)\x81?\xa2\x88\x01\x16\x8e\xdc\xe5\xb9\xd8_K\xce\x03\xe4\x88g\xf8\xa1'
File "blowfish_decr.py", line 12, in <module>
msg = cipher.decrypt(ciphertext)
File "/usr/lib/python3/dist-packages/Crypto/Cipher/blockalgo.py", line 295, in decrypt
return self._cipher.decrypt(ciphertext)
ValueError: Input strings must be a multiple of 8 in length
How to get it decrypted ? I know the error is because when I input the encoded text as a string it converts all the \ to \\ , and when I try sys.argv[2].encode().replace('\\','\') it it doesn't work because \' is a string literal.
How to get it done using the command line argument?

Categories