2015-06-09 2 views
1

Я использую компонент Delphi от chillkat, который для меня шифрует AES. Он работает как шарм, и сервер принимает мои зашифрованные запросы. Поэтому я попытался создать php-кулон с помощью mcrypt. Но результат PHP mcypt отличается от результата Delphi Chillcat - даже если все параметры одинаковы. Поэтому сервер отклоняет запросы php.Различия в шифровании AES между php mcrypt и компонентом Delphi

Все настройки шифрования одинаковы:

  • Cipher Название: AES 128
  • Cipher Режим работы: ECB
  • схема
  • Обивка: Pad с NULL
  • Длина ключа: 128
  • Key : 1234567890ABE1234567890ABE1234DB
  • Строка для шифрования: это действительно классная тестовая строка

Это немного PHP скрипт:

<?php 
    $key = '1234567890ABE1234567890ABE1234DB'; 
    function string_encrypt($string, $key) { 
     $crypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $string, MCRYPT_MODE_ECB); 
     return $crypted_text; 
    } 

    function string_decrypt($encrypted_string, $key) { 
     $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_string, MCRYPT_MODE_ECB); 
     return trim($decrypted_text); 
    } 

    echo $test_str = 'This is a really cool teststring'; echo '<br />'; 
    $enc_str = string_encrypt($test_str, $key); 
    echo bin2hex($enc_str);          echo '<br />'; 
    echo string_decrypt($enc_str, $key);      echo '<br />'; 

    ?> 

Выход РНР: e355fbcd91ada4b835e1b030cc9741759219f59fe441ba62e628eca2e8289eb3

Это Delphi код:

function encrypt(s:PWideChar;mode,padding:integer;algo,cipher,keylength:string):string; 
var 
crypt: HCkCrypt2; 
success: Boolean; 
ivHex: PWideChar; 
keyHex: PWideChar; 
encStr: PWideChar; 
decStr: PWideChar; 

begin 
crypt := CkCrypt2_Create(); 

// AES is also known as Rijndael. 
CkCrypt2_putCryptAlgorithm('aes'); 
// "pki", "aes", "blowfish", "blowfish2", "des", "3des", "rc2", "arc4", "twofish", "pbes1" and "pbes2" 

// CipherMode may be "ecb" or "cbc" 
CkCrypt2_putCipherMode(crypt,'ecb'); 

// KeyLength may be 128, 192, 256 
try 
    CkCrypt2_putKeyLength(crypt,128); 
Except 
    showmessage('The encryption key you have used seems to be invalid'); 
end; 


// The padding scheme determines the contents of the bytes 
// that are added to pad the result to a multiple of the 
// encryption algorithm's block size. AES has a block 
// size of 16 bytes, so encrypted output is always 
// a multiple of 16. 

{ 
Possible values are: 

0 = RFC 1423 padding scheme: Each padding byte is set to the number of padding bytes. 
If the data is already a multiple of algorithm's block size bytes, an extra block is 
appended each having a value equal to the block size. (for example, if the algorithm's 
block size is 16, then 16 bytes having the value 0x10 are added.). (This is also known as 
PKCS5 padding: PKCS #5 padding string consists of a sequence of bytes, each of which 
is equal to the total number of padding bytes added.) 

1 = FIPS81 (Federal Information Processing Standards 81) where the last byte contains 
the number of padding bytes, including itself, and the other padding bytes are set to random values. 

2 = Each padding byte is set to a random value. The decryptor must know 
how many bytes are in the original unencrypted data. 

3 = Pad with NULLs. (If already a multiple of the algorithm's block size, 
no padding is added). 

4 = Pad with SPACE chars(0x20). (If already a multiple of algorithm's block size, no padding is added). 
} 
CkCrypt2_putPaddingScheme(crypt,3); 

// EncodingMode specifies the encoding of the output for 
// encryption, and the input for decryption. 
// It may be "hex", "url", "base64", or "quoted-printable". 
CkCrypt2_putEncodingMode(crypt,'hex'); 

// An initialization vector is required if using CBC mode. 
// ECB mode does not use an IV. 
// The length of the IV is equal to the algorithm's block size. 
// It is NOT equal to the length of the key. 
ivHex := ''; 
CkCrypt2_SetEncodedIV(crypt,ivHex,'hex'); 

// The secret key must equal the size of the key. For 
// 256-bit encryption, the binary secret key is 32 bytes. 
// For 128-bit encryption, the binary secret key is 16 bytes. 

keyHex := '1234567890ABE1234567890ABE1234DB'; 
CkCrypt2_SetEncodedKey(crypt,keyHex,'hex'); 

// Encrypt a string... 
// The input string is 44 ANSI characters (i.e. 44 bytes), so 
// the output should be 48 bytes (a multiple of 16). 
// Because the output is a hex string, it should 
// be 96 characters long (2 chars per byte). 


//encryption 
if mode = 0 then 
begin 
    encStr := CkCrypt2__encryptStringENC(crypt,s); 
    result := encStr; 
end 
else 
begin 
    result := CkCrypt2__decryptStringENC(crypt,s); 
end; 


CkCrypt2_Dispose(crypt); 
End; 

chillkat Delphi вывода компонента это: 780F849AB30690433409D4FB7B3357735296A6E76D3AA6B6D6C769BE99F32041

Я подумал, оба выхода должны производить такое же значение, как и все входные параметры равны, так?

+0

Вы видели [все эти] (http://stackoverflow.com/questions/tagged/delphi+php+encryption)? –

+0

Я только что их краснул. Было несколько намеков, которые я пытался реализовать, но это не работает. Хотя в одном потоке этот сайт упоминался: [ссылка] (http://aes.online-domain-tools.com/), и этот сайт может зашифровать мой код Delphi и наоборот. – user3868781

ответ

2

MCrypt ожидает, что ключ является двоичной строкой, но вы передаете в нее шестнадцатеричную кодированную строку.

Использование

$key = hex2bin($key); 

или

$key = pack('H*', $key); 

в зависимости от поддержки PHP. Это должно быть сделано до, вызывая mcrypt_encrypt().


Безопасность:

Не когда-либо использовать режим ECB. Это не семантически безопасно. Существует много того, что злоумышленник может получить от зашифрованных текстов без их расшифровки. Вам нужно использовать по крайней мере режим CBC со случайным IV. У вас также должен быть тег проверки подлинности ваших зашифрованных текстов.

This answer дает вам все, что вам нужно знать об этом. Осталось одно: не используйте MCrypt. Это старая невоспитанная библиотека.

This answer также очень полезно в этом отношении с другим способом достижения того же.

+0

Выход не изменяется, если я добавляю эту строку. Кроме того, мне пришлось добавить функцию hex2bin вручную, так как ее нельзя было найти на моем сервере. – user3868781

+0

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

+0

«Мне пришлось добавить функцию hex2bin вручную, так как ее не удалось найти на моем сервере». Какую версию PHP вы используете? –

0

благодаря вашим вашим хорошим входам, я был в состоянии получить положительный ответ от сервера со следующими 4 строк коды:

$key = pack('H*', "*5DB"); 
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$mytxt, MCRYPT_MODE_ECB); 
$hex2 = bin2hex($ciphertext); 
echo strtoupper($hex2); 

Однако я узнал, что

  • ЕЦБ небезопасна
  • Mcrypt стар и не сопровождаются

Я проверю алтернативный и обновить мой код соответственно. Еще раз спасибо !