def DecryptMethod(txt_to_decrypt, key):
#ct = txt_to_decrypt
f = open(txt_to_decrypt,'rb')
ct = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv)
pt = unpad(cipher.decrypt(ct), 16)
#decoded_txt = pt.decode()
print(pt)
return pt
testData = DecryptMethod("test1.enc",decrypted_key)
Within my tes1.enc the encrypted version of the text test1.
However, I am unable to decrypt. Everything was alright until
This part.
pt = unpad(cipher.decrypt(ct), 16)
The above part will constantly show the error:
TypeError: Object type <class 'str'> cannot be passed to C code
I've already checked multiple times, but this part constantly throws out this error.
Thank you in advance.
Plaintexts and ciphertexts (input/output) can only be bytes, bytearray or memoryview. In Python 3, you cannot pass strings. In Python 2, you cannot pass Unicode strings
You can convert the string to bytes like this:
b = bytes(mystring, 'utf-8')
For more information, read these docs
Related
This question is similar to this one here but if I put this into this code like so:
import base64
theone = input('Enter your plaintext: ')
encoded = str(base64.b64encode(theone))
encoded = base64.b64encode(encoded.encode('ascii'))
encoded = encoded[2:]
o = len(encoded)
o = o-1
encoded = encoded[:o]
print(encoded)
it raises this problem:
line 58, in b64encode
encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
And then if I remove this line of code:
encoded = base64.b64encode(encoded.encode('ascii'))
then it raises the same error. I'm not sure what to do from here and I would be grateful for any help.
You seem to be having problems with bytes and strings. The value returned by input is a string (str), but base64.b64encode expects bytes (bytes).
If you print a bytes instance you see something like
b'spam'
To remove the leading 'b' you need to decode back to a str.
To make your code work, pass bytes to base64.b64encode, and decode the result to print it.
>>> theone = input('Enter your plaintext: ')
Enter your plaintext: Hello World!
>>> encoded = base64.b64encode(theone.encode())
>>> encoded
b'SGVsbG8gV29ybGQh'
>>> print(encoded.decode())
SGVsbG8gV29ybGQh
I know where the problem is but I don't know how to fix it. The problem is with the padding. I have absolutely no idea about it and how it works. I tried searching online but nothing seemed to help. I am trying to implement this function to work with my website. The python encrypts and sends the data and PHP decrypts it.
Here's the actual code of my python:
from rijndael.cipher.crypt import new
from rijndael.cipher.blockcipher import MODE_CBC
import base64
PADDING = b'.'
def r_pad(payload, block_size=32):
return payload + (block_size - len(payload) % block_size) * PADDING
KEY = 'lkirwf897+22#bbtrm8814z5qq=498j5'
IV = '741952hheeyy66#cs!9hjv887mxx7#8y'
plain_text = "A padded string to BLOCKSIZE length."
rjn = new(KEY, MODE_CBC, IV, blocksize=32)
encd = rjn.encrypt(r_pad(plain_text))
data = base64.b64encode(encd)
print(data)
rjn = new(KEY, MODE_CBC, IV, blocksize=32)
data = base64.b64decode(data)
decd = rjn.decrypt(r_pad(data))
print (decd)
This is the output:
Dv0Y/AFXdFMlDrcldFCu8v5o9zAlLNgyM+vO+PFeSrqWdzP1S1cumviFiEjNAjz5njnMMC9lfxsBl71x5y+xCw==
A padded string to BLOCKSIZE length.............................Å¿:è°⌐┘n┤«╞Px╜:æC┬♣╬Q┤▼«U_♦â☻ìr
I need the output of the encrypted string to be something like this:
Dv0Y/AFXdFMlDrcldFCu8v5o9zAlLNgyM+vO+PFeSrpO8Ve82mdUcc4rkzp9afDYc75NmkSd4mdflt38kceOdA==
A padded string to BLOCKSIZE length
I tried to make RIJNDAEL256 function out of this code:
EncryptRJ256("lkirwf897+22#bbtrm8814z5qq=498j5", "741952hheeyy66#cs!9hjv887mxx7#8y", "A padded string to BLOCKSIZE length.")
Public Function EncryptRJ256(ByVal prm_key As String, ByVal prm_iv As String, ByVal prm_text_to_encrypt As String) As String
Dim s As String = prm_text_to_encrypt
Dim managed2 As New RijndaelManaged With {
.Padding = PaddingMode.Zeros,
.Mode = CipherMode.CBC,
.BlockSize = 256
}
Dim stream As New MemoryStream
Dim stream2 As New CryptoStream(stream, managed2.CreateEncryptor(Encoding.ASCII.GetBytes(prm_key), Encoding.ASCII.GetBytes(prm_iv)), CryptoStreamMode.Write)
Dim bytes As Byte() = Encoding.ASCII.GetBytes(s)
stream2.Write(bytes, 0, bytes.Length)
stream2.FlushFinalBlock()
Return Convert.ToBase64String(stream.ToArray)
End Function
Can anyone please help? I am lost at this point. :/
I have encrypted some of the data. Here my encryption converter is AES-256-CBC.
import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
class AESCipher(object):
def __init__(self, key):
self.key = hashlib.sha256(key.encode()).digest()
def encrypt(self, raw):
raw = self._pad(raw)
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key, AES.MODE_CBC, iv)
return base64.b64encode(iv + cipher.encrypt(raw))
def _pad(self, s):
return s + (AES.block_size- len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)
key = some key
raw='한글 (한국말)이라고도하는 한국어는 남한과 한국의 공식 언어입니다'
AESCipher_obj=AESCipher(key)
val = AESCipher_obj.encrypt(raw)
print(val)
When I execute my code it gives me that error.
> Traceback (most recent call last): File "aes2.py", line 27, in
> <module>
> s= AESCipher_obj.encrypt(raw) File "aes2.py", line 17, in encrypt
> return base64.b64encode(iv + cipher.encrypt(raw)) File "/usr/local/lib/python3.5/dist-packages/Crypto/Cipher/blockalgo.py",
> line 244, in encrypt
> return self._cipher.encrypt(plaintext) ValueError: Input strings must be a multiple of 16 in lengt
My input data is in the Korean language but When I try with the English language it is working perfectly. So how to encrypt for a specific language?
Assuming that you use a Python3 version, your string is an unicode string. You should encode it to an utf8 encoded byte string before padding it because the length will change. It works for ascii strings, because the length of the encoded byte string is the length of the unicode string.
So in your code, you must simply do:
key = some key
raw ='한글 (한국말)이라고도하는 한국어는 남한과 한국의 공식 언어입니다'
byte_raw = raw.encode('utf8')
AESCipher_obj=AESCipher(key)
val = AESCipher_obj.encrypt(byte_raw)
print(val)
After decrypting, you will get a byte string that should be decoded with .decode('utf8') to convert it to a Python3 (unicode) string.
Your Error:
ValueError: Input strings must be a multiple of 16 in length
AES is a block cipher, it works on 16-byte (128-bit) blocks.
The data needs to be padded until they're 16 bytes.
See this answer.
Hope this helps you!
try to encode() your string into byte string maybe ? and then padding it.
you can see here https://github.com/dlitz/pycrypto/blob/master/lib/Crypto/Cipher/blockalgo.py
that it's working with bytestring instead of unicode (you are using python3)
your step are correct, and I see nothing wrong with the padding mechanism
Trying to solve Cryptopals Challenge 10 where have to CBC decrypt a text file against "YELLOW SUBMARINE" with an IV of all ASCII 0 (\x00\x00\x00 &c).
Link to the text file is following:
http://cryptopals.com/static/challenge-data/10.txt
I have followed the algorithm CBC uses by taking cipher text, decrypting(using ECB decryption) and then taking xor with Initialization Vector for first block and ciphertext(i-1) for subsequent blocks. However for some not-understandable reason I am not getting a readable decryption. I just see some weird characters when I print after decryption:
from Crypto.Cipher import AES
key ='YELLOW SUBMARINE'
iv = "%00%00%00"*32
iv = iv.replace('%',r'\x')
#XOR-ing function
def xor_strings(a, b):
return "".join(chr(ord(a1) ^ ord(b1)) for a1, b1 in zip(a, b))
#Taking input file and converting it into a single string
file = open('10.txt','r')
data = file.read()
block = 128
obj = AES.new(key, AES.MODE_ECB)
def split_len(string, size):
return [string[i:i+size] for i in range(0, len(string), size)]
mylist = split_len(data,block)
decrypted = ""
for i in range (0,len(mylist)):
mystr = obj.decrypt(mylist[i])
if (i==0):
decrypted = decrypted + xor_strings(mystr,iv)
else:
decrypted = decrypted + xor_strings(mystr, mylist[i-1])
print decrypted
What might be the problem here ?
The iv needs to be 16 zero bytes (the question is not clearly worded here when it says “ASCII 0”):
iv = "\x00" * 16
You need to base64 decode the file before decrypting it:
from base64 import b64decode
#...
file = open('10.txt','r')
data = file.read()
data = b64decode(data)
Finally your block size needs to be in bytes for this code to work, not bits:
block = 16
For my class assignment we need to decrypt a message that used RSA Encryption. We were given code that should help us with the decryption, but its not helping.
def block_decode(x):
output = ""
i = BLOCK_SIZE+1
while i > 0:
b1 = int(pow(95,i-1))
y = int(x/b1)
i = i - 1
x = x - y*b1
output = output + chr(y+32)
return output
I'm not great with python yet but it looks like it is doing something one character at a time. What really has me stuck is the data we were given. Can't figure out where or how to store it or if it is really decrypted data using RSA. below are just 3 lines of 38 lines some lines have ' or " or even multiple.
FWfk ?0oQ!#|eO Wgny 1>a^ 80*^!(l{4! 3lL qj'b!.9#'!/s2_
!BH+V YFKq _#:X &?A8 j_p< 7\[0 la.[ a%}b E`3# d3N? ;%FW
KyYM!"4Tz yuok J;b^!,V4) \JkT .E[i i-y* O~$? o*1u d3N?
How do I get this into a string list?
You are looking for the function ord which is a built-in function that
Returns the integer ordinal of a one-character string.
So for instance, you can do:
my_file = open("file_containing_encrypted_message")
data = my_file.read()
to read in the encrypted contents.
Then, you can iterate over each character doing
char_val = ord(each_character)
block_decode(char_val)