Hello everyone i was trying to decrypt some encrypted strings i encrypted with python .
the problem is that sometimes it decrypts correctly and sometimes it gives empty output for no obvious reason and i couldn't find any solution for it.
here's the code i'm using to decrypt on PHP .
knowing that online AES decryption tools decrypts it correctly.
$rtk=base64_decode('zgdHfETipvp1E5m3ix5NFOLuX8N0+zAIBzg+GOq0cTQ=');
$method = "aes-128-ecb";
$key = 'aaaaaaaaaaaaaaaa';
$email=openssl_decrypt($rtk, $method, $key,OPENSSL_RAW_DATA);
i would apreciate your help !
EDIT :
The python code i used to encript the string :
import pandas as pd
from Crypto.Cipher import AES
import names
import urllib.parse
import base64
from Crypto.Util.Padding import pad
from Crypto.Util.Padding import unpad
email="zqeafzeqaf23#example1.com"
key = b'aaaaaaaaaaaaaaaa'
data = email.encode('ascii', 'ignore')
cipher = AES.new(key, AES.MODE_ECB)
b64string = base64.urlsafe_b64encode(cipher.encrypt(pad(data,16)))
print(b64string)
Your Python code uses urlsafe_b64encode, but your PHP code uses the normal base64 variant (in fact your example data in the PHP code contains a + character so couldn’t have been produced by that Python code).
This could explain why the decryption is failing. If the url safe base 64 output from Python contains a - or _ character, PHP will simply strip that character from the string before decoding the rest of it. This will leave a string that is not a multiple of the AES block length and the decryption will fail.
You should ensure you are using the same base 64 variant to encode and decode. It doesn’t look like PHP provides a URL safe variant, you might need to use something like strtr before decoding to convert the base 64 into a normal variant:
$data = strtr($data, '-_', '+/');
$decoded = base64_decode($data);
Related
I have the following PHP code:
require('/var/www/third_party_plugins/phpseclib/vendor/autoload.php');
use phpseclib3\Crypt\PublicKeyLoader;
use phpseclib3\Crypt\RSA;
use phpseclib3\Math\BigInteger;
use phpseclib3\Crypt\AES;
use phpseclib3\Crypt\Random;
$message = hex2bin('f5f905e8b2d8f0a72e179a169a59bc373021a75865e55c6797627bc43ddc6af0d9bd673bf94f5e8defc5af81019fd87c7d504a6aa758ba1e2f1f9858d0293b0b');
$key = hex2bin('d2ce45fd5f80c15db0a4ab26a7e27f42b507ed9469f0d63c1dbe4f89ed84c0c2');
$iv = hex2bin('db9d7e844b00282327221bb563639f96');
$cipher = new AES('cbc');
$cipher->setIV($iv);
$cipher->setKey($key);
//$cipher->disablePadding();
$Decrypted = bin2hex($cipher->decrypt($message));
print("\n" . $Decrypted . "\n");
When I run this code, I get the following result:
240dcbefc0f82fadc00ef8494488aaa81400000c2def01e79fec6c4d9a822358dd8a910cac606e8afcb607793cb442093a56b7b40b
Inside of this result, I can see the message I WANT, which is:
1400000c2def01e79fec6c4d9a822358
However, there are 16 bytes of data in the front of the message which make no sense to me, it seems like some kind of padding, but I dont want it in my result nor do I understand why it is there, because from what I understand the padding should be removed by phpseclib or openssl functions
240dcbef c0f82fad c00ef849 4488aaa8
I understand that there is a 20 byte MAC at the end, however, I notice ONE extra byte in front of the mac:
dd8a910cac606e8afcb607793cb442093a56b7b40b // THIS IS 21 BYTES, NOT 20...why?
I'm also having trouble re-encrypting the data and getting a valid response from the server, as I'm re-encrypting it with PHP, then sending the SAME data to my C# server, and it is unable to decrypt the message.
I have this issue where something is encrypted in python using aes 256 cbc encryption as shown in the python codes encrypt method .
I am trying to create a Decrypt method in php to actually decrypt whats encrypted using the python class .
Here is my attempt to convert the python decryption method to php does it look right or am I missing something in my conversion as every time i use the php version to decrypt it says hmac failed ?
anyhelp in converting the python class to php i will appreciate.
public function decrypt(){
$encrypt_method ="AES-256-CBC";
$secret_key =base64_decode('samekeyusedintheencryption');
$encrypted=(string)'some encrypted text to be decrypted';
$data=json_decode(base64_decode($encrypted),true);
$secret_iv =base64_decode($data['iv']);
$output = \openssl_decrypt($data['value'],
$encrypt_method,$secret_key,0,$secret_iv);
return json_encode($output);
}
def decrypt(self, payload):
data = json_c.decode(base64.b64decode(payload))
value = base64.b64decode(data['value'])
iv = base64.b64decode(data['iv'])
crypt_object=AES.new(self.key,AES.MODE_CBC,iv)
plaintext = crypt_object.decrypt(value)
return loads(plaintext)
OK, I got it to work!
function decrypt($encryptedText, $secret_key){
$secret_key = base64_decode($secret_key);
$encrypt_method ="AES-256-CBC";
$data = json_decode(base64_decode($encryptedText),true);
$data['iv'] = base64_decode($data['iv']);
$data['value'] = base64_decode($data['value']);
return openssl_decrypt($data['value'], $encrypt_method, $secret_key, OPENSSL_RAW_DATA|OPENSSL_ZERO_PADDING, $data['iv']);
}
Some things I learned:
If the options in the openssl function are set to '0' it expects a base64_encoded input for the cipher text. Also, if the default options is set to '0' the padding default is set to PKCS#7. This, I think, is why we were getting the bad block size error.
So, the cipher text needs to be base64_decoded and we need to set both options for the padding.
I was able to decrypt your provided cipher text and see the email addresses.
You are provided the MAC in the Data array so this would allow you to check the MAC in the PHP script. This allows you to make sure the data has not been tampered with.
I recently did an encryption project and started with the open ssl, but ended up changing to the libSodium library. I highly recommend you check it out for any further projects.
Cheers!
In our application we are getting encrypted text from external server. This text have been encrypted using openssl in php.
When I am trying to decrypt the text in my Ruby code, I am getting following error message:
OpenSSL::Cipher::CipherError: wrong final block length
I read couple of solutions on Stackoverflow and was suggest to add following line to the code cipher.padding = 0. But after adding padding = 0, I am getting different error:
OpenSSL::Cipher::CipherError: data not multiple of block length
Below is my rough script I have written to decrypt the code.
require 'openssl'
require 'digest/sha1'
require 'base64'
encrypted = "VaZYJzn9QVEQIH4fmtA1Cg=="
key = "my_secret_key"
cipher = OpenSSL::Cipher::Cipher.new("aes-128-ecb")
cipher.decrypt
cipher.padding = 0
cipher.key = key
decrypted = cipher.update(encrypted)
decrypted << cipher.final
puts Base64.decode64(decrypted)
If I encrypt the text using Ruby then I can easily decrypt it. I am having problem to decrypt the code which are encrypted in php. Is there any way I can make encryption and decryption compatible between php and Ruby.
Simply change the way you call it.
From decrypted << cipher.final to decrypted = cipher.update(encrypted) + cipher.final
could get the string like
<GF\x8F\xDC\x91\xE1ew\xB1\x1C\xE8\xF8V\xA0\x99g\x01C\xCDF\xD6\v\x841l\x13\xA6\x9496{
Last, quote from Ruby Doc You should never use ECB mode unless you are absolutely sure that you absolutely need it
I want to encrypt a message in php with a known password using blowfish. I would then be like to decrypt this message in python.
This is useful even if you want to encrypt in one language and decrypt elsewhere.
I searched quite extensively but could not find any conclusive solution, so I thought to record my findings.
Note it is quite simple to encrypt/decrypt in same language such as python or php.
This solution is very simple but it took me a while to figure out.
Blowfish Params
Password should be of length 16
use mode MODE_ECB.
Data being encrypted length should be always divisible by 16 pad by spaces or anyother char. I have taken a 16 length data string in example below.
php code:
<?php
$passw='secretPassword12';
$ntext='helloWorld123456';
$enc = base64_encode(mcrypt_encrypt(MCRYPT_BLOWFISH, $passw, $ntext, MCRYPT_MODE_ECB));
echo '<div>'.$enc.'</div';
This outputs 3C8f2kaD8Of0INYk3l9qEg==
python code:
from Crypto.Cipher import Blowfish
from base64 import b64encode, b64decode
passw='secretPassword12'
ntext='helloworld123456'
cipher=Blowfish.new(passw, Blowfish.MODE_ECB)
encStr=b64encode(cipher.encrypt(data))
print encStr
This code outputs 3C8f2kaD8Of0INYk3l9qEg== too
Now suppose you want to decrypt some string in python encrypted in php. First do b64decode and then decrypt the result.
Remember to pad your data such that the len is divisible by 16.
Happy encrypting and decrypting!!!
PHP code:
$key = "12345678abcdefgh12345678abcdefgh";
$iv = "12345678abcdefgh";
$plaindata = "This is a test string.";
$enc = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaindata, MCRYPT_MODE_CBC, $iv));
echo($enc);
Result:
QBN0Yue3D9hBrBuD01n5KWG+lv2doMf97cKm/AeusAI=
How can this be decrypted in Python?
Try something like this (altho i do have PyCrypto installed)
from Crypto.Cipher import AES
import base64
AES.key_size=128
iv="your iv"
key="your key"
crypt_object=AES.new(key=key,mode=AES.MODE_CBC,IV=iv)
decoded=base64.b64decode(plain) # your ecrypted and encoded text goes here
decrypted=crypt_object.decrypt(decoded)
This will bring the decoded text but it will be padded with bytes for it to be a size multiple of 16.
You should probably decide on a proper padding scheme and remove it afterwards accordingly
Read the manual, its pretty well documented.
data = base64.b64decode('QBN0Yue3D9hBrBuD01n5KWG+lv2doMf97cKm/AeusAI=')