PHP mcrypt to ColdFusion decrypt - php

I am working in a PHP app we have a particular string that we need to encrypt before storing in a database. I can do this in PHP with not problem using mcrypt with a key and a iv. Currently I'm trying to use blowfish because I thought it would be the most flexible as far as decrypting it in ColdFusion. The issue I ran into is it seems ColdFusion doesn't want to use the key or iv I encrypted with. ColdFusion wants you to generateSecretKey() and use some other way to create the iv.
What I can't seem to do is get the two to communicate. I tried first encrypting in coldFusion and using the key it generated and iv it used in PHP but the result was not what it should be. I know I must be missing something but I can't quite pinpoint what it might be.
<?php
$securedString = mcrypt_encrypt ('MCRYPT_BLOWFISH' , 'THISISMYKEYTHATISVERYLONG32CHARS' , "This is the string I need encrypted' , MCRYPT_MODE_CBC , '12345678');
echo base64_encode($securedString);
?>
So what would an equivalent ColdFusion Decryption call look like?
BTW: if Blowfish is not the ideal algorithm to use please feel free to suggest another as long as both ColdFusion and PHP can use it and it is secure.
Thanks,
Bruce

Something like this should work. You just need to share a common key between each.
In PHP:
base64_encode(mcrypt_encrypt(MCRYPT_3DES, $key, $plain_string, MCRYPT_MODE_ECB));
In Coldfusion:
<cfscript>
decrypted_string = decrypt(enc_string, key, "DESEDE", "Base64");
</cfscript>

Related

PHP RSA encryption openssl issue

I have been racking my brain. I am using the latest version of php 7. I can get rsa working with short text, however long text seems to not work. I read to use openssl_seal/open.. when I demoed the code on a test page it works great.. when I put it into practice with mysql its not working the way its supposed to..
Encryption code:
$messageiv = openssl_random_pseudo_bytes(32);
openssl_seal($_POST[$_SESSION['message']], $encryptedmessage, $ekeys, array($_SESSION['recipient_publickey']), "AES256", $messageiv);
openssl_seal($_POST[$_SESSION['subject']], $encryptedsubject, $ekeys, array($_SESSION['recipient_publickey']), "AES256", $messageiv);
The above is then base91_encoded and stored into blobs/varchar.
To decrypt it
openssl_open(base91_decode($row['messagesubject']), $decryptedsubject, $ekeys[0], $_SESSION['privatersakey'], "AES256", base91_decode($row['messageiv']));
openssl_open(base91_decode($row['messagebody']), $decryptedbody, $ekeys[0], $_SESSION['privatersakey'], "AES256", base91_decode($row['messageiv']));
The above variables $decryptedsubject and $decryptedmessage are blank.
I had this issue before using openssl_public/private key encrypt/decrypt and added the padding, this worked, however with long text it won't encrypt/decrypt....
Any assistance would be great...
I can get rsa working with short text, however long text seems to not work.
This is expected. RSA only operates on short inputs. If you want to encrypt a long message with RSA, you need to do one of two things:
Break your message into several distinct chunks and encrypt them separately. This is slow, inefficient, and insecure. (Attackers can drop or reorder chunks.)
Use a secure construction combining RSA and AES, like so.
Thus, you end up with something like this:
Encryption
Generate a random 32-byte key, k.
Encrypt k with your RSA public key to get C.
Calculate the HMAC-SHA256(C, k) to get the message key m.
Encrypt your message (P) with m, using AES-256-GCM to get D.
Return C and D.
Decryption
Generate a random dummy key, which we'll call k'.
Decrypt C using your RSA private key, to obtain k (one-time AES key).
If step 2 failed, use a constant-time algorithm to swap k out for k'.
Calculate the HMAC-SHA256(C, k) to get the message key m.
Decrypt D using m.
Return the decrypted plaintext (or fail because of the authentication tag).
I read to use openssl_seal/open.. when I demoed the code on a test page it works great.. when I put it into practice with mysql its not working the way its supposed to..
First, consider using libsodium instead.
Whether or not you continue to use OpenSSL, you probably want to base64-encode your output (and make sure you're storing data in a text field rather than a short varchar).

Decrypting the .ASPXAUTH Cookie WITH protection=validation

For quite sometime I've been trying to decipher the ASP .ASPXAUTH cookie and decrypt it using PHP. My reasons are huge and I need to do this, there is no alternative. In PHP so far I have successfully managed to read the data from this cookie, but I cannot seem to do it while it is encrypted. Anyway, here it goes...
First you need to alter your servers Web.config file (protection needs to be set to Validation):
<authentication mode="None">
<forms name=".ASPXAUTH" protection="Validation" cookieless="UseCookies" timeout="10080" enableCrossAppRedirects="true"/>
</authentication>
Then in a PHP script on the same domain, you can do the following to read the data, this is a very basic example, but is proof:
$authCookie = $_COOKIE['_ASPXAUTH'];
echo 'ASPXAUTH: '.$authCookie.'<br />'."\n";//This outputs your plaintext hex cookie
$packed = pack("H*",$authCookie);
$packed_exp = explode("\0",$packed);//This will separate your data using NULL
$random_bytes = array_shift($packed_exp);//This will shift off the random bytes
echo print_r($packed_exp,TRUE); //This will return your cookies data without the random bytes
This breaks down the cookie, or at least the unencrypted data:
Now that I know I can get the data, I removed the 'protection="validation"' string from my Web.config and I tried to decrypt it using PHP mcrypt. I have tried countless methods, but here is a promising example (which fails)...
define('ASP_DECRYPT_KEY','0BC95D748C57F6162519C165E0C5DEB69EA1145676F453AB93DA9645B067DFB8');//This is a decryption key found in my Machine.config file (please note this is forged for example)
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_RAND);
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, ASP_DECRYPT_KEY, $authCookie, MCRYPT_MODE_CBC, $iv);//$authCookie is the pack()'d cookie data
This however fails. I've tried variations of IV with all zeros # 16 bytes. I've tried different Rijndael sizes (128 vs 256). I've tried base64_decode()ing, nothing seems to work. I've found this stackoverflow post here and started using variations of the key/iv that are made using sha256, but that isn't really working either.
Anybody have a clue what I should do?
I don't know how encryption is made in .NET AuthCookies, but I can try to answer.
Assuming the encryption occurs in AES CBC-IV mode, with randomly generated IVs, you need to first find out where the IV is.
The code snippet you show cannot work, as you are generating a random IV (which will be incorrect). That being said, even if you get the IV wrong, in CBC mode you will only have the first 16 bytes of your decrypted ciphertext "garbled" and the rest will decrypt properly - you can use this as a test to know if you're doing the rest correctly. In practice when using random IVs, it's very likely that it's prepended to the ciphertext. To check if this correct, you can try to check if len(ciphertext) = len(plaintext) + 16. This would mean that most likely the first 16 bytes are your IV (and therefore it should be removed from the ciphertext before attempting to decrypt it).
Also on your code snippet, it seems you are using the key as an ascii-string, whereas it should be a byte array. Try:
define('ASP_DECRYPT_KEY',hex2bin('0BC95D748C57F6162519C165E0C5DEB69EA1145676F453AB93DA9645B067DFB8'));
Also, this seems to be a 32 byte key, so you need to use AES-256. I don't know how the authcookie looks like, but if it's base64 encoded, you also need to decode it first obviously.
Hope this helps!
Note: I don't recomment doing this for important production code, however - because there are many things that can go wrong if you try to implement even your own decryption routine as you are doing here. In particular, I would guess there should be a MAC tag somewhere that you have to check before attempting decryption, but there are many other things that can go wrong implementing your own crypto.
I understand this may not have been possible for the OP but for other people heading down this route here is a simple alternative.
Create a .net web service with a method like:
public FormsAuthenticationTicket DecryptFormsAuthCookie(string ticket)
{
return FormsAuthentication.Decrypt(ticket);
}
Pass cookie to web service from PHP:
$authCookie = $_COOKIE['.ASPXAUTH'];
$soapClient = new SoapClient("http://localhost/Service1.svc?wsdl");
$params= array(
"ticket" => $authCookie
);
$result = $soapClient->DecryptFormsAuthCookie($params);
I know what a pain is to decrypt in PHP something encrypted in .NET and vice versa.
I had to end up coding myself the Rijndael algorithm ( translated it from another language ).
Here is the link to the source code of the algorithm: http://pastebin.com/EnCJBLSY
At the end of the source code there is some usage example.
But on .NET, you should use zero padding when encrypting. Also test it with ECB mode, I'm not sure if CBC works.
Good luck and hope it helps
edit: the algorithm returns the hexadecimal string when encrypts, and also expects hexadecimal string when decrypting.

