I have following steps to perform for decryption
base64 decode the response
Decrypt the first 128 bytes with the RSA1024 public key. Key is in base64 encoded X509 format with PKCS1 padding.
My code looks like this:
$decodedString = $this->base64UrlDecode($string); //does proper url decoding
$publicKey = file_get_contents("public.key",true);
$pub_key = openssl_get_publickey($publicKey);
openssl_public_decrypt($decodedString,$decrypted,$pub_key,OPENSSL_PKCS1_PADDING);
var_dump($decrypted);
I am not able to get anything in $decrypted variable. If I try to base64 decode public key before using it, I am getting error of not a valid public key. What I am missing or doing wrong to achieve mentioned 2 steps?
See this comment for openssl_pkey_get_public:
http://www.php.net/manual/en/function.openssl-pkey-get-public.php#101513
PKCS1 padding poses a problem to that function, it seems.
It was actually a problem with how I was getting response. By doing urldecode before base64 decoding I am able to get proper results.
$decodedString = $this->base64UrlDecode(urldecode($string));
Related
I am working on decrypting some content coming from an API. They have provided a command as well. So with some mofication below is the command, which works perfectly fine:
openssl enc -d -aes-128-cbc -K 422943374a3568755d7c527f6e472132 -iv 00000000000000000000000000000000 -nopad -in <(echo 'D5fiXKI4ie4c69gcCwM4/p414yrYtH9np+piNoqZASbkUnHAvbB4norHz6d6uzJmIg1sULhHFmfQTkvpw0tIEVmNcjyP6j2LK8zXYzohtNlsqBHx5v4xHEIyCcvfbMJddd5hs97jqkUtHuQyer2GdfDKZseaGgpXJ75GK7uKFPkbJ3wgQ6A0Q7q2tbBYeXEDmRMO6OhWeHgrezQOcyjcdOQk50SjMuaSb9IRimwagXamiXRg0LyTzA18a0SuqtbKCNgXnmhf39YxJUudkRmcMQ==' | base64 --decode)
I need to code in PHP, so I need to translate same thing in PHP, and here is what I have written in PHP:
$encodedStr = "PYroeIibeYwy/waD3opLw6yWT6Wfv3AhBKhQpoR+6qT9gx/bTDdR9QIfXcVURoQ2QlTl8L+JZX4Ije8M+FAQOxVmEXAmyUpzLgeg7aRCA6iiJbav/W3xW0BWb3D3QELjKTN4KRB2FdM7G5eIIfvjpeySLxQ3h7eL16nQf+1rms4VoVsBaeO8aU+Zy9saKZR4oL+k40m6tjtvtXryg7sWcmUgdonP/Jg4osESrY3MmGl7qXSpJC+v4g3iOY7s8NwywSN9q2Id7P0IaVtb5AFOEQ==";
$secretHash = ",MF-,2Y*s8DoYCFI";
$encryptionMethod = "AES-128-CBC";
$iv = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
$encrypted = base64_decode($encodedStr);
$hexKey = strToHex($secretHash);
$response = openssl_decrypt($encodedStr, $encryptionMethod, $hexKey, OPENSSL_ZERO_PADDING, $iv);
And in response, I am getting a string of odd characters instead of actual string which I can get from openssl command in command line.
As per openssl_decrypt documentation:
Takes a raw or base64 encoded string and decrypts it using a given method and key.
I have also tried giving base64 decoded value as well in first argument of this function. Encryption method also seems fine. And Zero padding as told in API document. Only thing which I think can be doubtful is zero iv. Let me know if I am making zero iv in wrong way. I have tried not using iv as well but not useful. Or also let me know if I am doing wrong in something else.
openssl_decrypt expects key to be binary not hex. You don't need to convert $secretHash to hex and just pass it as is.
$response = openssl_decrypt($encodedStr, $encryptionMethod, $secretHash, OPENSSL_ZERO_PADDING, $iv);
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.
I need to send a password that's RSA encrypted with a public key (along with some other data). Here are the exact instructions from the documentation for the password:
Encode password in Base64 and ensure UTF-8 encoding
Encrypt password with RSA with provided public key, no block mode, and PKCS1Padding
Encode resulting encryption in Base64 with ensured UTF-8 encoding
Here's the code I'm using that to me seems correct:
function encryptPassword($pass) {
$pass = base64_encode($pass);
$fp = fopen("./cert.crt", "r");
$publicKey = fread($fp, 8192);
fclose($fp);
openssl_get_publickey($publicKey);
openssl_public_encrypt($pass, $cryptedText, $publicKey, OPENSSL_PKCS1_PADDING);
return base64_encode(utf8_encode($cryptedText));
}
I'm getting an error on the other side saying the password can't be decoded. Support from them is basically non-existent other than the error message, and them saying everything is correct on their side. My question is, am I sending what they're asking for according to the documentation?
Thanks in advance!
No, you've taken Base64 with ensured UTF-8 encoding too literally. utf8_encode transforms one textual encoding into another, but $cryptedText is not textual. It is a binary string, so you lose some characters during encoding. Simply remove it, because Base64 gives you already a textual representation of the binary data:
return base64_encode($cryptedText);
Additionally, you probably wanted to pass the public key resource into the encryption function:
$key_resource = openssl_get_publickey($publicKey);
openssl_public_encrypt($pass, $cryptedText, $key_resource, OPENSSL_PKCS1_PADDING);
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.