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