Я шифрую номера клиентов в PHP, используя openssl_encrpyt.
$value = '01715034842';
$key = 'pi3kn3W@k@cj3';
$iv = 'Toy@dtv!';
$cipher = 'bf-cbc';
$crypted = openssl_encrypt($value, $cipher, $key, true, $iv);
$hashValue = unpack('H*',$crypted);
Конечный результат:
0b6b81176ac7c298ebcb294f0a581539
Также мой друг программирует другую часть в Перл. И он также кодирует то же число, используя те же ключи и используя Blowfish для (он использует библиотеку перл: https://metacpan.org/pod/release/LDS/Crypt-CBC-2.30/CBC.pm ):
use Crypt::CBC;
use Crypt::Blowfish;
## szyfrowanie
my $key = 'pi3kn3W@k@cj3';
my $iv = 'Toy@dtv!';
my $cipher = Crypt::CBC->new( -key => $key,
-iv => $iv,
-header => 'none',
-cipher => 'Blowfish'
);
sub mkHash {
my $crypt = $cipher->encrypt_hex($_[0]);
# print 'Hash: '.$crypt."\n";
return $crypt;
}
sub deHash {
my $crypt = $cipher->decrypt_hex($_[0]);
# print 'string: '.$crypt."\n";
return $crypt;
}
my $clientHash = mkHash($smc);
И он получил для одного и того же набора данных другой результат:
c5377bcf0f55af641709c35928350576
Таким образом, мы не можем использовать этот широкий язык.
Это зависит от языковых различий программирования? Или это ошибка в моем коде или языке?
Я думаю, что когда мы используем один и тот же набор данных и одинаковое шифрование (BlowFish CBC), мы должны получить одинаковые результаты на всех языках.
Ждем мнения по этому делу.
Лучший
Bartek.
Следующие сценарии PHP и Perl показывают, как добиться одинакового вывода для двух языков. Я объясню некоторые детали ниже.
PHP:
$value = '01715034842';
$cipher = 'bf-cbc';
$key = '12345678901234567890123456789012345678901234567890123456';
$option = OPENSSL_RAW_DATA;
$iv = 'Toy@dtv!';
$crypted = openssl_encrypt($value, $cipher, $key, $option, $iv);
echo($crypted)
Perl:
use Crypt::CBC;
use Crypt::Blowfish;
my $value = '01715034842';
my $key = '12345678901234567890123456789012345678901234567890123456';
my $iv = 'Toy@dtv!';
my $cipher = Crypt::CBC->new( -literal_key => 1,
-key => $key,
-iv => $iv,
-header => 'none',
-cipher => 'Blowfish'
);
my $crypted = $cipher->encrypt($value);
print $crypted;
С помощью diff
на двух выходах нет разницы, показывая, что они одинаковы:
$ diff <(php encrypt.php) <(perl encrypt.pl)
$
В следующих разделах объясняются необходимые изменения по сравнению с исходным кодом.
Ключ шифрования
PHP openssl_encrypt()
Функция всегда ожидает необработанный ключ. Байты, которые вы передаете, являются байтами, используемыми в качестве ключа шифрования. Perl CBC
класс с другой стороны ожидает парольную фразу по умолчанию, из которого он получит ключ шифрования делая хеш MD5. Если вы хотите, чтобы класс использовал ваши необработанные байты в качестве ключа шифрования, вы должны установить параметр literal_key
в 1
,
После того, как вы это сделали, CBC
класс ожидает, что ключом будет точное число байтов, необходимое для схемы шифрования, который CBC
класс предполагает 56
для Crypt::Blowfish
реализация. Отсюда и скорректированный ключ в скриптах. В противном случае вы получите ошибку If specified by -literal_key, then the key length must be equal to the chosen cipher's key length of 56 bytes
Выходной формат
PHP openssl_encrypt()
функция по умолчанию возвращает строку в кодировке base64, CBC
класс возвращает необработанные байты. Один из способов сделать это последовательным, установив OPENSSL_RAW_DATA
вариант в PHP.
Проверка зашифрованного текста
Если вы хотите проверить зашифрованный текст в удобочитаемом формате, вы можете добавить свои собственные процедуры печати в конце или перенаправить вывод в такой инструмент, как hexdump
или же xxd
$ php encrypt.php | xxd
00000000: 5f35 3205 74e8 dcaa 2f05 9aa4 366e ef8b _52.t.../...6n..
$ perl encrypt.pl | xxd
00000000: 5f35 3205 74e8 dcaa 2f05 9aa4 366e ef8b _52.t.../...6n..
Других решений пока нет …