TripleDES в Perl/PHP/ColdFusion

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

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

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

12
задан Seidr 12 May 2010 в 09:19
поделиться

3 ответа

Никогда не следует использовать Perl's TripleDES. Он делает так много странных вещей, и вы получите удовольствие.

Ваша первая проблема в том, что ключи в Perl - шестнадцатеричные, и вам нужно преобразовать их в двоичные. Попробуйте сделать это в 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, "\n";

В результате вы получите,

AYOF+kRtg239Mnyc8QIarw==

Затем вам придется заполнить его странным образом. Я забыл подробности. Вам повезло с этим примером (в нем 16 символов).

8
ответ дан 2 December 2019 в 06:25
поделиться

О, это весело!

> hex clear_text
0000  75 73 65 72 6e 61 6d 65  3d 74 65 73 74 31 32 33  username =test123

> openssl des3 -in clear_text -out crypt_text
enter des-ede3-cbc encryption password: 123412341234123412341234
Verifying - enter des-ede3-cbc encryption password: 123412341234123412341234

> hex crypt_text
0000  53 61 6c 74 65 64 5f 5f  d7 1b 37 a6 e0 c4 99 d1  Salted__ ..7.....
0010  ce 39 7f 87 5e 8b e8 8a  27 ca 39 41 58 01 38 16  .9..^... '.9AX.8.
0020  a5 2b c8 14 ed da b7 d5                           .+......

> base64 crypt_text
U2FsdGVkX1/XGzem4MSZ0c45f4dei+iKJ8o5QVgBOBalK8gU7dq31Q==

> openssl version
OpenSSL 0.9.8k 25 Mar 2009

> base64 --version | head -n 1
base64 (GNU coreutils) 7.1

Вам следует поговорить с экспертом по криптографии, попробуйте, возможно, списки рассылки openssl-users или dev-tech-crypto@mozilla, если здесь не появится кто-нибудь полезный.

2
ответ дан 2 December 2019 в 06:25
поделиться

Ответ Coldfusion:

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

Следующим шагом является преобразование ключа в шестнадцатеричный. Чтобы сделать это в CF, у нас есть:

<cfset theKey="123412341234123412341234000000000000000000000000">
<cfset encodedKey = ToBase64(BinaryDecode(theKey, "HEX"))>

Последний шаг заключается в том, что результат также не дополняется, поэтому нам нужно указать это в алгоритме шифрования в CF:

<cfset strEncodedEnc = Encrypt(theString, encodedKey, "DESEDE/ECB/NoPadding", "Base64")>

Полученный полный код:

<cfset theKey="123412341234123412341234000000000000000000000000">
<cfset encodedKey = ToBase64(BinaryDecode(theKey, "HEX"))>
<cfset theString = "username=test123">
<cfset strEncodedEnc = Encrypt(theString, encodedKey, "DESEDE/ECB/NoPadding", "Base64")>
<cfdump var="#strEncodedEnc#"><br>

results in:

AYOF+kRtg239Mnyc8QIarw==
5
ответ дан 2 December 2019 в 06:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: