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.
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')
I have a code in scala where I have my encryption and decryption code, It works fine and the code is:
import java.util.Base64
import javax.crypto.Cipher
import javax.crypto.spec.{IvParameterSpec, SecretKeySpec}
class Encryption {
val key = "enIntVecTest2020"
val initVector = "encryptionIntVec"
def encrypt(text: String): String = {
val iv = new IvParameterSpec(initVector.getBytes("UTF-8"))
val skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv)
val encrypted = cipher.doFinal(text.getBytes())
return Base64.getEncoder().encodeToString(encrypted)
}
def decrypt(text:String) :String={
val iv = new IvParameterSpec(initVector.getBytes("UTF-8"))
val skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES")
val cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING")
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv)
val original = cipher.doFinal(Base64.getDecoder.decode(text))
new String(original)
}
}
val encryptobj = new Encryption()
val pwd = "#test#12345"
val result =encryptobj.encrypt(pwd)
pwd: String = #test#12345
result: String = lHhq1OzMSYnj+0XxiNzKhQ==
val pwd1 = encryptobj.decrypt(result)
println(pwd1)
pwd1: String = #test#12345
#test#12345
I tried in Python to achieve the same but does not give the expected encryption result, here is my code(I took the help of other similar answers):
from hashlib import sha256
import base64
from Crypto import Random
from Crypto.Cipher import AES
BS = 16
pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')
unpad = lambda s : s[0:-ord(s[-1:])]
class AESCipher:
def __init__( self, key ):
self.key = bytes(key, 'utf-8')
def encrypt( self, raw ):
raw = pad(raw)
iv = "encryptionIntVec".encode('utf-8')
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return base64.b64encode( iv + cipher.encrypt( raw ) )
def decrypt( self, enc ):
enc = base64.b64decode(enc)
iv = enc[:16]
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc[16:] )).decode('utf8')
cipher = AESCipher('enIntVecTest2020')
encrypted = cipher.encrypt('#test#12345')
decrypted = cipher.decrypt(encrypted)
print(encrypted)
b'ZW5jcnlwdGlvbkludFZlY5R4atTszEmJ4/tF8YjcyoU='
As you can see both the encryption is not right, I don't know where I am doing wrong. Please help in achieving the same encrypting result in python as showing in scala, I would be much thankful.
Thanks to #Topaco answer and after some search it worked.
import base64
from Crypto.Cipher import AES
BS = 16
pad = lambda s: bytes(s + (BS - len(s) % BS) * chr(BS - len(s) % BS), 'utf-8')
unpad = lambda s : s[0:-ord(s[-1:])]
class AESCipher:
def __init__( self, key ):
self.key = bytes(key, 'utf-8')
def encrypt( self, raw ):
raw = pad(raw)
iv = "encryptionIntVec".encode('utf-8')
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return base64.b64encode(cipher.encrypt( raw ) )
def decrypt( self, enc ):
iv = "encryptionIntVec".encode('utf-8')
enc = base64.b64decode(enc)
cipher = AES.new(self.key, AES.MODE_CBC, iv )
return unpad(cipher.decrypt( enc )).decode('utf8')
cipher = AESCipher('enIntVecTest2020')
encrypted = cipher.encrypt('#test#12345')
print(encrypted.decode('utf-8'))
-> lHhq1OzMSYnj+0XxiNzKhQ==
decrypted = cipher.decrypt(encrypted)
print(decrypted)
-> #test#12345
key = "password"
def cipher(text): #my example cipher method
encoded_chars = []
for i in range(len(text)):
key_c = key[i % len(key)]
encoded_c = chr(ord(text[i]) + ord(key_c) % 256)
encoded_chars.append(encoded_c)
encoded_string = ''.join(encoded_chars)
return (encoded_string)
def decipher(text):
dec = []
text = base64.urlsafe_b64encode(b"'{text}'").decode()
print('text')
for i in range(len(text)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(text[i]) - ord(key_c)) % 256)
dec.append(text)
return str(dec_c)
enter code here
print(decipher("test"))
After encrypting it successfully with vigenere cipher I get something like this: b'\xc2\xbd\xc2\xb8\xc3\x83\xc3\x80'
I would like to decrypt this string with the code above and turn it into back to the text "password" however when I try to decrypt my text it leaves me with another encoded string. Can someone explain what I am doing wrong with my decryption?
It's not clear what you are trying to do with the base64 library. Also, you are mixing up come variables in your decrypt method:
dec.append(text) # text is the passed in argument.
# Why append it to the result
return str(dec_c) # this is the last element in the loop
# why return this rather than the list you made above?
Neither of the above things make much sense. Maybe something like this will get it going in the right direction:
key = "password"
def cipher(text): #my example cipher method
encoded_chars = []
for i in range(len(text)):
key_c = key[i % len(key)]
encoded_c = chr(ord(text[i]) + ord(key_c) % 256)
encoded_chars.append(encoded_c)
encoded_string = ''.join(encoded_chars)
return (encoded_string)
def decipher(text):
dec = []
for i in range(len(text)):
key_c = key[i % len(key)]
dec_c = chr((256 + ord(text[i]) - ord(key_c)) % 256)
dec.append(dec_c)
return "".join(dec)
plain = "some text to encrypt"
encrypted = cipher(plain)
print("encrypted: ", encrypted)
decrypted = decipher(encrypted)
print("decrypted: ", decrypted)
Prints:
encrypted: ãÐàØã×ÜäçâÔàÇâÚãç
decrypted: some text to encrypt
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.
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.