Недавно возникла проблема, связанная с подключением 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, и три совершенно разные результирующие строки.
Мой вопрос заключается в том, что, исходя из вашего опыта работы с этими тремя языками и их реализацией алгоритма TripleDES, вы смогли заставить любые два из них дать одинаковый ответ, и если да, то какие настройки для кода были вам необходимы? сделать для того, чтобы прийти к результату?
Я понимаю, что это очень длительный вопрос, но я хотел дать четкую и точную настройку для каждого этапа тестирования, который мы должны были выполнить.
Позже я также выполню еще несколько следственных работ по этому вопросу и опубликую любые выводы, которые я приду к этому вопросу, чтобы другие могли избежать этой головной боли.