php from mcrypt to openssl - php

Since this day I've used mcrypt on my website to encrypt the users e-mail address.
The php mcrypt module was installed with php 7.4 on my last server so it didn't make any problems.
Since I needed to change the hosting company, they won't provide me with a mcrypt installation on their server. So I'll need to change the function which will be supported on php 7.4.
I had this function to encrypt my users e-mail address for security reasons if a sql injection ever happened.
function encrypt_128($string){
$string = rtrim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_ECB)));
return $string;
I've replaced with this function but it doesn't return the same output.
function encrypt_128($string){
return rtrim(base64_encode(openssl_encrypt($string, 'aes-256-ecb', $key, OPENSSL_RAW_DATA)));
I've read that mcrypt uses no padding and I tried adding OPENSSL_ZERO_PADDING but it can't encrypt the users e-mail address anymore, and returns no output.
I'll need the function to make the same output because the new users can register with the same e-mail address as the old users.

It turns out it isn't a way to make this possible
I just decrypted all my data and re encrypted them with the new algorithm. It took long but it was a needed change.
If anyone knows how feel free to post an answer.

Related

aspnet_membership password decryption via PHP

I've spent better half of the day trying to figure out the problem I have, and I'm at a dead end it seems.
I have a ASP application(no access to actual code, just database), in which the user passwords are stored in aspnet_membership > Password column, it also has a salt.
I've also got a copy of the machine key file, which from what I understand contains the keys neede to decryot the password?
<machineKey validationKey="**validation key**" decryptionKey="**decryption key**" validation="SHA1" decryption="AES"/>
i've tried a bunch of different ways of doing this, with open ssl, with different libraries, etc. However I seem to lack knowledge when it comes to this. I'm currently trying to use https://github.com/phpseclib/phpseclib library to decrypt the password:
$cipher = new AES(); // could use AES::MODE_CBC
// keys are null-padded to the closest valid size
// longer than the longest key and it's truncated
//$cipher->setKeyLength(128);
$cipher->setKey(**decrypt key**);
// the IV defaults to all-NULLs if not explicitly defined
$cipher->setIV($salt);
echo $cipher->decrypt($password);
However any way i'm trying todo this, I get either random return or false. I've got a very limited amount of info about the version of AES running on the ASP application or any other encryption info. Any help would be appreciated!
Hi This MachineKey has nothing to do with Salt, the salt is generating by the code at run-time using the Password provided.
.NET framework using Rfc2898DeriveBytes for encryption
Something like this
using (Rfc2898DeriveBytes rfc2898DeriveByte = new Rfc2898DeriveBytes(password, 16, 1000))
{
salt = rfc2898DeriveByte.Salt;
bytes = rfc2898DeriveByte.GetBytes(32);
}

Decrypt Rijndael with Passphrase in PHP

A customer is sending us a file encrypted with "AES-256". It arrives as a binary file (I normally get base64-encoded files, but this should be OK) and, in desperation, I have iterated through the PHP options using mcrypt_decrypt but cannot crack it.
<?php
$str = file_get_contents($argv[1]);
$key ='jimminny fred owns apple'; //not the actual one, but same length
$modes = array(
MCRYPT_MODE_ECB,
MCRYPT_MODE_CBC,
MCRYPT_MODE_CFB,
MCRYPT_MODE_OFB,
MCRYPT_MODE_NOFB);
$cryps = array(
MCRYPT_RIJNDAEL_128,
MCRYPT_RIJNDAEL_256,
MCRYPT_RIJNDAEL_192);
foreach($modes as $mode){
foreach($cryps as $cryp){
echo "\n\n$cryp $mode\n\n";
echo mcrypt_decrypt($cryp, $key, $str, $mode);
}
}
My understanding is that I should be receiving a 32-byte key, not a 24 char passphrase, but they are using a program called GlobalScape and this is all it requires for its 'Rijndael' encryption. (See screenshot attached showing the dialog window that the customer completes at their end).
I've checked the site and GlobalScape doesn't offer any details on how they encrypt. Not only do they not specify the key derivation function (KDF) that they use for "Rijndael" encryption. It's unlikely that they directly use the passphrase as a key - unless they are complete muppets - but the KDF could be anything. They do not specify the mode of operation for AES either
Simply do not use trash like that. Just use PGP or one of the standardized options for sending / receiving messages.
Going on a wild goose chase won't help you. Even if you program a solution then it may fail in the future because of any number of factors. Ask your client to clearly specify a protocol instead of giving you a screenshot.

Translate PHP mcrypt_decrypt function to Lua

I need to translate next PHP code to Lua:
mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $message, MCRYPT_MODE_ECB);
to Nginx+Lua.
I have openssl extension, but the problem is MCRYPT_RIJNDAEL_256. I do not know what method for openssl I need to use, and as I understood from this post: http://thefsb.tumblr.com/post/111035508040/porting-php-code-from-mcrypt-to-openssl I can't use openssl at all. Any other solutions?
Also, you may say I should not use mcrypt_decrypt/encrypt or MCRYPT_RIJNDAEL_256 at all, but I must, since I need to port PHP project to Nginx+Lua and changing encryption method will break whole system at the moment and consequences will be devastating.

