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.
1 Correct answer
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
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.
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.
Copy link to clipboard
Copied
Interesting.
Can you pls post your CF, Java & PHP code which demonstrate this?
Cheers.
--
Adam
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.
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>
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
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
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.
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
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
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
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?
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.
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>
Copy link to clipboard
Copied
@ -==cfSearching==-
Some detective work, there, old chap!
Copy link to clipboard
Copied
@ -==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 ..

