Solved

encryption issues

Posted on 2012-03-13
14
287 Views
Last Modified: 2012-04-01
Hello,
I'm working with a 3rd party vendor trying to send them an encrypted URL string with encode to preserve any spaces ect..  They are requiring a DESEDE encryption in ECB mode with PKCS5 padding using Base64 and the string should not be encoded again after the Base64 encoding.  

They have provided with me a username, password, and key they are expecting.  The code should be straight forward.  When put the code in, I get the following error:  

The key specified is not a valid key for this encryption: Wrong key algorithm, expected DESede.

Here is the code:

<cfset myKey = toBase64(BinaryDecode("xxxxxx[24bit key]xxxxxxx", "Base64"))>
<cfset myDate = dateformat(dateconvert( "local2Utc", now()), "YYYYMMDDHHMMSS")>
<cfset uid = "MyUserId">
<cfset pw = "MyPassword">
<cfset stmt = URLEncodedFormat("User_Id=#variables.uid#&User_Password=#Variables.pw#&User_TimeStamp=#variables.myDate#")>
<cfset encryptedUrl = encrypt(stmt, myKey, "DESEDE/ECB/PKCS5Padding", "Base64")>

I've taken out the actual username and password in this sample.  I've tried setting the the myKey to xxxxxx[24bit key]xxxxxxx (which is the key they are expecting), hashing the key, and taking out the ECB/PKCS5Padding.  

Any help would be greatly appreciated.  I'm not sure if I've overlooked anything, or exactly what I'm missing.  I'm not sure why CF keeps asking for the generateSecretKey method.  As soon as I do that, everything works great.   We are running CF 8.  Thank you in advance for your help.
0
Comment
Question by:DADITWebGroup
14 Comments
 
LVL 51

Expert Comment

by:ahoffmann
ID: 37718699
I'm no CF expert, but I assume that your encrypt() expects the key in binary format while you pass it base64 encoded
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 37719848
Sorry this is a PHP example, but it shows the principles of what needs to be done.
<?php // RAY_encrypt_decrypt.php
error_reporting(E_ALL);

// MAN PAGE: http://us.php.net/manual/en/ref.mcrypt.php

class Encryption
{
    protected $key;
    protected $eot;
    protected $ivs;
    protected $iv;

    public function __construct()
    {
        // SET KEY, DELIMITER, INITIALIZATION VECTOR - MUST BE KNOWN TO BOTH PARTS OF THE ALGORITHM
        $this->key = 'quay';
        $this->eot = '___EOT';
        $this->ivs = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
        $this->iv  = mcrypt_create_iv($this->ivs);
    }

    public function encrypt($text)
    {
        // APPEND END OF TEXT DELIMITER
        $text .= $this->eot;

        // ENCRYPT THE DATA
        $data = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv);

        // MAKE IT base64() STRING SAFE FOR STORAGE AND TRANSMISSION
        return base64_encode($data);
    }

    public function decrypt($text)
    {
        // DECODE THE DATA INTO THE BINARY ENCRYPTED STRING
        $text = base64_decode($text);

        // DECRYPT THE STRING
        $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv);

        // REMOVE END OF TEXT DELIMITER
        $data = explode($this->eot, $data);
        return $data[0];
    }
}

// INSTANTIATE THE CLASS
$c = new Encryption();

// INITIALIZE VARS FOR LATER USE IN THE HTML FORM
$encoded = '';
$decoded = '';

// IF ANYTHING WAS POSTED
if (!empty($_POST["clearstring"]))
{
    $encoded = $c->encrypt($_POST["clearstring"]);
    echo "<br/>{$_POST["clearstring"]} YIELDS ";
    var_dump($encoded);
}

if (!empty($_POST["cryptstring"]))
{
    $decoded = $c->decrypt($_POST["cryptstring"]);
    echo "<br/>{$_POST["cryptstring"]} YIELDS ";
    var_dump($decoded);
}

// END OF PHP - PUT UP THE FORM
?>
<form method="post">
<input name="clearstring" value="<?php echo $decoded; ?>" />
<input type="submit" value="ENCRYPT" />
<br/>
<input name="cryptstring" value="<?php echo $encoded; ?>" />
<input type="submit" value="DECRYPT" />
</form>

Open in new window

Everything inside the Encryption class is assumed to be unsigned binary data.  You only use base64 encoding to make the data into a string that is safe for transport over HTTP.   In my development I found that it was necessary to add an end-of-string delimiter to the original input strings.  The encode/decode process had a way of adding some shmutz to the end of the original string.
0
 
LVL 1

Author Comment

by:DADITWebGroup
ID: 37719878
Correct.  Their exact instructions are:  "Encrypt the Query String using DES3 and encode it using Base64 (Note that the string should NOT be URL-encoded again after the Base64 encoding.)  Then append the encrypted Query String to the URL."
0
 
LVL 52

Expert Comment

by:_agx_
ID: 37743013
I'm not sure why CF keeps asking for the generateSecretKey

That just means it doesn't see your key as valid for DESEDE. I noticed your key is shorter than what's returned by generateSecretKey.  Since CF only uses the 1st 24 bytes, try padding yours with 8 zeroes:

