• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Blowfish Encrypt() output differs from Blowfish encryption in PHP and other languages

New Here ,
Sep 22, 2009 Sep 22, 2009

Copy link to clipboard

Copied

I need to post the result of a blowfish hex encryption to an external API. 

The result of encrypt(myText, key, "BLOWFISH", "HEX") gives me a value that I can decrypt just fine in coldfusion, but apparently not the same value as you would get if you ran the same encryption (blowfish, hex) using PHP or Java. 

Essentially I'm trying to make the result of
encrypt(myText, key, "BLOWFISH", "HEX")
match what you get using this tool:
http://webnet77.com/cgi-bin/helpers/blowfish.pl
this tool seems to output the result that would be generated by php and what the API expects.

I'm not sure why the result differs or what options I would need to change to make Coldfusion generate the correct value.


I've tried padding the myText variable with null characters to fill it so the length is a multiple of 8 (have to use URLDecode("%00") instead of char(0) as the null character, since char(0) doesn't actually increase the length of the string).  But that doesn't seem to have much of any effect.


If someone can make the result of coldfusion's blowfish encryption match what you get using that tool above I would really appreciate it.

TOPICS
Advanced techniques

Views

9.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Valorous Hero , Nov 25, 2009 Nov 25, 2009

Still no clue why Coldfusion's Blowfish encryption is different, but here's the code for using java in case anyone else runs into the same issue:

