I need 2 sets of encrypt/decrypt functions to run under PHP and AS3.
I found AS3Crypto (for Flex) and mcrypt_encrypt (for PHP) and this article that shows how to use them for DES encryption:
http://www.zedia.net/2009/as3crypto-and-php-what-a-fun-ride/
I then tried to replace the DES encryption with AES-256, because the DES seems too vulnerable to brute force attacks.
The results from AES encryption in Flex and PHP are different.
Does anyone know (and tested) any equivalent functions for aes encryption in as3 and php?
If I wasn't clear enough, here is another post of an user having the same problem:
http://forum.openlaszlo.org/showthread.php?t=13709
Thanks!
I've done similar with different back end's and it can be a headache to get them to match.
I will tell you with a high degree of confidence from experience that most likely the issue you're running into is that the padding isn't matching up between the two or the encoding going back and forth (Hex).
Here's some working coldfusion code from an implementation I did a couple years ago, quickest I could dig up...
<cfsetting enablecfoutputonly="yes">
<cfparam name="form.k" default="1bbee91984f8b5bc032b6f67a665704e"/>
<cfscript>
textToEncrypt = 'printButton=No&saveButton=No';
encKey = ToBase64(BinaryDecode(form.k,"Hex"));
encryptedText = encrypt(textToEncrypt, encKey, 'AES', 'Hex');
</cfscript>
<cfoutput>settings=#encryptedText#</cfoutput>
(side note: isnt coldfusion awesome? hehe :P)
The decryption side in flex :
private function settingsEncResponse( e : ResultEvent ) : void {
// decrypt settings string
var o : Object = e.result;
var k:String = pKey; // key to decrypt with
var kdata:ByteArray;
kdata = Hex.toArray(k);
var txt:String = o.settings; // text to decrypt
var data:ByteArray;
data = Hex.toArray(txt);
var pad:IPad = new PKCS5;
var mode:ICipher = Crypto.getCipher("aes-ecb", kdata, pad);
pad.setBlockSize(mode.getBlockSize());
mode.decrypt(data);
currentInput = data;
var decryptedSettings : String = Hex.toString(Hex.fromArray(currentInput));
Related
I am working on creating an PHP String decrypter for a program that is written in VB.Net. I have done some research on .NET to PHP Encryption and Decryption and I can't seem to find a definitive solution.
I am new to PHP and my strong suit is not in Cryptography. It seems like their is a lot of different encryption classes.(mcrypt, Openssl and Sodium)
Here is the Code that I was given for the VB.Net Application.
Public Shared Function DecryptString(ByVal cipherTextStringWithSaltAndIv As String, ByVal passPhrase As String) As String
Dim cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherTextStringWithSaltAndIv)
Dim saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray()
Dim ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray()
Dim cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray()
Dim key As New Rfc2898DeriveBytes(passPhrase, saltStringBytes, 1000)
Dim keyBytes = key.GetBytes(Keysize / 8)
Using symmetricKey As New RijndaelManaged()
symmetricKey.BlockSize = 256
symmetricKey.Mode = CipherMode.CBC
symmetricKey.Padding = PaddingMode.ISO10126
Using decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes)
Using memoryStream As New MemoryStream(cipherTextBytes)
Using cryptoStream As New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
Dim plainTextBytes As Byte() = New Byte(cipherTextBytes.Length - 1) {}
Dim decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length)
memoryStream.Close()
cryptoStream.Close()
Return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount)
End Using
End Using
End Using
End Using
End Function
This is the function that I am unable to replicate in PHP.
So what I am looking for specifically.
Which Class/Extension? should I be using to receive an encrypted string and decrypt it to get the same results as this VB.Net function.
If you have any examples of how to solve this issue or any links to articles that would help me understand this issue further I would be
very grateful.
Thanks.
You can use (as you already said) Sodium!
Sodium for .NET
Also you should check out how does the Public-key authenticated encryption works. This is what you need. This system provides mutual authentication. However, a typical use case is to secure communications between a server, whose public key is known in advance, and clients connecting anonymously.
The code is written in C# but is it not a big deal to translate it. Die lib itself works without problems in vb.net
EDIT: I translated the example for you:
Private Sub GetStarted()
Const MESSAGE As String = "hello bob"
Dim vbnet As Sodium.KeyPair = Sodium.PublicKeyBox.GenerateKeyPair()
Dim php As Sodium.KeyPair = Sodium.PublicKeyBox.GenerateKeyPair()
Dim nonce As Byte() = Sodium.PublicKeyBox.GenerateNonce()
'vbnet encrypts A message for php
Dim encrypted As Byte() = Sodium.PublicKeyBox.Create(MESSAGE, nonce, vbnet.PrivateKey, php.PublicKey)
'php decrypt the message
Dim decrypted As Byte() = Sodium.PublicKeyBox.Open(encrypted, nonce, php.PrivateKey, vbnet.PublicKey)
'make the bytes readable
Dim msg As String = System.Convert.ToBase64String(decrypted)
decrypted = Convert.FromBase64String(msg)
msg = System.Text.Encoding.UTF8.GetString(decrypted)
MsgBox(msg)
End Sub
For php you should check the PHP String Encryption Example with Libsodium in this answer.
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!
So I am working on a PHP script that queries an API which uses HMAC authentication headers. However, I have been banging my head trying to encode the HMAC signature correctly. I have a preexisting nodejs script to work from as a template.
In the nodejs script, the HMAC signature is calculated using the following:
var crypto = require('crypto');
var hmac = [];
hmac.secret = 'ODc0YTM3YzUxODFlMWQ1YTdhMGQwY2NiZmE1N2Y1ODdjYzM5NTgyMDJhZjVkYTE4MmQxYzQ5ODk0M2QzNWQxYw==';
hmac.timestamp = 1457326475000;
hmac.path = '/account/';
hmac.message = hmac.path +'\n' + hmac.timestamp;
var sig = crypto.createHmac('sha512', new Buffer(hmac.secret, 'base64'));
hmac.signature = sig.update(hmac.message).digest('base64');
console.log(hmac);
This correctly calculates the HMAC signature as:
bWjIFFtFmWnj0+xHLW2uWVa6M6DpbIV81uyUWwRFCJUg+0Xyt40QWZWQjGvfPUB/JbjGZHUoso0Qv5JHMYEv3A==.
Meanwhile, in PHP, I am using:
<?php
$hmac['secret'] = 'ODc0YTM3YzUxODFlMWQ1YTdhMGQwY2NiZmE1N2Y1ODdjYzM5NTgyMDJhZjVkYTE4MmQxYzQ5ODk0M2QzNWQxYw==';
$hmac['nonce'] = '1457326475000';
$hmac['path'] = '/account/';
$hmac['message'] = $hmac['path']."\n".$hmac['nonce'] ;
$hmac['signature'] = base64_encode(hash_hmac('sha512',$hmac['message'],
$hmac['secret'], true));
print_r($hmac);
The above code, will calculate the HMAC signature as:
vqP49m/bk9nA4S3nMqW2r+kc2+yBfwhY/jWGUfz6dlKJUMkC2ktiPnuCcymdSWl4XezZT5VKCATYfus86Hz/Gg==
Working from the principle that "one million monkeys hacking away at a million keyboards" might one day be able to encode a valid HMAC signature, I have even tested a loop that iterates through all the permutations of the above PHP code (with/without base64 encoding the message, secret; with/without binary encoding of the HMAC, etc.)... to no avail.
Any suggestions for this here, one exhausted simian?
The problem is that you're not decoding your $hmac['secret'] first before passing it to hash_hmac().
Try:
$hmac['secret'] = base64_decode($hmac['secret']);
$hmac['signature'] = base64_encode(
hash_hmac('sha512', $hmac['message'], $hmac['secret'], true)
);
Was hoping someone would be able to help me out.
I desperately need this VB.NET code converted to PHP.
This is the Instructions I received:
To test your encryption, encrypt the following word with these keys and check if you get the same result:
Text to encrypt: MyPassword
Salt key: *&^%$##!
PBE Key: FWV70700
PBE IV: WEBSV
NOTE:
Encrypted text: A+V3JATKUt/T91HiF23eOA==
Following is a short VB.Net code snippet that will do the encryption, as we need it. The VB program has a form (From1) with two text boxes (TextBox1 and TextBox2) and one button (Button1):
VB.NET Function:
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Security.Cryptography
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
TextBox2.Text = EncryptText(TextBox1.Text)
End Sub
Public Shared Function EncryptText(ByVal strText As String) As String
Dim pdbPassword As PasswordDeriveBytes
Dim pdbIV As PasswordDeriveBytes
Dim DES As New DESCryptoServiceProvider
Dim salt() As Byte = {Asc("*"), Asc("&"), Asc("^"), Asc("%"), Asc("$"), Asc("#"), Asc("#"), Asc("!")}
Dim ms As New System.IO.MemoryStream
Dim cs As CryptoStream
Dim plainText As String = strText
Dim plainBytes() As Byte
plainBytes = System.Text.Encoding.UTF8.GetBytes(plainText)
pdbPassword = New PasswordDeriveBytes("FWV70700", salt)
pdbPassword.HashName = "SHA1"
pdbPassword.IterationCount = 1000
DES.Key = pdbPassword.GetBytes(8)
pdbIV = New PasswordDeriveBytes("WEBSV", salt)
pdbIV.HashName = "SHA1"
pdbIV.IterationCount = 1000
DES.IV = pdbIV.GetBytes(8)
cs = New CryptoStream(ms, DES.CreateEncryptor, CryptoStreamMode.Write)
cs.Write(plainBytes, 0, plainBytes.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray)
End Function
Could someone PLEASE convert this to PHP for me?
You need to find the according functions that do the same in PHP and then code it in PHP. It's best to do this step by step so you can compare if it's already working or not. As you have the vb.net code you can do this.
Sometimes functions vary a bit between .net and PHP, so there might be specific issues you need to take care about, so better do everything step by step and double checked.
See as well this related question: Same string, different SHA1 hash values obtained from VB.net and PHP.
In node.js, I have:
var h = crypto.createHash("md5"); // md5
h.update("AAA");
h.digest("hex");
In PHP I have:
md5("AAA");
However, both have different value. How can I make it the same? or else, what other algorithm I should use to make them the same, so that I can use it as signature calculation. Thanks.
Oppss.. actually. my mistake. when I test it, there is a bug.. it will md5 the same thing.
Simple googling I did in the past gave me => http://japhr.blogspot.com/2010/06/md5-in-nodejs-and-fabjs.html
Node.js
Script:
var crypto = require('crypto');
var hash = crypto.createHash('md5').update('AAA').digest("hex");
console.log(hash);
Output:
alfred#alfred-laptop:~/node/hash$ node hash.js
e1faffb3e614e6c2fba74296962386b7
PHP
Code
<?php
echo md5("AAA");
Output:
alfred#alfred-laptop:~/node/hash$ php md5.php
e1faffb3e614e6c2fba74296962386b7
The output for both PHP and node.js are equal.
C extension
Also you might have look at https://github.com/brainfucker/hashlib which uses C implementation which is going to be faster.
Your code creates the same hash value for me, you might doing it wrong at some point
I had the same issue with creating hash for non UTF8 string :
var non_utf8_str = "test_merchant;www.market.ua;DH783023;1415379863;1547.36;UAH;Процессор
Intel Core i5-4670 3.4GHz;Память Kingston DDR3-1600 4096MB
PC3-12800;1;1;1000;547.36";
The results in PHP and NodeJS was different until I used utf8 library.
So following code works equivalent for both PHP and NodeJS :
crypto.createHash('md5').update(utf8.encode(non_utf8_str)).digest('hex');
var hash = crypto.createHash('md5').update(password, 'latin1', 'latin1').digest('hex');
This worked for me. Try different encodings: 'utf8', 'ascii', or 'latin1'.