AES encryption in php and then decryption with Javascript (cryptojs)

I'm searching for a way to make a 2 way encryption of a simple text (5 to 6 numbers and/or characters). The catch is that i want to make the encryption in php and then decrypt it via Javascript. For php i've tested using mcrypt_encode and have gotten it to work, hence when i try to decrypt it with javascript (i'm using the Crypto-js library - http://code.google.com/p/crypto-js/ ) i get no results. Here is the php code i'm using:
$key = "oijhd981727783hy18274";
$text = "1233";
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', MCRYPT_MODE_CBC, '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC,$iv);
echo base64_encode($crypttext);
and then here is the Javascript code i'm using:
var encrypted = CryptoJS.enc.Base64.parse("LiJU5oYHXRSNsrjMtCr5o2ev7yDFGZId85gh9MEXPeg=");
var key = 'oijhd981727783hy18274';
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
document.write( decrypted.toString(CryptoJS.enc.Utf8) );
As i'm just testing, i copy/paste the output from the php straight into the JS and see if it would return any results, however that doesnt happen. As i'm new to the encryption/decryption part i might be missing something. Any suggestions will be greatly appreciated.
On a side note, as i read a lot of suggestions here about using other types of communication to transfer the data, that would not be possible in this case, as i need to pass this string to a third party software, which will bring it over on a secure area, where i have access to edit only the javascript, this is why i'm trying to encrypt the text in php and place it inside the website's source, from where the third party software will read it as it is encrypted and will transfer it to the secure section, where i will need to decrypt it back via Javascript (i dont have access to php there).
So, after some more digging i came to the following online encryptor/decryptor which led me to the gibberish-aes at GitHub repository.
Inside one of the comments on the first link i found that this JS library has a php equivalent, which seems to be working reasonably well and is fairly easy to deploy:
https://github.com/ivantcholakov/gibberish-aes-php
So thanks to Lars for the answer he provided, i would encourage him to open the repository, i'm sure he'll make someone's life a little bit easier :)
From the CryptoJS documentation:
For the key, when you pass a string, it's treated as a passphrase and used to derive an actual key and IV. Or you can pass a WordArray that represents the actual key. If you pass the actual key, you must also pass the actual IV.
So in your line
var decrypted = CryptoJS.AES.decrypt(encrypted, key);
"oijhd981727783hy18274" is treated as a passphrase to create a key and not as the actual key.
Passing an IV works like this:
var key = CryptoJS.enc.Hex.parse('000102030405060708090a0b0c0d0e0f');
var iv = CryptoJS.enc.Hex.parse('101112131415161718191a1b1c1d1e1f');
var encrypted = CryptoJS.AES.encrypt("Message", key, { iv: iv });
Some time ago I had the same problem. I finally got to use SlowAES from http://code.google.com/p/slowaes/ with some fixes and ported it to PHP.
Note: The official sources are broken, just as the official PHP port.
Let me know if you're interested. Then I'd open a new repository at GitHub where you can grab everything you need...

