Формат открытого ключа OpenSSH (и формат проводника SSH, на котором он основан) действительно начинается с типа, но для ECDSA тип включает идентификатор кривой.Например, одна из моих тестовых систем имеет ключ ecdsa / p256 следующим образом:
$ awk '{print $2}' <id_ecdsa.pub |openssl base64 -d -A |xxd
0000000: 0000 0013 6563 6473 612d 7368 6132 2d6e ....ecdsa-sha2-n
0000010: 6973 7470 3235 3600 0000 086e 6973 7470 istp256....nistp
0000020: 3235 3600 0000 4104 8141 9c28 53e7 532e 256...A..A.(S.S.
0000030: 8c4b 9781 c6a5 1820 f41a bc95 4e62 13a9 .K..... ....Nb..
0000040: 8356 a517 be55 6ebc fbf4 de74 e216 8f17 .V...Un....t....
0000050: 6222 011c 5920 a3fc caed c880 4298 46d5 b"..Y ......B.F.
0000060: dd39 396e d72d 1e40 .99n.-.@
, который состоит из:
4 байта 00000013 bigendian int = 19: длина типа
19 байтовТип 'ecdsa-sha2-nistp256'
4 байта 00000008 bigendian int = 8: длина кривой
8 байтов: длина точки публикации
65 байт, начиная с 04: точка публикации в формате X9.62, более удобно скопированная в SEC1, которая составляет 1 байт 04 = несжатый, N-байтовая X-координата, N байтов Y-координата, где N - это(фиксированный) размер, необходимый для представления нижележащего поля кривой как беззнакового.
В основном они определены в rfc5656, раздел 3.1 , а значения кривой в 6.1.RFC допускает формат сжатых точек, но OpenSSH не использует эту опцию.
BCECPublicKey.getEncoded()
(как и все классы Java PublicKey) возвращает так называемое кодирование X.509 (на самом деле SubjectPublicKeyInfo, SPKI), которое для EC включает в себя публичную точку в несжатом формате X9.62, но для ее извлечения необходим некоторый анализ.Поскольку у вас есть BC, проще всего это использовать:
byte[] point = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(encoded)).getPublicKeyData().getOctets();
В качестве альтернативы .getW()
и .getQ()
получить точку в виде класса JCE или BC, из любого из которых вы можете получить (аффинный) Xи координаты Y как BigInteger
соотв.ECFieldElement
, что, в свою очередь, дает BigInteger
, и каждый BigInteger
может быть преобразован в массив байтов переменного размера, который вы затем должны урезать слева или слева до правильного размера.
Результатом являются хешируемые данные.Если вы не знаете, только OpenSSH версии 6.8 и выше используют base64 (sha256 (pubkey)) для отпечатка пальца (по умолчанию).До этого это был hex-with-двоеточия (md5 (pubkey)), и более новые версии могут сделать старый отпечаток для совместимости (см. Параметр FingerprintHash
в ssh_config
для ssh
и флаг -E
в ssh-keygen
).
И чтобы быть ясным, это всего лишь OpenSSH отпечаток пальца.Отпечатки клавиш также используются в мирах PGP и X.509 / PKIX (SSL / TLS, CMS / SMIME и т. Д.), И они совершенно разные.