I was following this link link and it is working with what I presume is an error. This is the output I get when decrypting an encrypted string. I can't copy it so this is the image:
It should decrypt to mYs3cr3t! string.
Edit, here is my code:
def encrypt(self,param):
BLOCK_SIZE = 16
PADDING = '{'
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
secret = "mynotsosecretkey"
print 'encryption key:',secret
cipher = AES.new(secret)
encoded = EncodeAES(cipher, param)
print 'Encrypted string:', encoded
return (encoded,secret)
def decryption(self,passwd):
PADDING = '{'
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
encryption,key = self.encrypt(passwd)
cipher = AES.new(key)
decoded = DecodeAES(cipher, encryption)
print decoded
As for the output, I am unable to copy it because it contains some weird characters.
Related
I use https://create.withcode.uk
So I found a AES (Advanced Encryption Standard) implementation in Python, but just the encoding and the decoding part:
def encrypt(string, password):
pad = lambda s : s + str.encode(chr(16 - len(s) % 16) * (16 - len(s) % 16))
password = str.encode(password)
string = str.encode(string)
salt = os.urandom(8) # Unpredictable enough for cryptographic use
salted = b''
dx = b''
while len(salted) < 48:
dx = md5_encode(dx + password + salt, True)
salted += dx
key = salted[0:32]
iv = salted[32:48]
cipher = AES.new(key, AES.MODE_CBC, iv)
encrypted_64 = base64.b64encode(cipher.encrypt(pad(string))).decode('ascii')
json_data = {
'ct': encrypted_64,
'iv': iv.hex(),
's': salt.hex()
}
return json.dumps(json_data, separators = (',', ':'))
Which works perfectly btw. Then after I did some "sentence = input('blah blah blah') and some password = input('blah blah'), after that, i did encrypt(sentence, password). But I'm really not that sure I did it correctly because it says : AttributeError: 'str' object has no attribute 'encode' on line 4
I'm new to Python.
str should be replaced by the string you want to encode, and the encoding you want to apply goes in the brackets.
password = password.encode(encoding='UTF-8')
string = string.encode(encoding='UTF-8')
Can't figure out by debugging, why I got b in front of my hidden string?
I get this string in my result:
'1101000011001010110110001101100011'
def retr(filename):
img = Image.open(filename)
binary = ''
if img.mode in ('RGBA'):
img = img.convert('RGBA')
datas = img.getdata()
for item in datas:
digit = decode(rgb2hex(item[0], item[1], item[2]))
if digit == None:
pass
else:
binary = binary + digit
if (binary[-16:] == '1111111111111110'):
# print("Success")
return bin2str(binary[:-16])
return str(bin2str(binary))
return "Incorrect Image Mode, Couldn't Retrieve"
But result in console is: b'hello'. Where is b from?
Doing some pre fucntion before retr():
def rgb2hex(r, g, b):
return '#{:02x}{:02x}{:02x}'.format(r, g, b)
def hex2rgb(hexcode):
return int(hexcode[1:3], 16), int(hexcode[3:5], 16), int(hexcode[5:7], 16)
def str2bin(message):
binary = bin(int(binascii.hexlify(message.encode("ascii")), 16))
return binary[2:]
def bin2str(binary):
message = binascii.unhexlify('%x' % (int('0b' + binary, 2)))
return message
help ,please, to catch that b..
x = b'hello'
print(x)
b'hello'
print(x.decode('utf-8'))
'hello'
I hope this shows enough so that you understand how to get it back to a utf-8 string
bin2str is returning a byte literal. You can use .decode() to return a string instead.
def bin2str(binary):
message = binascii.unhexlify('%x' % (int('0b' + binary, 2)))
return message.decode("utf-8") # or encoding of choice
I believe that any byte string will include: "b'" before the string to indicate it came from a binary value. After you convert the binary value to the string, you can do a replace function:
newstring = message.replace("b", "")
newstring = message.replace("'", "")
I have searched a lot on SO about complete encryption decryption example with my requirement. In fact, I've got many links and examples but None is working for me for AES-192-CBC mode and AES-256-CBC.
I have got following example which is supposed to be working with all types but it is working only with AES-128-CBC mode. I am new to Python. Can anyone help me where I am wrong?
I am using Python 3.4 on windows and I can not move to Python 2.7.
import base64
from Crypto.Cipher import AES
class AESCipher:
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, key, block_size=16):
if block_size < 2 or block_size > 255:
raise AESCipher.InvalidBlockSizeError('The block size must be between 2 and 255, inclusive')
self.block_size = block_size
self.key = key
self.iv = bytes(key[0:16], 'utf-8')
print(self.key)
print(key[0:16])
def __pad(self, text):
text_length = len(text)
amount_to_pad = self.block_size - (text_length % self.block_size)
if amount_to_pad == 0:
amount_to_pad = self.block_size
self.pad = chr(amount_to_pad)
return text + self.pad * amount_to_pad
def __unpad(self, text):
#pad = ord(text[-1])
#return text[:-pad]
text = text.rstrip(self.pad)
return text
def encrypt( self, raw ):
raw = self.__pad(raw)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return base64.b64encode(cipher.encrypt(raw))
def decrypt( self, enc ):
enc = base64.b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv )
return self.__unpad(cipher.decrypt(enc).decode("utf-8"))
e = AESCipher('1234567812345678', 16)
#e = AESCipher('123456781234567812345678', 24)
#e = AESCipher('12345678123456781234567812345678', 32)
secret_data = "hi"
enc_str = e.encrypt(secret_data)
print('enc_str: ' + enc_str.decode())
dec_str = e.decrypt(enc_str)
print('dec str: ' + dec_str)
Though this code encrypts the data with 192 and 256 bit encryption and successfully decrypt that too but my other .Net and Ruby application only able to decrypt the data which was encrypted using 128 encryption.
Note .Net and Ruby application are successfully tested with each other and with online encryption tool with all encryption types.
Note that my application requires AES-CBC mode and PKCS#7 padding and must be run on Python 3.4.
Made it working by padding of 16 bytes for any encryption types. For that I used AES.block_size which is 16 by default for AES.
import base64
from Crypto.Cipher import AES
class AESCipher:
class InvalidBlockSizeError(Exception):
"""Raised for invalid block sizes"""
pass
def __init__(self, key):
self.key = key
self.iv = bytes(key[0:16], 'utf-8')
print(self.key)
print(key[0:16])
def __pad(self, text):
text_length = len(text)
amount_to_pad = AES.block_size - (text_length % AES.block_size)
if amount_to_pad == 0:
amount_to_pad = AES.block_size
pad = chr(amount_to_pad)
return text + pad * amount_to_pad
def __unpad(self, text):
pad = ord(text[-1])
return text[:-pad]
def encrypt( self, raw ):
raw = self.__pad(raw)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
return base64.b64encode(cipher.encrypt(raw))
def decrypt( self, enc ):
enc = base64.b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, self.iv )
return self.__unpad(cipher.decrypt(enc).decode("utf-8"))
e = AESCipher('1234567812345678', 16)
#e = AESCipher('123456781234567812345678', 24)
#e = AESCipher('12345678123456781234567812345678', 32)
secret_data = "hi"
enc_str = e.encrypt(secret_data)
print('enc_str: ' + enc_str.decode())
dec_str = e.decrypt(enc_str)
print('dec str: ' + dec_str)
I am trying to communicate from AutoIt with a Python TCP server using encryption, but I think there's something wrong with my algorithms since the results of both encryptions/decryptions are different:
AutoIt:
#include <Crypt.au3>
Global $key = "pjqFX32pfaZaOkkCFQuYziOApaBgRE1Y";
Global $str = "Am I welcome???"
_Crypt_Startup()
$hKey = _Crypt_DeriveKey($key, $CALG_AES_256)
$s = _Crypt_EncryptData($str, $hKey, $CALG_USERKEY)
$s = _Base64Encode($s)
ConsoleWrite("Encrypted: " & $s & #CRLF)
$s = _Base64Decode($s)
$str = _Crypt_DecryptData($s, $hKey, $CALG_USERKEY)
ConsoleWrite("Decrypted: " & BinaryToString($str) & #CRLF)
AutoIt Output:
Encrypted: ZFBnThUDPRuIUAPV6vx9Ng==
Decrypted: Am I welcome???
Python:
#!/usr/bin/env python
from Crypto.Cipher import AES
import base64
import binascii
BLOCK_SIZE = 16
PADDING = binascii.unhexlify(b"07")
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
secret = 'pjqFX32pfaZaOkkCFQuYziOApaBgRE1Y'
cipher=AES.new(key=secret, mode=AES.MODE_ECB)
encoded = EncodeAES(cipher, 'Am I welcome???')
print 'Encrypted string:', encoded
decoded = DecodeAES(cipher, encoded)
print 'Decrypted string:', decoded
Python output:
Encrypted string: NDJepp4CHh5C/FZb4Vdh4w==
Decrypted string: Am I welcome???
The encrypted results are the NOT the same...
Where is my "bug"?
The problem can be solved by changing the paddings AND using a different AES implementation in AutoIt:
rijndael.au3 from here: http://www.autoitscript.com/forum/topic/44581-crypto-suite/
AutoIt:
#include <rijndael.au3>
#include <String.au3>
Global $key = "pjqFX32pfaZaOkkC";
Global $text = "Am I welcome???"
$encrypted = _StringToHex(BinaryToString(_rijndaelCipher($key, $text, 128, 0, '')))
ConsoleWrite("Encrypted: " & $encrypted & #CRLF)
$decrypted = BinaryToString(_rijndaelInvCipher($key, _HexToString($encrypted), 128, 0, ''))
ConsoleWrite("Decrypted: " & $decrypted & #CRLF)
Output:
Encrypted: A6848F1EF8C7C1313689E18567235A93
Decrypted: Am I welcome???
Python:
#!/usr/bin/env python
from Crypto.Cipher import AES
import base64
BLOCK_SIZE = 16
PADDING = chr(0)
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b16encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b16decode(e)).rstrip(PADDING)
text = 'Am I welcome???'
secret = 'pjqFX32pfaZaOkkC'
cipher=AES.new(key=secret, mode=AES.MODE_ECB)
encoded = EncodeAES(cipher, text)
print 'Python Encrypted string: ', encoded
decoded = DecodeAES(cipher, encoded)
print 'Python Decrypted string: ', decoded.encode("hex")
print 'Python Decrypted string: ', decoded
myencoded = "A6848F1EF8C7C1313689E18567235A93"
print "AutoIt Result: ", myencoded
decoded = DecodeAES(cipher, myencoded)
print 'From AU Decrypted string:', decoded
mydecoded = EncodeAES(cipher, decoded)
print 'Re-Encrypted string: ', mydecoded.upper()
Output:
Python Encrypted string: A6848F1EF8C7C1313689E18567235A93
Python Decrypted string: 416d20492077656c636f6d653f3f3f
Python Decrypted string: Am I welcome???
AutoIt Result: A6848F1EF8C7C1313689E18567235A93
From AU Decrypted string: Am I welcome???
Re-Encrypted string: A6848F1EF8C7C1313689E18567235A93
Don't continue to use the base64 encoding/decoding since sending the raw binary is fine for TCP streams.
Hey, I have been working on this for a while, and I can remebr my brother stepped me through this very same alogorithm.
Basicly, it just adds the ascii values of both the characters from the key, and the phrase.
I can encrypt it with this:
def encrypt(key, string):
encoded = ''
for i in range(len(string)):
key_c = ord(key[i % len(key)])
string_c = ord(string[i % len(string)])
encoded += chr((key_c + string_c) % 127)
return encoded
But I can't seem to remember what we did as far as decrypting. Its difficult to revers a mod :P
Any ideas?
That's simple, let's see how it works. First of all, the encrypted message is obtained by subtracting the key.
enc = msg + key (mod 127)
How can we obtain the original message? That's easy, subtract the key in both sides
enc - key = msg + key - key (mod 127)
And here we get:
enc - key = msg (mod 127)
For more details, please refer to Modular arithmetic, I think it should belong one of group/field/ring. I'm not an expert in math, for further reading, you should check out Number theory. Here is the refined code:
def encrypt(key, msg):
encryped = []
for i, c in enumerate(msg):
key_c = ord(key[i % len(key)])
msg_c = ord(c)
encryped.append(chr((msg_c + key_c) % 127))
return ''.join(encryped)
def decrypt(key, encryped):
msg = []
for i, c in enumerate(encryped):
key_c = ord(key[i % len(key)])
enc_c = ord(c)
msg.append(chr((enc_c - key_c) % 127))
return ''.join(msg)
if __name__ == '__main__':
key = 'This_is_my_awsome_secret_key'
msg = 'Hello world'
encrypted = encrypt(key, msg)
decrypted = decrypt(key, encrypted)
print 'Message:', repr(msg)
print 'Key:', repr(key)
print 'Encrypted:', repr(encrypted)
print 'Decrypted:', repr(decrypted)
Output
Message: 'Hello world'
Key: 'This_is_my_awsome_secret_key'
Encrypted: '\x1dNV`O\nkO`fD'
Decrypted: 'Hello world'
Decryption is the same, except with minus instead of plus.
But you do not need to inverse the mod, just the + key_c, right? So just add 128, subtract key_c, and do modulo 127 again to keep in range. (instead of the last line, all the other lines are the same as with encrypting.