Как рассчитать отпечаток пальца из открытого ключа SSH RSA в Java? - PullRequest
0 голосов
/ 27 июня 2018

Как заголовок, Как рассчитать отпечаток пальца из открытого ключа SSH RSA в Java? Я получил объект rsaPublicKey из sample.pub и вычислил отпечаток с помощью библиотеки Apache Commons Codec DigestUtils.sha256Hex(rsaPublicKey.getEncoded()); Но я получил другой отпечаток при использовании команды ssh-keygen ssh-keygen -E sha256 -lf sample.pub sample.pub как ниже ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAsuVPKUpLYSCNVIHD+e6u81IUznkDoiOvn/t56DRcutRc4OrNsZZ+Lmq49T4JCxUSmaT8PeLGS/IC946CNQzFwMh++sVoc19UUkZtRaDgiYn+HkYk8VW4IFI1dKfXomKSbX/lB+ohzLzXLVP2/UJgfBmdaE10k+6b+/Yd8YGXIeS8/Z9zToHPo0ORNSGIolgq3xMXUtfAOK/0KC6IFc/FuvuOSAG1UWup91bcm5GSXv4BWWjgFtOxCLIknYjsDah4qfrP8Olp5eUDhn/65xRcZsmRXoYe1ylhlSjJoPDFWXVs9npwqQmi3JaZtgg7xJxMu1ZcdpYxoj280zM9/6w1Lw==

1 Ответ

0 голосов
/ 27 июня 2018

Ваша основная проблема заключается в том, что кодировка *1001* в стиле , используемая SSH для publickey, которую OpenSSH использует для вычисления отпечатка пальца, не совпадает с кодировкой, используемой в криптографии Java, являющейся ASN. 1 Формат DER, определенный X.509, формально называется SubjectPublicKeyInfo. На самом деле я очень удивлен, что вы смогли прочитать файл OpenSSH .pub на Java; прямого пути для этого нет. Посмотрите многочисленные существующие Qs по этому вопросу на ssh-keygen и openssl дают два разных открытых ключа (раскрытие: мое), но при быстрой проверке я не думаю, что какой-либо из них является Java, так что вам нужно будет сделать что-то вроде:

byte[] n = rsapubkey.getModulus().toByteArray(); // Java is 2sC bigendian
byte[] e = rsapubkey.getPublicExponent().toByteArray(); // and so is SSH
byte[] tag = "ssh-rsa".getBytes(); // charset very rarely matters here
ByteArrayOutputStream os = new ByteArrayOutputStream();
DataOutputStream do = new DataOutputStream(os);
do.writeInt(tag.length); do.write(tag);
do.writeInt(e.length); do.write(e);
do.writeInt(n.length); do.write(n);
byte[] encoded = os.toByteArray();
// now hash that (you don't really need Apache) 
// assuming SHA256-base64 (see below)
MessageDigest digest = MessageDigest.getInstance("SHA256");
byte[] result = digest.digest(encoded);
String output = Base64.getEncoder().encodeToString(result);

(Кроме того: Спасибо linc01n за обнаружение ошибки - я стараюсь всегда компилировать перед публикацией, и я не уверен, как я пропустил это.)

Вторая проблема заключается в том, что OpenSSH никогда не отображал отпечатки SHA256 в шестнадцатеричном формате. Первоначально он использовал MD5 отпечатки пальцев в шестнадцатеричном виде с двоеточиями; в 6.8 он по умолчанию переключился на SHA256 в base64 (используя традиционный алфавит, а не 'URLsafe', предпочитаемый JSON), хотя вы все равно можете получить более старую форму (в ssh используйте -oFingerprintHash=md5 или эквивалентная настройка конфигурации; в ssh-keygen -l используйте -E md5). Определите, какой из них вы хотите, и укажите соответствующий код.

Или, если у вас есть файл .pub, просто прочитайте второе разделенное пробелами поле одной строки, преобразуйте из base64 в byte[], хэшируйте его и отобразите.

...