問題描述
最近出現了一個問題,涉及將 API 與要求使用 TripleDES 標準加密的字符串用作令牌的支付處理器連接.我們的應用程序使用 ColdFusion 運行,它有一個 Encrypt 標簽——支持 TripleDES——但是我們得到的結果不是支付處理器所期望的.
Recently a problem arose regarding hooking up an API with a payment processor who were requesting a string to be encrypted to be used as a token, using the TripleDES standard. Our Applications run using ColdFusion, which has an Encrypt tag - that supports TripleDES - however the result we were getting back was not what the payment processor expected.
首先,這是支付處理器所期望的結果令牌.
First of all, here is the resulting token the payment processor were expecting.
AYOF+kRtg239Mnyc8QIarw==
下面是我們使用的 ColdFusion 的片段,以及結果字符串.
And below is the snippet of ColdFusion we were using, and the resulting string.
<!--- Coldfusion Crypt (here be monsters) --->
<cfset theKey="123412341234123412341234">
<cfset theString = "username=test123">
<cfset strEncodedEnc = Encrypt(theString, theKey, "DESEDE", "Base64")>
<!---
resulting string(strEncodedEnc): tc/Jb7E9w+HpU2Yvn5dA7ILGmyNTQM0h
--->
如您所見,這并沒有返回我們希望的字符串.為了尋求解決方案,我們為此過程放棄了 ColdFusion,并嘗試在 PHP 中重現令牌.
As you can see, this was not returning the string we were hoping for. Seeking a solution, we ditched ColdFusion for this process and attempted to reproduce the token in PHP.
現在我知道各種語言以不同的方式實現加密 - 例如,在過去管理 C# 應用程序和 PHP 后端之間的加密時,我不得不嘗試填充以使兩者談論,但我的經驗是 PHP 在加密標準方面通常表現得很好.
Now I'm aware that various languages implement encryption in different ways - for example in the past managing encryption between a C# application and PHP back-end, I've had to play about with padding in order to get the two to talk, but my experience has been that PHP generally behaves when it comes to encryption standards.
無論如何,我們嘗試過的 PHP 源代碼和結果字符串.
Anyway, on to the PHP source we tried, and the resulting string.
/* PHP Circus (here be Elephants) */
$theKey="123412341234123412341234";
$theString="username=test123";
$strEncodedEnc=base64_encode(mcrypt_ecb (MCRYPT_3DES, $theKey, $theString, MCRYPT_ENCRYPT));
/*
resulting string(strEncodedEnc): sfiSu4mVggia8Ysw98x0uw==
*/
您可以清楚地看到,我們得到了另一個字符串,它與支付處理器預期的字符串和 ColdFusion 生成的字符串都不同.提示對抗集成技術.
As you can plainly see, we've got another string that differs from both the string expected by the payment processor AND the one produced by ColdFusion. Cue head-against-wall integration techniques.
在與支付處理商進行多次來回溝通后(很多代表說我們無法幫助解決編碼問題,你一定是做錯了,閱讀手冊")我們終于被升級到某人有多個腦細胞相互摩擦,誰能夠退后一步,實際查看和診斷問題.
After many to-and-fro communications with the payment processor (lots and lots of reps stating 'we can't help with coding issues, you must be doing it incorrectly, read the manual') we were finally escalated to someone with more than a couple of brain-cells to rub together, who was able to step back and actually look at and diagnose the issue.
他同意,我們的 CF 和 PHP 嘗試沒有產生正確的字符串.經過快速搜索,他還同意這不一定是我們的來源,而是這兩種語言如何實現他們對 TripleDES 標準的看法.
He agreed, our CF and PHP attempts were not resulting in the correct string. After a quick search, he also agreed that it was not neccesarily our source, but rather how the two languages implemented their vision of the TripleDES standard.
今天早上走進辦公室,我們收到一封電子郵件,其中包含一段 Perl 源代碼.這是他們直接用于生成預期令牌的代碼.
Coming into the office this morning, we were met by an email with a snippet of source code, in Perl. This is was the code they were directly using on their end to produce the expected token.
#!/usr/bin/perl
# Perl Crypt Calamity (here be...something)
use strict;
use CGI;
use MIME::Base64;
use Crypt::TripleDES;
my $cgi = CGI->new();
my $param = $cgi->Vars();
$param->{key} = "123412341234123412341234";
$param->{string} = "username=test123";
my $des = Crypt::TripleDES->new();
my $enc = $des->encrypt3($param->{string}, $param->{key});
$enc = encode_base64($enc);
$enc =~ s/
//gs;
# resulting string (enc): AYOF+kRtg239Mnyc8QIarw==
所以,我們有了它.三種語言,他們在文檔中引用的 TripleDES 標準加密的三種實現,以及三種完全不同的結果字符串.
So, there we have it. Three languages, three implementations of what they quote in the documentation as TripleDES Standard Encryption, and three totally different resulting strings.
我的問題是,根據您對這三種語言及其 TripleDES 算法實現的經驗,您是否能夠讓其中任何兩種語言給出相同的響應,如果是,您必須對代碼進行哪些調整?為了得出結果?
My question is, from your experience of these three languages and their implementations of the TripleDES algorithm, have you been able to get any two of them to give the same response, and if so what tweaks to the code did you have to make in order to come to the result?
我知道這是一個非常冗長的問題,但我想為我們必須執行的每個測試階段提供清晰準確的設置.
I understand this is a very drawn out question, but I wanted to give clear and precise setting for each stage of testing that we had to perform.
稍后我還將對此主題進行更多調查工作,并將發布我對這個問題提出的任何發現,以便其他人可以避免這種頭痛.
I'll also be performing some more investigatory work on this subject later, and will post any findings that I come up with to this question, so that others may avoid this headache.
推薦答案
永遠不要使用 Perl 的 TripleDES.它做了很多奇怪的事情,你會玩得很開心.
The Perl's TripleDES should never be used. It does so many weird things and you are going to have fun.
您的第一個問題是 Perl 中的鍵是十六進制的,您需要將它們轉換為二進制.在 PHP 中試試這個,
Your first problem is that the keys in Perl are hex and you need to convert them into binary. Try this in PHP,
$theKey="123412341234123412341234";
$key = pack('H*', str_pad($theKey, 16*3, '0'));
$strEncodedEnc=base64_encode(mcrypt_ecb (MCRYPT_3DES, $key, $theString, MCRYPT_ENCRYPT));
echo $strEncodedEnc, "
";
結果是,
AYOF+kRtg239Mnyc8QIarw==
然后你必須以一種奇怪的方式填充它.我忘記了細節.你很幸運有這個樣本(它有 16 個字符).
Then you have to pad it in a weird way. I forgot the details. You are lucky with this sample (it's 16 chars).
這篇關于Perl/PHP/ColdFusion 中的 TripleDES的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!