Как вычислить правильное значение KCV для ключа шифрования 3des?
Я пытаюсь вычислить KCV для шифрования DES.
$data = 'F337CE3C64E02D96C61A9EC69E051D5A';
$transport = '4B4D3733504D3735';
$encData = bin2hex(mcrypt_encrypt(MCRYPT_DES, pack('H*', $transport),
$data, MCRYPT_MODE_ECB));
Все в порядке, данные шифруются должным образом.
Теперь я хочу вычислить KCV.
$key = 'F337CE3C64E02D96C61A9EC69E051D5A';
$zeroBytes = 00000000;
$kcv = bin2hex(mcrypt_encrypt(MCRYPT_3DES, $key, $zeroBytes, MCRYPT_MODE_ECB));
var_dump($kcv);
Это возвращает неправильное значение: 953f34d098f996f9 и оно должно быть (конечное kcv) 53173F.
2 ответа:
Я вижу две проблемы с вашим кодом: 1. Ключ должен быть двоичным, 2. Следует использовать нулевые байты, а не целочисленные нули.
$key = pack('H*', '0123456789ABCDEF'); $data = "\0\0\0\0\0\0\0\0"; $kcv = strtoupper(bin2hex(mcrypt_encrypt(MCRYPT_3DES, $key, $data, MCRYPT_MODE_ECB))); var_dump($kcv);
Это выводит
D5D44FF720683D0D
как ожидалось (KCV для ключа0123456789ABCDEF
являетсяD5D44FF720683D0D
).EDIT: в вашем случае вам нужно добавить первые 16 символов в конец ключа, чтобы получить правильный KCV:
$key = 'F337CE3C64E02D96C61A9EC69E051D5A'; $key .= substr($key, 0, 16); $key = pack('H*', $key); $data = "\0\0\0\0\0\0\0\0"; $kcv = strtoupper(bin2hex(mcrypt_encrypt(MCRYPT_3DES, $key, $data, MCRYPT_MODE_ECB))); var_dump($kcv);
Это выводит
53173F8B139F34FE
. Дополнительные сведения см. В разделе параметры ввода:Стандарты определяют три варианта манипулирования ключами:
- Вариант 1: Все три ключа независимы.
Вариант 2: K1 и K2 независимы, а K3 = K1. Вариант 3: Все три ключа идентичны, т. е. K1 = K2 = K3.
Я не криптограф, но быстрый поиск в Google говорит, что 3DES KCV должен быть вычислен по "строке двоичных нулей", а
$zeroBytes = 00000000;
- это не так.PHP прочитает это как
0
, а затем введет его в нулевой символ ASCII, он же0x30
.Я думаю, что вы хотите:
$zeroBytes = "\0\0\0\0\0\0\0\0";
Который даст вам восемь нулевых байт, он же
0x00
.