Как я могу конвертировать открытый ключ DSA из формата OpenSSL в формат OpenSSH в PHP?
Я использовал ключи RSA в своем приложении. Я использовал следующий код для преобразования ключа RSA из формата OpenSSL в формат OpenSSH. Это отлично работало для ключа RSA. Теперь я хочу поддерживать ключи DSA. Но мой код преобразования не работает для ключей DSA. Какая модификация мне нужна, чтобы заставить его работать с ключами DSA?
$private_key = openssl_pkey_get_private($rsaKey);
$public_key = sshEncodePublicKey($private_key);
echo "RSA public key in OpenSSH format:\n$pubKey\n\n";
function sshEncodePublicKey($privKey)
{
$keyInfo = openssl_pkey_get_details($privKey);
$buffer = pack("N", 7) . "ssh-rsa" .
sshEncodeBuffer($keyInfo['rsa']['e']) .
sshEncodeBuffer($keyInfo['rsa']['n']);
return "ssh-rsa " . base64_encode($buffer);
}
function sshEncodeBuffer($buffer)
{
$len = strlen($buffer);
if (ord($buffer[0]) & 0x80) {
$len++;
$buffer = "\x00" . $buffer;
}
return pack("Na*", $len, $buffer);
}
1 answers
Определение ключа dsa принципиально отличается от определения ключей rsa. Там нет "экспоненты" (числа, к которому вы обращаетесь с помощью $keyInfo['rsa']['e']
и нет n
.
Поскольку ваш код анализирует ключ и повторно кодирует его, это не удастся с ключами dsa. Вместо этого openssl_pkey_get_details
предоставляет вам совершенно другой массив элементов, как указано в руководстве.
Чтобы преобразовать это, используйте следующий код:
function sshEncodePublicKey($privKey)
{
$keyInfo = openssl_pkey_get_details($privKey);
$buffer = pack("N", 7) . "ssh-dss" .
sshEncodeBuffer($keyInfo['dsa']['p']) .
sshEncodeBuffer($keyInfo['dsa']['q']) .
sshEncodeBuffer($keyInfo['dsa']['g']) .
sshEncodeBuffer($keyInfo['dsa']['pub_key']);
return "ssh-dss " . base64_encode($buffer);
}
Конечно, ваш код должен решить, какой это тип ключа, но я думаю, я могу оставить это тебе.
Пожалуйста, также обратите внимание, что PHP имеет функцию openssl_pkey_get_public, которая более подходит. Я использовал это для тестирования приведенного выше кода (я просто заменил ваши первые 4 строки на $public_key = sshEncodePublicKey(openssl_pkey_get_public('file://ssl.pub'));