Encrypt / Decrypt with Private key

I would like to implement some security in some of the Flash/PHP applications that I have.
I have some Flash apps that communicate with PHP files, and the PHP is sending the data as get string ( e.g.: name=John&sname=Doe&age=24&balance=12.4 ). Instead of all these variables, I would like it to send a single variable ( e.g.: flashvar=jr9afgaw9-fg90agfawf7gw ) that would contain those values, so then Flash would decrypt the string and get the real and useful vars.
I want to encrypt this using a private key and use the same private key to decrypt this inside Flash. If someone would want to decode the message PHP sends, he would have to decompile the flash file and find the private key I'm using in Flash to decode the message and then decode it.
The reason I posted here is because I want to use an encryption algorithm that allows only the use of a private key for encryption/decryption.
I'm new in the cryptography field and I'd like some suggestions for this.
Thank you!
A "shared private key" is refered to as a symmetric key. The standard symmetric algorithm in use today is AES. I have no idea if php, or flash, have the capability of using AES (Google does), but if they do, you could hard code an AES key in your code and use it to encrypt and decrypt data. However, hard coding a key is very bad cryptography and is little more than obfuscation.
Another thing to keep in mind is the cipher mode you are using. Cipher Block Chaining (CBC) requires the use of an initialization vector (sort of like a salt for a hash), so two of the same values encrypted with the same key, but different IV, will result in differen cipher text. ECB does not need an initialization vector, but is less secure. For your needs I would go with ECB so you dont have to worry about an IV.
Google is a very good way of finding information, you should use it.
After a quick search, I saw that ActionScript 3 has support for encryption throught ASCrypt3 library. According to the website, AES Rijndael is supported.
Rijndael is also supported in PHP using the mcrypt extension. Here's a pretty good example taken from the manual:
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$text = "Meet me at 11 o'clock behind the monument.";
echo strlen($text) . "\n";
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
If You want to encrypt data I would go with the ASCrypt3o library.
It works very well and supports multiple types of encryption.
You can see a demo of it here click on the secret key tab.

Encrypt in VBScript/ASP Classic, Decrypt in PHP?

I'm looking to encrypt a string in VBScript, and decrypt it in PHP. I have full control over the VBScript/ASP Classic environment, but zero control over my PHP environment.
Given this, what sort of encryption could I use that would be adequate enough to secure a string? Apologies for the vagueness of the question, but I do not know where to begin.
Assuming the string is making its way between the servers via http then use https to send the string. That way you don't have to do the encryption/decryption, thats done for you by SSL.
The first thing you should try is simply using a standard encryption/decryption algorithm.
The problem is that these are handled by the php mcrypt extension and you may or may not have then available.
You want mdecrypt_generic. But you can test for it with:
<?php
if(function_exists('mdecrypt_generic')){
echo "Fred says 'you are going to be OK!'";
}else{
echo "Fred says 'it is a shame you cannot control your php environment'";
}
?>
If it exists then plain text that you encrypt with the same algorithm and parameters on VBScript/ASP should decrypt on PHP just fine. Be prepared to try different algorithms if you get funny results, sometime a "parameter" can really mess with you... If you do not have mcrypt then check for openssl. openssl_seal can do the same work for you, but you need to mess with x509 keys in that case. (I like CACert.org for simple x509 outsourcing...)
The other thing to consider... do you really need encryption or merely obfuscation?
HTH,
-FT

Categories