SagePay v3.0 VSPForm in PHP

I am using VSPForm on V3.00 and AES encryption. I have it all set up and working on one site but on another (where everything is identical) I get an error saying Currency field is missing.
After spending all day trying to sort it with Sage they keep telling me that I am not sending 128 bit encryption and that they cannot decrypt what i am sending. Strange as i am sending the same identical info from another site and that works. I know I am sending 128bit and I can encrypt and decrypt the string sent to them on my own system
For my encrypt I use the following inside a function
global $strEncryptionType
,$strEncryptionPassword;
$strIV = $strEncryptionPassword;
//** add PKCS5 padding to the text to be encypted
$strIn = addPKCS5Padding($strIn);
//** perform encryption with PHP's MCRYPT module
$strCrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $strEncryptionPassword, $strIn, MCRYPT_MODE_CBC, $strIV);
//** perform hex encoding and return
return "#" . bin2hex($strCrypt);
Does anyone know of any other reason why this error would occur? When checking the post and cart info Currency is definitely set.
The 3045 'Currency' error is usually nothing to do with the currency. It usually indicates that there is something wrong with the encryption - I would check the password is correct, bearing in mind that these are different for live / test.
I found the issue, for some reason my global vars are not working inside the function even though they are all on the same page
P

crypt() breaks when migrating from PHP 5.2 to 5.4

I have a system running on PHP version 5.2.10 Unfortunately the original programmer misunderstood how crypt() was implemented.
$crypt = crypt(trim($cuPassword), CRYPT_BLOWFISH);
// The programmer thought this is how you configure a blowfish cipher
nb CRYPT_BLOWFISH has a value of zero on this machine.
This works in as much as it produces a random looking password hash eg 0$oZ534I2VvSw
Today, I migrated the software to PHP 5.4.9 and discovered that $crypt becomes *0 , ie an error due to the invalid salt.
My problem is that I have a table of login passwords that I can no longer validate. My question: Is there going to be a way I can recreate the original cipher that ran under version 5.2? What hash was implemented when you passed "0" as a salt?
Your description doesn't really add up. In PHP 5.4.9, I tested this:
var_dump(crypt('hello', 0));
Output:
0$ny0efnQXFkE
Now in PHP 5.5, you'll get *0 when calling crypt('hello', 0). But that's okay! Because this is still true in PHP 5.5: this crypt('hello', '0$ny0efnQXFkE') == '0$ny0efnQXFkE'.
All you need to do is change how you generate your hash for new passwords. Validating existing passwords will continue to work.
For good measure, after people successfully log in, check if their hash begins with 0$. If it does, rehash the password (since they entered it, you know what it is) with the updated, proper crypt call.
I tried all valid two digit combinations (CRYPT_STD_DES) and I found that "0q" is equivalent (nearly).
PHP 5.2.10
crypt(trim($cuPassword), CRYPT_BLOWFISH);
Result = 0$txv6CWBxJ9Y
PHP 5.4.9
crypt(trim($cuPassword), '0q');
Result = 0qtxv6CWBxJ9Y
All I need to do is adjust the second character and I can match passwords again.
No, there's no way you can recreate the original cipher. Otherwise even a boy scout would be able to break blowfish.
Your best chance is to generate a random password for your users and hash it once again, then force them to change the password as soon as they login.
"$" is not a valid salt value according to crypt(3) so you need to find a crypt implementation that's equally broken as the one PHP/libc used to have :)
If verifying old passwords is enough, use Matthews answer, else try e.g. openssl which currently still seems to accept "0$" as salt:
$ echo -n "secret" | openssl passwd -crypt -salt '0$' -stdin
0$z.PXBBy6uY.

Categories