ie
<cfset myKey = "xxxxxx[24bit key]xxxxxxx"& "00000000">
<cfset encryptedUrl = encrypt(stmt, myKey, "DESEDE/ECB/PKCS5Padding", "Base64")>

<cfset myKey = toBase64(BinaryDecode("xxxxxx[24bit key]xxxxxxx", "Base64"))>

Fyi, that isn't needed if the key is in base64 to begin with.
0
 
LVL 1

Author Comment

by:DADITWebGroup
ID: 37743138
Thank you.  I've tried the padding of the 0's to get me the 32 bytes.  The encryptions goes through the way I expect it too, but when the 3rd party goes to decrypt it, they are unable to decrypt it because of the padding of 0's.  The last <cfset> was the very last thing I tried because I was out of ideas.  

<cfset myKey = toBase64(BinaryDecode("xxxxxx[24bit key]xxxxxxx", "Base64"))>

I've even tried to give not have any padding on the DESEDE, which becomes different issues.  
<cfset encryptedUrl = encrypt(stmt, myKey, "DESEDE/ECB/nopadding", "Base64")>
0
 
LVL 52

Expert Comment

by:_agx_
ID: 37743755
They are unable to decrypt it because of the padding of 0's.


I believe you, but it shouldn't make a difference because the docs say CF only uses the 1st 24 bytes. Do you know what the other side is using -java, c#, php?

For grins, try padding it with the 1st 8 characters of the key instead of 0's. Test it with a very simple input like "abc"
0
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 
LVL 1

Author Comment

by:DADITWebGroup
ID: 37774405
I've requested that this question be deleted for the following reason:

Found my own solution and it was mandatory I delete it because it unknowingly contained sensitive data that I did not want referenced later.<br /><br />Thank you
0
 
LVL 52

Expert Comment

by:_agx_
ID: 37773304
What was the actual solution?
0
 
LVL 1

Accepted Solution

by:
DADITWebGroup earned 0 total points
ID: 37774377
From my experience with many webservices and APIs, there never seems to be one specific way to consume and/or use them. It all depends on the expectations of the 3rd parties code. So what works here may be very different than another solution for another API. I have worked on many and I have yet to have two be identical. Hopefully, this helps someone get at least close in the future. . .

SOLUTION:
Coldfusion using a C# 3rd Party API

<cfset myKey = "xxxxxx[24bit key]xxxxxxx"> - (no formatting needed here even though you see it later on inline within the encryption tag. Coldfusion handles it differently inside the encyption tag then when setting the variable here.)

<cfset myDate = dateformat(dateconvert( "local2Utc", now()), "YYYYMMDD")&timeformat(dateconvert( "local2Utc", now()), "HHMMSS")> - (The dateformat function does not allot for the time mask specifications, thus this needed to be separated out and appended to the end with the timeformat function.)

<cfset stmt = "User_Id=[MyUserId]&User_Password=[MyPassword]&User_TimeStamp=#variables.myDate#"> - (Due to some difference in URLEncoding formats between coding languages, the URLEncodingFormat function was sending incorrect formats and really was not needed anyhow, so it was removed from this variable set)

<cfset encryptedUrl = encrypt(stmt, toBase64(myKey), "DESEDE/ECB/PKCS5Padding", "Base64")> - (The Base64 around the key itself must be specified here because of the way Coldfusion is handling the encryption function I suspect, but am not 100% sure on that. I just know that it does not work if set in variable definition instead. One note, you also must use the PKCS5Padding when dealing with C#.)

Thank you for taking the time to put in your suggestions. Unfortunately, they did not work this time out. Have a great day!
0
 
LVL 1

Author Comment

by:DADITWebGroup
ID: 37774406
Close request can be canceled as there was resolution to our issue.
0
 
LVL 52

Expert Comment

by:_agx_
ID: 37774745
The Base64 around the key itself must be specified here because of the way Coldfusion is handling the encryption function I suspect, but am not 100% sure on that. I just know that it does not work if set in variable definition instead.

Weird, I've never experienced that one myself, but .. encryption's sensitive so that's entirely possible. Anyway, glad you found a solution .. and thanks for posting the complete details for the archives.
0
 
LVL 1

Author Closing Comment

by:DADITWebGroup
ID: 37792771
This is the only resolution that worked. (Supervisor had solution)
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
File names with & character 6 70
Coova-Chilli can't work with URL using HTTPS! 3 160
use of cookies and regulations 1 76
Question to locate the problem 18 81
I will show you how to create a ASP.NET Captcha control without using any HTTP HANDELRS or what so ever. you can easily plug it into your web pages. For Example a = 2 + 3 (where 2 and 3 are 2 random numbers) Session("Answer") = 5 then we…
This article covers the basics of the Sass, which is a CSS extension language. You will learn about variables, mixins, and nesting.
The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…
Learn how to create flexible layouts using relative units in CSS.  New relative units added in CSS3 include vw(viewports width), vh(viewports height), vmin(minimum of viewports height and width), and vmax (maximum of viewports height and width).

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now