Вот демонстрационный скрипт PHP, который шифрует и расшифровывает данные:
<? $encryptionkey = 'h8y2p9d1'; $card_nbr = "1234"; echo "original card_nbr: $card_nbr <br>\n"; $card_nbr_encrypted=encrypt_data($card_nbr); echo "card_nbr_encrypted: $card_nbr_encrypted <br>\n"; $card_nbr_decrypted=decrypt_data($card_nbr_encrypted); echo "card_nbr_decrypted: $card_nbr_decrypted <br>\n"; $len=strlen($card_nbr_decrypted); echo "length: $len <br>\n"; function encrypt_data($text){ global $encryptionkey; $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $encrypted_text = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $encryptionkey, $text, MCRYPT_MODE_ECB, $iv); return $encrypted_text; } function decrypt_data($text){ global $encryptionkey; $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); $decrypted_text = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $encryptionkey, $text, MCRYPT_MODE_ECB, $iv); return $decrypted_text; } ?>
Выход:
original card_nbr: 1234 card_nbr_encrypted: vY¨(Z$<§G3-žÃ-Éù3Ý2Ê×rz¨VÛ card_nbr_decrypted: 1234 (and 28 binary characters) length: 32
Выход успешно дешифрован, но к концу добавляется 28 двоичных символов. Это можно наиболее легко увидеть в Firefox при просмотре HTML-источника. Строка длиной 32 также демонстрирует это. Есть идеи?
Возвращаемая строка заполняется, чтобы заполнить байты n * blocksize
используя нулевой символ \0
, поэтому вы видите дополнительные данные.
Если вы запустите $card_nbr_decrypted= rtrim($card_nbr_decrypted, "\0");
он должен вернуть фактические данные.
Кажется, это известная проблема . Используйте rtrim()
после декодирования, чтобы удалить избыточные NUL.
Вы получаете нулевые байты, потому что используете блок электронного кода (ECB) для режима работы блочного шифрования , который заполняет конец вашего открытого текста, чтобы вписаться в размер блока. В вашем случае размер блока составляет 256 бит, потому что вы используете MCRYPT_RIJNDAEL_256
.
Вы можете избежать этой проблемы заполнения, если используете режим обратной связи Cipher (CFB) – MCRYPT_MODE_CFB
– нет нулевых байтов, нет необходимости обрезать. Но с CFB вы должны HMAC зашифрованные данные, чтобы убедиться, что он не был подделан (см. «Маллет») . Вы можете найти пример рабочей реализации в: Cryptography For the Average Developer .
Также следует отметить, что режим ECB считается менее безопасным, поскольку он может выявлять шаблоны данных . Кроме того, ECB (и CBC с тех пор, как он также работает) может быть уязвим для атаки оракула .
Я думаю, проблема в том, что вы используете двоичные данные, когда:
mcrypt_encrypt – Шифрует открытый текст с заданными параметрами
Вы можете использовать base64_encode ($ text) для использования открытого текста.