TripleDES в Perl / PHP / ColdFusion

Недавно возникла проблема, связанная с подключением API к платежному процессору, который запрашивал шифрование строки для использования в качестве токена с использованием стандарта TripleDES. Наши приложения запускаются с использованием ColdFusion, который имеет тег Encrypt, который поддерживает TripleDES, однако результат, который мы получили, оказался не таким, как ожидал обработчик платежей.

Прежде всего, вот полученный токен, который ожидал обработчик платежей.

AYOF+kRtg239Mnyc8QIarw==

А ниже приведен фрагмент ColdFusion, который мы использовали, и полученная строка.

<!--- 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.

Теперь я знаю, что разные языки реализуют шифрование по-разному - например, в прошлом, управляя шифрованием между приложением C # и серверной частью PHP, мне пришлось поэкспериментировать с отступами, чтобы заставить их говорить, но Мой опыт показывает, что PHP обычно ведет себя, когда речь идет о стандартах шифрования.

Во всяком случае, к исходному тексту PHP мы попробовали и полученную строку.

/* 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. Методы интеграции головы к стене.

После многих переписок с обработчиком платежей (много и много повторений заявляли: «Мы не можем помочь с проблемами кодирования, вы, должно быть, делаете это неправильно, прочитайте руководство»), мы наконец-то перешли к кому-то с более чем пару мозговых клеток, которые смогли потереть друг друга, которые смогли сделать шаг назад и фактически посмотреть и диагностировать проблему.

Он согласился, что наши попытки CF и PHP не привели к правильной строке. После быстрого поиска он также согласился с тем, что это был не наш источник, а то, как эти два языка реализовали свое видение стандарта TripleDES.

Этим утром мы пришли в офис по электронной почте с фрагментом исходного кода на Perl. Это был код, который они непосредственно использовали на своем конце для получения ожидаемого токена.

#!/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/\n//gs;

# resulting string (enc): AYOF+kRtg239Mnyc8QIarw==

Так что у нас это. Три языка, три реализации того, что они указывают в документации как TripleDES Standard Encryption, и три совершенно разные результирующие строки.

Мой вопрос, исходя из вашего опыта работы с этими тремя языками и их реализацией алгоритма TripleDES, смогли ли вы заставить любые два из них дать одинаковый ответ, и если да, то какие настройки для кода вы должны были сделать, чтобы прийти к результату?

Я понимаю, что это очень длительный вопрос, но я хотел дать четкие и точные настройки для каждого этапа тестирования, который мы должны были выполнить.

Позже я также выполню еще несколько следственных работ по этому вопросу и опубликую любые выводы, которые я приду к этому вопросу, чтобы другие могли избежать этой головной боли.

Ответы на вопрос(8)

Ваш ответ на вопрос