Just to follow-up, it turns out the CF key needs to be in base64 format (and have a valid key length) to get the same result from CF+Java. (I hate it when it is something that simple .. 😉

<-cfset myText = "whatever">
<cfset plainKey = "something" />
<cfset keyInBase64 = BinaryEncode(CharsetDecode(plainKey, "utf8"), "base64")>
<cfset cfEncrypted = encrypt(m

...

Votes

Translate

Translate
Engaged ,
Sep 24, 2009 Sep 24, 2009

Copy link to clipboard

Copied

My instincts tell me that you need to come up with a different approach.

If you're expecting two entirely-unrelated language implementation teams, not only "to come up with compatible implementations" but to continue to do so for (perhaps...?) the next twenty-five years, "it ain't gonna happen."

And you ... or your successor (who is cursing your name posthumously after you had "that very unfortunate with a bread truck") ... might well be stuck with several gigabytes of un-decryptable data.  "Don't go there!"

If two applications need to talk to each other in such a way that no one can understand what they are saying, don't attempt a "roll your own" solution.  Instead, require that an encrypted secure communication-channel must exist between the two parties ... using proven, commercially available technologies such as VPN or SSL.  The information which the two parties send to each other is "in the clear."

Likewise, if you need to store secret data in a database, arrange for the database management system to secure that database on your behalf.  Make sure that your connection to the DBMS is likewise "flowing across a secure network channel."

If you need to store data securely on the hard drive, arrange to use an encrypted disk-volume.

In all of these cases, you have succeeded in removing the obligation for security from your application.  You have passed-the-buck to known-good third parties.  You have also built your app to rely upon technologies that the IS infrastructure people already know how to manage.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 25, 2009 Sep 25, 2009

Copy link to clipboard

Copied

I need to encrypt data using blowfish in order to post to an API.

Currently, the API has libraries for PHP, Java, .NET, Perl and Delphi but no Coldfusion, so I have to write the functions myself.

All these languages encrypt data using algorithm=BLOWFISH, mode=ECB, encoding=HEX and produce exactly the same result, so the API accepts it.  When I try to do it in CF, it produces a different result, so I cannot post to the API.

If PHP, Java, .NET, Perl and Delphi can come up with compatible implementations of Blowfish, why can't Coldfusion? Coldfusion is obviously the outlier, and is doing something different from the "standard" implementation of this encryption method - I'm trying to understand what that difference is, and if I can somehow bring it in line with the rest of the world.

At this point, I've been working on this for a week and the solution seems no closer.  I've even tried using Sean Corfield's cf_php, but that doesn't work because its implementation of the unpack function seems to have a bug.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

Interesting.

Can you pls post your CF, Java & PHP code which demonstrate this?

Cheers.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

Essentially I'm trying to make the result of encrypt(myText, key, "BLOWFISH", "HEX") match what you get using this tool:
http://webnet77.com/cgi-bin/helpers/blowfish.pl
this tool seems to output the result that would be generated by php

Not Perl?

I'm not sure why the result differs or what options I would need to change to make Coldfusion generate the correct value.

The author of that tool has to let you know his or her Initialization Vector. Different Blowfish IVs will produce different results even when the key is  the same.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

There was no IV for the encryption.

Anyway - I ended up solving it by instantiating a java object - and the java encryption gave the result that was expected.

Still no clue why Coldfusion's Blowfish encryption is different, but here's the code for using java in case anyone else runs into the same issue:

<cfset myText = "something">
<cfset myKey="somethingelse">
<!--- get a cipher instance --->
<cfset Cipher = createObject("java", "javax.crypto.Cipher")>
<cfset encryptor = Cipher.getInstance("Blowfish/ECB/NoPadding")>
<!--- must convert the key string into a KeySpec object first --->
<cfset keySpec = createObject("java", "javax.crypto.spec.SecretKeySpec").init(myKey.getBytes(), "Blowfish")>
<!--- initialize the cipher for encrypting --->
<cfset encryptor.init(Cipher.ENCRYPT_MODE, keySpec)>
<!--- do the encrypt --->
<cfset encryptedTextFromJava = encryptor.doFinal(myText.getBytes())>
<!--- finally convert it to hex --->
<cfset encryptedText = BinaryEncode(encryptedTextFromJava, "HEX")>
<cfoutput>
        encryptedText = #encryptedText#
<br>
</cfoutput>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

there was no IV for the encryption.

There most probably was, even if it was just the default.

P.S.: Coldfusion and IVs

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

Still no clue why Coldfusion's Blowfish encryption is different

I'm pleased you got your problem sorted.  I'd still like to get to the bottom of why CF is doing this differently, so it would be really helpful if you could post the code you used to demonstrate that - when given the same parameters - CF presents different results than PHP and Java (which provide the same results).  If there's a bug here, I'd like to get it on Adobe's radar.  If there's an obscure explanation for it, I'd like to work out what it is "for next time".

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

it would be really helpful if you could post the code you used to demonstrate tha

Actually - I already posted all the code you need to demonstrate it.

The coldfusion version:

<cfset encryptedText = encrypt(myText, mykey, "BLOWFISH", "HEX")>

The java object version:

<cfset Cipher = createObject("java", "javax.crypto.Cipher")>
<cfset encryptor = Cipher.getInstance("Blowfish/ECB/NoPadding")>
<!--- must convert the key string into a KeySpec object first --->
<cfset keySpec = createObject("java", "javax.crypto.spec.SecretKeySpec").init(myKey.getBytes(), "Blowfish")>
<!--- initialize the cipher for encrypting --->
<cfset encryptor.init(Cipher.ENCRYPT_MODE, keySpec)>
<!--- do the encrypt --->
<cfset encryptedTextFromJava = encryptor.doFinal(myText.getBytes())>
<!--- finally convert it to hex --->
<cfset encryptedText = BinaryEncode(encryptedTextFromJava, "HEX")>

You'll see different results.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

Yes thanks.  Needless to say I did see that.  You also mentioned you had a PHP equivalent demonstrating it output the same result as the Java one.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

I think this is it - don't really know php very well, so I'm not completely sure this is accurate...

$alg = "blowfish";

$mode = "ecb";

$iv = "00000000";
if (false === ($td = @mcrypt_module_open($alg, "", $mode, ""))) {
throw new Exception("Can not initialize the encryption module!", ENCRYPTION_ERROR);
}

if (@mcrypt_generic_init($td, $key, $iv)) {
throw new Exception("Encryption error!", ENCRYPTION_ERROR);
}

$data = @mcrypt_generic($td, $data);
@mcrypt_generic_deinit($td);
@mcrypt_module_close($td);

$data = @unpack("H*", $data);
$encryptedText=$data[1];

You can also check the results from online tools like

http://webnet77.com/cgi-bin/helpers/blowfish.pl and

http://www.tools4noobs.com/online_tools/encrypt

All give you the same result - the only one that's different is CF

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Sep 26, 2009 Sep 26, 2009

Copy link to clipboard

Copied

Cheers.  My PHP is sketchy too, but it's good to have a few examples of where CF is being different.  I'll raise this with the Adobe dev team.

--

Adam

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Sep 27, 2009 Sep 27, 2009

Copy link to clipboard

Copied

You can also check the results from online tools like

http://webnet77.com/cgi-bin/helpers/blowfish.pl and

http://www.tools4noobs.com/online_tools/encrypt

All give you the same result

What test values and settings did you use that produced the same results from those two links?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 28, 2009 Sep 28, 2009

Copy link to clipboard

Copied

You can also check the results from online tools like

http://webnet77.com/cgi-bin/helpers/blowfish.pl and

http://www.tools4noobs.com/online_tools/encrypt

All give you the same result - the only one that's different is CF

I can confirm that. I cannot yet see why either.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 25, 2009 Nov 25, 2009

Copy link to clipboard

Copied

Still no clue why Coldfusion's Blowfish encryption is different, but here's the code for using java in case anyone else runs into the same issue:

Just to follow-up, it turns out the CF key needs to be in base64 format (and have a valid key length) to get the same result from CF+Java. (I hate it when it is something that simple .. 😉

<-cfset myText = "whatever">
<cfset plainKey = "something" />
<cfset keyInBase64 = BinaryEncode(CharsetDecode(plainKey, "utf8"), "base64")>
<cfset cfEncrypted = encrypt(myText, keyInBase64, "Blowfish/ECB/NoPadding", "HEX")>


<cfset Cipher = createObject("java", "javax.crypto.Cipher")>
<cfset encryptor = Cipher.getInstance("Blowfish/ECB/NoPadding")>
<cfset keySpec = createObject("java", "javax.crypto.spec.SecretKeySpec").init(plainKey.getBytes(), "Blowfish")>
<cfset encryptor.init(Cipher.ENCRYPT_MODE, keySpec)>
<cfset encryptedTextFromJava = encryptor.doFinal(myText.getBytes())>
<cfset javaEncrypted = BinaryEncode(encryptedTextFromJava, "HEX")>

<cfoutput>
cfEncrypted = #cfEncrypted#<br>
javaEncrypted = #javaEncrypted#<br>
</cfoutput>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 25, 2009 Nov 25, 2009

Copy link to clipboard

Copied

@ -==cfSearching==-
Some detective work, there, old chap!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 26, 2009 Nov 26, 2009

Copy link to clipboard

Copied

LATEST

@ -==cfSearching==-

Some detective work, there, old chap!

Thanks! It was not until I started working backwards (ie used java to generate the secrete key instead of CF) that I realized the issue. I had totally overlooked the obvious base64 issue ..

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation