У меня проблема с 3DES PHP. Я делаю проект, который будет иметь доступ к внутреннему интерфейсу банка. Они разработали интерфейс Java.
Одной из функций интерфейса является то, что банковская система получит открытый ключ RSA от моего сервера. Банковская сторона — это клиент. Он получает доступ к моему серверу по протоколу HTTP. Они требовали, чтобы открытый ключ RSA был зашифрован 3DES. Ключ для 3DES — «1000000200YYMMDD». И они требовали, чтобы результат был отправлен обратно потоком байтов.
Я загружаю несколько программ 3DES из сети. Они могут получить зашифрованную строку. Но все они потерпели неудачу на стороне банка. Ответ — «строковый индекс вне диапазона». Я думаю, что это сообщение является просто системным сообщением и имело мало значения для отладки.
Ниже моя программа.
У меня было несколько вопросов по этой проблеме.
1, Многие materail сказали, что длина ключа 3DES не более 168 байт. Как я могу расширить свой ключ на эту длину. Я имею в виду, что ключ «1000000200YYMMDD» составляет всего 16 символов, как конвертировать в 168 байтов.
2. Какая разница между PHP и JAVA в 3DES шифровании.
3, какой режим блока выбрать? ЕЦБ? CBC?
4. Какой вид прокладки мне следует использовать?
//encrypt method 1
public function DESencrypt($str)
{
if ($this->mcrypt == MCRYPT_DES) $str = $this->_pkcs5Pad($str);
$block = mcrypt_get_block_size($this->mcrypt, $this->mode);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
$result = mcrypt_encrypt($this->mcrypt, base64_encode($this->des_key), $str, $this->mode);
return $result;
}
//encrypt method 2
public function encrypt_1($input)
{
$td = mcrypt_module_open(MCRYPT_TRIPLEDES, '', 'ecb', '');
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $this->des_key, $iv);
$encrypted_data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return $encrypted_data;
}
//encrypt method 3
function encrypt($str)
{
$block = mcrypt_get_block_size(MCRYPT_TRIPLEDES, MCRYPT_MODE_ECB);
$pad = $block - (strlen($str) % $block);
$str .= str_repeat(chr($pad), $pad);
return mcrypt_encrypt(MCRYPT_3DES, $this->des_key, $str, MCRYPT_MODE_ECB);
}
//encrypt method 4
public function encrypt_2($input)
{
$key = $this->des_key.$this->des_key;
$tripleKey = substr($key, 0, mcrypt_get_key_size($this->mcrypt, $this->mode));
$blocksize = mcrypt_get_block_size($this->mcrypt, $this->mode);
$paddingSize = $blocksize - (strlen($input) % $blocksize);
$input .= str_repeat(chr($paddingSize), $paddingSize);
$encodedText = mcrypt_encrypt($this->mcrypt, $tripleKey, $input, $this->mode);
return $encodedText;
}///the main function
$des_key="1000000200YYMMDD";
///Initialize the encrypt class
$c = new Xcrypt($des_key);
/// Set the encrypt algorithm to 3DES
$c->setMcrypt(MCRYPT_3DES);
/// Get the RSA public key
$pub = $c->get_ZGSC_public();
// here I will encrypt the RSA key, I had used all the four method above, but all failed
$encyt_pub = $c->encrypt_2($pub);
///return to the client in byte stream.
file_put_contents("php://output", getBytes(base64_encode($encyt_pub)));
Задача ещё не решена.
Других решений пока нет …