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
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!
I'm a noob developer and I'm trying to decrypt some data but when I use OpenSSL in PHP I received no response. Also, when trying to encrypt data OpenSSL add a block of characters.
This is the code:
<?php
$dataToDecrypt = hex2bin("C2E5CDFE8BBFBC7350D40538434824DD3E11520B89A5BFDE24FA064DB2EED6EA");
$aesKey = hex2bin("E3FB8EA130722FA99266B96B77C2735C39393939393939393920202020202020");
$iv = hex2bin("00000000000000000000000000000000");
$result = openssl_decrypt($dataToDecrypt, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
echo bin2hex($result);
?>
The $result is supposed to be:
C3A6149C73FFBE4EAD36DC62FE40877D17CD690F37B06058CA3D65A345CC8212
I've tried this on VB and even in a AES encription web page (http://aes.online-domain-tools.com/) and the result is correct. But when trying with PHP I've got no answer.
I noticed when encrypting with the same information, the encrypted data is different. This is the code:
<?php
$dataToEncrypt = hex2bin("C3A6149C73FFBE4EAD36DC62FE40877D17CD690F37B06058CA3D65A345CC8212");
$aesKey = hex2bin("E3FB8EA130722FA99266B96B77C2735C39393939393939393920202020202020");
$iv = hex2bin("00000000000000000000000000000000");
$result = openssl_encrypt($dataToEncrypt, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
echo bin2hex($result);
?>
When I encrypt the result is:
C2E5CDFE8BBFBC7350D40538434824DD3E11520B89A5BFDE24FA064DB2EED6EA3A3ED407DC78D6AF9030BAB90CB40EAD
I get 32 characters more than expected (3A3ED407DC78D6AF9030BAB90CB40EAD). When I encrypt in VB or using the web page mentioned before I don't get these 32 extra characters.
Why is this happening? Am I missing something? I've been searching for an answer for several days. Any help is appreciated.
To see something during PHP decrypt you need to turn on warning messages.
Essentially the openssl_decrypt call will first decrypt your ciphertext. As long as your ciphertext is a multiple of 16 bytes (the block size of AES) this will always succeed. After that it will try and perform PKCS#7 compatible unpadding, which will fail (with high probability). To make it not unpad, use the OPENSSL_ZERO_PADDING in addition to OPENSSL_RAW_DATA.
The same goes for your encryption function of course. Currently you receive the ciphertext of the padded plaintext. This will add exactly one block of padding if the input plaintext is a multiple of the block size (and it is in your sample code). So you need OPENSSL_ZERO_PADDING there as well.
In one of our web application ( in PHP, MySQL ) we are saving user's mobile number as encrypted value and decrypt it when we send SMS to them. The application was pretty working well. But
now GoDaddy removed the option base64_encode and decode. So that we cant send SMS to users. So we revert back the mobile numbers to its normal state running it locally.
My question is which is the easiest and safe way to encrypt and decrypt a string using a key.
Something like
Normal string : 9876543210 -> After encrypt with a key -> AASASOOPFPOEROP45664654456
Encrypted string : AASASOOPFPOEROP45664654456 -> on decrypt -> 9876543210
My current code
function encodeString($str){
for($i=0; $i<5;$i++)
{
$str=strrev(base64_encode($str)); //apply base64 first and then reverse the string
}
return $str;
}
function decodeString($str){
for($i=0; $i<5;$i++)
{
$str=base64_decode(strrev($str)); //apply base64 first and then reverse the string}
}
return $str;
}
Please help me . Thanks in advance
Well if you were using base64 encode/decode you weren't encrypting the data, just obfuscating.
I don't know what php extensions godaddy has enabled, so I would suggest going with something like phpSecLib
http://phpseclib.sourceforge.net/
It is a standalone implementation you can include into your scripts, and will provide actual encryption of your data. AES or Rijndael should work find for your application
Basically it will encrypt the string with a key, even if your database is compromised, the data can't be decrypted without the key it was encrypted with (which you would hard coded into your script). This is unlike simply encoding it, in which case if someone got ahold of the database, they could decode it by running the first string through a variety of different encoding methods until they find one that works. And then run the rest through the same decoding method
here i am giving you one simple example with our own secret key you can use as below
// Secret key to encrypt/decrypt with
$key='mysecretkey'; // 8-32 characters without spaces
// String to encrypt
$string1='your sample key, that is the question';
// EnCrypt string
$string2=convert($string1,$key);
// DeCrypt back
$string3=convert($string2,$key);
// Test output
echo '<span style="font-family:Courier">';
echo 'Key: '.$key.'<br>'."\n";
echo $string1.'<br>'."\n";
echo $string2.'<br>'."\n";
echo $string3.'<br>'."\n";
echo '</span>'."\n";
OUTPUT
Key: mysecretkey
your sample key, that is the question
tvfw#ady{i|-rv|/2q|jq9dj3qkw%e~`jyp|k
your sample key, that is the question
Let me know i can help you more.
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!!!