Как получить хэш открытого ключа для закрепления SSL?

Как мне получить хэш информации об общедоступном сертификате, чтобы иметь возможность выполнять SSL-закрепление в моем приложении?

Я использую TrustKit в своем приложении для iOS, и он просит меня установить ожидаемый хэш. Откуда я могу это получить?


person mylogon    schedule 03.11.2016    source источник
comment
Как мне найти резервный ключ?   -  person jww    schedule 03.11.2016


Ответы (3)


Если это общедоступный веб-сайт, вы можете использовать серверный тест SSL Labs, который вычисляет и отображает штырь.

Отчет Лаборатории SSL с указанием булавки

На странице закрепления открытого ключа в сети разработчиков Mozilla также есть команды для получения пин-кода из ключевого файла, запроса на подпись сертификата, сертификата или веб-сайта (это тот, который находится в ответ @ mylogon).

person Anand Bhat    schedule 03.11.2016
comment
Хорошее объяснение, спасибо. Могу ли я узнать причину, по которой OpenSSL является недружественной утилитой для работы с сертификатами? - person Fazal Hussain; 16.06.2021

Поскольку это веб-сайт программирования, я хотел объяснить, как вычислить хэш открытого ключа для закрепления открытого ключа. Это важно, потому что алгоритм полностью недокументирован. (Это даже не задокументировано каноническим RFC 7469 расширением закрепления открытого ключа для HTTP ! В RFC просто сказано «Используйте OpenSSL». Это не ответ.)

tl; dr: Base64(SHA256(SubjectPublicKeyInfo))

Структура сертификата

Первое, что нужно понять, это то, что открытый ключ - это просто число (например, 2048-битное число для RSA). Сертификат - это набор большого количества дополнительной информации (имена субъектов, хэши, цифровые подписи).

Это означает, что:

  • сертификат связывает веб-сайт с этим номером (например, stackoverflow.com)
  • SHA256: 854206f3b721ef511941885904492ad952812e386eb2c530ee747cc32b98eeb6 (шестнадцатеричный)

Пин-код открытого ключа содержит хэш открытого ключа. Это не хеш сертификата. Это позволяет обновлять сертификаты, сохраняя при этом открытый ключ.

Но что я на самом деле хэширую?

Нам нужно извлечь открытый ключ из сертификата, поэтому нам нужно знать его структуру. Структура сертификата задокументирована (ужасно) в RFC 5280 - Сертификат инфраструктуры открытого ключа Internet X.509 и отзыв сертификата Список (CRL) профиля

С точки зрения программирования Сертификат - это:

struct Certificate {
   TBSCertificate      tbsCertificate,
   AlgorithmIdentifier signatureAlgorithm,
   BITSTRING           signatureValue
}

И именно SubjectPublicKeyInfo внутри tbsCertificate содержит то, что нам нужно:

struct TBSCertificate {
    EXPLICIT                version,
    CertificateSerialNumber serialNumber,
    AlgorithmIdentifier     signature,
    Name                    issuer,
    Validity                validity,
    Name                    subject,
    SubjectPublicKeyInfo    subjectPublicKeyInfo,
    //...optional extra stuff...
    }

Нам нужно взять SHA256 необработанного subjectPublicKeyInfo.

digest = SHA256(certificate.tbsCertificate.subjectPublicKeyInfo);    

Это значение в кодировке base64 становится значением, которое мы помещаем в заголовки ответа нашего веб-сервера:

String pin = String.Format("max-age=%d; pin-sha256=\"%s\"", 
    31536000, //1 year
    System.Convert.ToBase64(digest));
response.Headers.Add("Public-Key-Pins",  pin);

Например:

Public-Key-Pins: max-age=31536000; pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY=";

Что много

В качестве примера вычисления хэша PKP SHA256 я собираюсь использовать текущий сертификат Facebook.com. Вы можете перейти на Facebook, просмотреть сертификат и сохранить его в DER PEM с кодировкой base64:

Facebook.cer (в кодировке PEM DER ASN.1)

-----BEGIN CERTIFICATE-----
MIIH5DCCBsygAwIBAgIQDACZt9eJyfZmJjF+vOp8HDANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
dXJhbmNlIFNlcnZlciBDQTAeFw0xNjEyMDkwMDAwMDBaFw0xODAxMjUxMjAwMDBa
MGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRMwEQYDVQQHEwpN
ZW5sbyBQYXJrMRcwFQYDVQQKEw5GYWNlYm9vaywgSW5jLjEXMBUGA1UEAwwOKi5m
YWNlYm9vay5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASg8YyvpzmIaFsT
Vg4VFbSnRe8bx+WFPCsE1GWKMTEi6qOS7WSdumWB47YSdtizC0Xx/wooFJxP3HOp
s0ktoHbTo4IFSjCCBUYwHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjsw
HQYDVR0OBBYEFMuYKIyhcufiMqmaPfINoYFWoRqLMIHHBgNVHREEgb8wgbyCDiou
ZmFjZWJvb2suY29tgg4qLmZhY2Vib29rLm5ldIIIKi5mYi5jb22CCyouZmJjZG4u
bmV0ggsqLmZic2J4LmNvbYIQKi5tLmZhY2Vib29rLmNvbYIPKi5tZXNzZW5nZXIu
Y29tgg4qLnh4LmZiY2RuLm5ldIIOKi54eS5mYmNkbi5uZXSCDioueHouZmJjZG4u
bmV0ggxmYWNlYm9vay5jb22CBmZiLmNvbYINbWVzc2VuZ2VyLmNvbTAOBgNVHQ8B
Af8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHUGA1UdHwRu
MGwwNKAyoDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWhhLXNlcnZl
ci1nNS5jcmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWhh
LXNlcnZlci1nNS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAQEwKjAoBggrBgEF
BQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBAgIwgYMG
CCsGAQUFBwEBBHcwdTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
Y29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
aUNlcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAA
MIICsAYKKwYBBAHWeQIEAgSCAqAEggKcApoAdgCkuQmQtBhYFIe7E6LMZ3AKPDWY
BPkb37jjd80OyA3cEAAAAVjl02IEAAAEAwBHMEUCIQDvWFsUeqWE/xwIYcXPvbb5
ExzfHBZTNwfnUf4RPO/lBgIgdOGmr0j7+u8/S+7tfFw71ZEjqpwJELl/sEFuQdPn
pwQBLwCsO5rtf6lnR1cVnm19V1Zy+dmBAJQem97/7KExO3V4LQAAAVjl02IoAAAE
AQEAYvnMV+BfP3Wrk4yFQE/Zx5WsjSabYOpLj1Tj5xFaoVoHdGqLCf/Hi+Vv0IRy
ePKFBCSW0+3eA589+WnCDMwcJlBYeZV8MlvHFZg3a66Uhx/OAvoetb0mCtUpnmIE
UwLX/eMNEvjg2qTH3/33ysCo2l25+/EcR8upF+2KIcmnk5WwaJzfq7cFPQc4Cvcz
mTHasJi/jmVaIaJ9HC50g3dx584TQX26lDLddF/Li4uEbJ7TSopnTzjQdWBtWbMF
h3bcfhFCKaqK2kIJV3bgup5HibEnZ2LPm6lekY072ZFCGM4QYc4ukqzou2JWCRmG
o0dMHJhnvQXpnIQGwATqCD4Q1AB2AFYUBpov18Ls0/XhvUSyPsdGdrm8mRFcwO+U
mFXWidDdAAABWOXTYrkAAAQDAEcwRQIgGhXXbwUO5bD4Ts/Q0gqZwUS2vl/A4Hem
k7ovxl82v9oCIQCbtkflDXbcunY4MAQCbKlnesPGc/nftA84xDhJpxFHWQB3AO5L
vbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABWOXTZBEAAAQDAEgwRgIh
AKubngQoa5Iak8eCOrffH7Xx3AP1NMb5pFw35nt2VSeRAiEA47Kq1UQcDXIEsV+W
nuPd9LM5kpdeu0+TiHKtTLRQr0swDQYJKoZIhvcNAQELBQADggEBADrNSsoonbj1
YGjwy9t9wP9+kZBwrNMO2n5N5fQNhGawkEAX+lXlzgm3TqYlTNi6sCFbPBAErim3
aMVlWuOlctgnjtAdmdWZ4qEONrBLHPGgukDJ3Uen/EC/gwK6KdBCb4Ttp6MMPY1c
hb/ciTLi3QUUU4h4OJWqUjvccBCDs/LydNjKWZZTxLJmxRSmfpyCU3uU2XHHMNlo
8UTIlqZsOtdqhg7/Q/cvMDHDkcI/tqelmg0MD2H9KpcmAvVkwgjn+BVpv5HELl+0
EP0UhYknI1B6LBecJuj7jI26eXZdX35CYkpI/SZA9KK+OYKHh6vCxKqnRZ9ZQUOj
XnIWKQeV5Hg=
-----END CERTIFICATE-----

Все вышеперечисленное закодировано в base64. Расшифруем его в шестнадцатеричный формат:

Facebook.cer (в кодировке DER ASN.1)

30 82 07 e4 30 82 06 cc a0 03  02 01 02 02 10 0c 00 99 b7 d7  89 c9 f6 66 26 31 7e bc ea 7c  1c 30 0d 06 09 2a 86 48 86 f7 
0d 01 01 0b 05 00 30 70 31 0b  30 09 06 03 55 04 06 13 02 55  53 31 15 30 13 06 03 55 04 0a  13 0c 44 69 67 69 43 65 72 74 
20 49 6e 63 31 19 30 17 06 03  55 04 0b 13 10 77 77 77 2e 64  69 67 69 63 65 72 74 2e 63 6f  6d 31 2f 30 2d 06 03 55 04 03 
13 26 44 69 67 69 43 65 72 74  20 53 48 41 32 20 48 69 67 68  20 41 73 73 75 72 61 6e 63 65  20 53 65 72 76 65 72 20 43 41 
30 1e 17 0d 31 36 31 32 30 39  30 30 30 30 30 30 5a 17 0d 31  38 30 31 32 35 31 32 30 30 30  30 5a 30 69 31 0b 30 09 06 03 
55 04 06 13 02 55 53 31 13 30  11 06 03 55 04 08 13 0a 43 61  6c 69 66 6f 72 6e 69 61 31 13  30 11 06 03 55 04 07 13 0a 4d 
65 6e 6c 6f 20 50 61 72 6b 31  17 30 15 06 03 55 04 0a 13 0e  46 61 63 65 62 6f 6f 6b 2c 20  49 6e 63 2e 31 17 30 15 06 03 
55 04 03 0c 0e 2a 2e 66 61 63  65 62 6f 6f 6b 2e 63 6f 6d 30  59 30 13 06 07 2a 86 48 ce 3d  02 01 06 08 2a 86 48 ce 3d 03 
01 07 03 42 00 04 a0 f1 8c af  a7 39 88 68 5b 13 56 0e 15 15  b4 a7 45 ef 1b c7 e5 85 3c 2b  04 d4 65 8a 31 31 22 ea a3 92 
ed 64 9d ba 65 81 e3 b6 12 76  d8 b3 0b 45 f1 ff 0a 28 14 9c  4f dc 73 a9 b3 49 2d a0 76 d3  a3 82 05 4a 30 82 05 46 30 1f 
06 03 55 1d 23 04 18 30 16 80  14 51 68 ff 90 af 02 07 75 3c  cc d9 65 64 62 a2 12 b8 59 72  3b 30 1d 06 03 55 1d 0e 04 16 
04 14 cb 98 28 8c a1 72 e7 e2  32 a9 9a 3d f2 0d a1 81 56 a1  1a 8b 30 81 c7 06 03 55 1d 11  04 81 bf 30 81 bc 82 0e 2a 2e 
66 61 63 65 62 6f 6f 6b 2e 63  6f 6d 82 0e 2a 2e 66 61 63 65  62 6f 6f 6b 2e 6e 65 74 82 08  2a 2e 66 62 2e 63 6f 6d 82 0b 
2a 2e 66 62 63 64 6e 2e 6e 65  74 82 0b 2a 2e 66 62 73 62 78  2e 63 6f 6d 82 10 2a 2e 6d 2e  66 61 63 65 62 6f 6f 6b 2e 63 
6f 6d 82 0f 2a 2e 6d 65 73 73  65 6e 67 65 72 2e 63 6f 6d 82  0e 2a 2e 78 78 2e 66 62 63 64  6e 2e 6e 65 74 82 0e 2a 2e 78 
79 2e 66 62 63 64 6e 2e 6e 65  74 82 0e 2a 2e 78 7a 2e 66 62  63 64 6e 2e 6e 65 74 82 0c 66  61 63 65 62 6f 6f 6b 2e 63 6f 
6d 82 06 66 62 2e 63 6f 6d 82  0d 6d 65 73 73 65 6e 67 65 72  2e 63 6f 6d 30 0e 06 03 55 1d  0f 01 01 ff 04 04 03 02 07 80 
30 1d 06 03 55 1d 25 04 16 30  14 06 08 2b 06 01 05 05 07 03  01 06 08 2b 06 01 05 05 07 03  02 30 75 06 03 55 1d 1f 04 6e 
30 6c 30 34 a0 32 a0 30 86 2e  68 74 74 70 3a 2f 2f 63 72 6c  33 2e 64 69 67 69 63 65 72 74  2e 63 6f 6d 2f 73 68 61 32 2d 
68 61 2d 73 65 72 76 65 72 2d  67 35 2e 63 72 6c 30 34 a0 32  a0 30 86 2e 68 74 74 70 3a 2f  2f 63 72 6c 34 2e 64 69 67 69 
63 65 72 74 2e 63 6f 6d 2f 73  68 61 32 2d 68 61 2d 73 65 72  76 65 72 2d 67 35 2e 63 72 6c  30 4c 06 03 55 1d 20 04 45 30 
43 30 37 06 09 60 86 48 01 86  fd 6c 01 01 30 2a 30 28 06 08  2b 06 01 05 05 07 02 01 16 1c  68 74 74 70 73 3a 2f 2f 77 77 
77 2e 64 69 67 69 63 65 72 74  2e 63 6f 6d 2f 43 50 53 30 08  06 06 67 81 0c 01 02 02 30 81  83 06 08 2b 06 01 05 05 07 01 
01 04 77 30 75 30 24 06 08 2b  06 01 05 05 07 30 01 86 18 68  74 74 70 3a 2f 2f 6f 63 73 70  2e 64 69 67 69 63 65 72 74 2e 
63 6f 6d 30 4d 06 08 2b 06 01  05 05 07 30 02 86 41 68 74 74  70 3a 2f 2f 63 61 63 65 72 74  73 2e 64 69 67 69 63 65 72 74 
2e 63 6f 6d 2f 44 69 67 69 43  65 72 74 53 48 41 32 48 69 67  68 41 73 73 75 72 61 6e 63 65  53 65 72 76 65 72 43 41 2e 63 
72 74 30 0c 06 03 55 1d 13 01  01 ff 04 02 30 00 30 82 02 b0  06 0a 2b 06 01 04 01 d6 79 02  04 02 04 82 02 a0 04 82 02 9c 
02 9a 00 76 00 a4 b9 09 90 b4  18 58 14 87 bb 13 a2 cc 67 70  0a 3c 35 98 04 f9 1b df b8 e3  77 cd 0e c8 0d dc 10 00 00 01 
58 e5 d3 62 04 00 00 04 03 00  47 30 45 02 21 00 ef 58 5b 14  7a a5 84 ff 1c 08 61 c5 cf bd  b6 f9 13 1c df 1c 16 53 37 07 
e7 51 fe 11 3c ef e5 06 02 20  74 e1 a6 af 48 fb fa ef 3f 4b  ee ed 7c 5c 3b d5 91 23 aa 9c  09 10 b9 7f b0 41 6e 41 d3 e7 
a7 04 01 2f 00 ac 3b 9a ed 7f  a9 67 47 57 15 9e 6d 7d 57 56  72 f9 d9 81 00 94 1e 9b de ff  ec a1 31 3b 75 78 2d 00 00 01 
58 e5 d3 62 28 00 00 04 01 01  00 62 f9 cc 57 e0 5f 3f 75 ab  93 8c 85 40 4f d9 c7 95 ac 8d  26 9b 60 ea 4b 8f 54 e3 e7 11 
5a a1 5a 07 74 6a 8b 09 ff c7  8b e5 6f d0 84 72 78 f2 85 04  24 96 d3 ed de 03 9f 3d f9 69  c2 0c cc 1c 26 50 58 79 95 7c 
32 5b c7 15 98 37 6b ae 94 87  1f ce 02 fa 1e b5 bd 26 0a d5  29 9e 62 04 53 02 d7 fd e3 0d  12 f8 e0 da a4 c7 df fd f7 ca 
c0 a8 da 5d b9 fb f1 1c 47 cb  a9 17 ed 8a 21 c9 a7 93 95 b0  68 9c df ab b7 05 3d 07 38 0a  f7 33 99 31 da b0 98 bf 8e 65 
5a 21 a2 7d 1c 2e 74 83 77 71  e7 ce 13 41 7d ba 94 32 dd 74  5f cb 8b 8b 84 6c 9e d3 4a 8a  67 4f 38 d0 75 60 6d 59 b3 05 
87 76 dc 7e 11 42 29 aa 8a da  42 09 57 76 e0 ba 9e 47 89 b1  27 67 62 cf 9b a9 5e 91 8d 3b  d9 91 42 18 ce 10 61 ce 2e 92 
ac e8 bb 62 56 09 19 86 a3 47  4c 1c 98 67 bd 05 e9 9c 84 06  c0 04 ea 08 3e 10 d4 00 76 00  56 14 06 9a 2f d7 c2 ec d3 f5 
e1 bd 44 b2 3e c7 46 76 b9 bc  99 11 5c c0 ef 94 98 55 d6 89  d0 dd 00 00 01 58 e5 d3 62 b9  00 00 04 03 00 47 30 45 02 20 
1a 15 d7 6f 05 0e e5 b0 f8 4e  cf d0 d2 0a 99 c1 44 b6 be 5f  c0 e0 77 a6 93 ba 2f c6 5f 36  bf da 02 21 00 9b b6 47 e5 0d 
76 dc ba 76 38 30 04 02 6c a9  67 7a c3 c6 73 f9 df b4 0f 38  c4 38 49 a7 11 47 59 00 77 00  ee 4b bd b7 75 ce 60 ba e1 42 
69 1f ab e1 9e 66 a3 0f 7e 5f  b0 72 d8 83 00 c4 7b 89 7a a8  fd cb 00 00 01 58 e5 d3 64 11  00 00 04 03 00 48 30 46 02 21 
00 ab 9b 9e 04 28 6b 92 1a 93  c7 82 3a b7 df 1f b5 f1 dc 03  f5 34 c6 f9 a4 5c 37 e6 7b 76  55 27 91 02 21 00 e3 b2 aa d5 
44 1c 0d 72 04 b1 5f 96 9e e3  dd f4 b3 39 92 97 5e bb 4f 93  88 72 ad 4c b4 50 af 4b 30 0d  06 09 2a 86 48 86 f7 0d 01 01 
0b 05 00 03 82 01 01 00 3a cd  4a ca 28 9d b8 f5 60 68 f0 cb  db 7d c0 ff 7e 91 90 70 ac d3  0e da 7e 4d e5 f4 0d 84 66 b0 
90 40 17 fa 55 e5 ce 09 b7 4e  a6 25 4c d8 ba b0 21 5b 3c 10  04 ae 29 b7 68 c5 65 5a e3 a5  72 d8 27 8e d0 1d 99 d5 99 e2 
a1 0e 36 b0 4b 1c f1 a0 ba 40  c9 dd 47 a7 fc 40 bf 83 02 ba  29 d0 42 6f 84 ed a7 a3 0c 3d  8d 5c 85 bf dc 89 32 e2 dd 05 
14 53 88 78 38 95 aa 52 3b dc  70 10 83 b3 f2 f2 74 d8 ca 59  96 53 c4 b2 66 c5 14 a6 7e 9c  82 53 7b 94 d9 71 c7 30 d9 68 
f1 44 c8 96 a6 6c 3a d7 6a 86  0e ff 43 f7 2f 30 31 c3 91 c2  3f b6 a7 a5 9a 0d 0c 0f 61 fd  2a 97 26 02 f5 64 c2 08 e7 f8 
15 69 bf 91 c4 2e 5f b4 10 fd  14 85 89 27 23 50 7a 2c 17 9c  26 e8 fb 8c 8d ba 79 76 5d 5f  7e 42 62 4a 48 fd 26 40 f4 a2 
be 39 82 87 87 ab c2 c4 aa a7  45 9f 59 41 43 a3 5e 72 16 29  07 95 e4 78

Но единственная часть, которая нас волнует, - это SubjectPublicKeyInfo:

30 82 07 e4             ;30=SEQUENCE (0x07e4 bytes)
|- tbsCertificate
|  30 82 06 cc                          ;30=SEQUENCE (0x66cc bytes)
|  |- Version (0x03 bytes)
|  |    a0 03 02 01 02
|  |- SerialNumber (0x10 bytes)
|  |    02 10 0c 00 99 b7 d7 89 c9 f6 66 26 31 7e bc ea 7c 1c
|  |- Signature (0x0d bytes)
|  |    30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00
|  |- Issuer (0x70 bytes)
|  |    30 70 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 15 30 13 06 03 55 04 0a 13 0c 44 69 67 69 43 65 72 74 20 49 6e 63 31 19 30 17 06 03 55 04 0b 13 10 77 77 77 2e 64 69 67 69 63 65 72 74 2e 63 6f 6d 31 2f 30 2d 06 03 55 04 03 13 26 44 69 67 69 43 65 72 74 20 53 48 41 32 20 48 69 67 68 20 41 73 73 75 72 61 6e 63 65 20 53 65 72 76 65 72 20 43 41 
|  |- Validity (0x1e bytes)
|  |    30 1e 17 0d 31 36 31 32 30 39 30 30 30 30 30 30 5a 17 0d 31 38 30 31 32 35 31 32 30 30 30 30 5a 
|  |- Subject (0x69 bytes)
|  |    30 69 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 13 30 11 06 03 55 04 08 13 0a 43 61 6c 69 66 6f 72 6e 69 61 31 13 30 11 06 03 55 04 07 13 0a 4d 65 6e 6c 6f 20 50 61 72 6b 31 17 30 15 06 03 55 04 0a 13 0e 46 61 63 65 62 6f 6f 6b 2c 20 49 6e 63 2e 31 17 30 15 06 03 55 04 03 0c 0e 2a 2e 66 61 63 65 62 6f 6f 6b 2e 63 6f 6d 
|  |- SubjectPublicKeyInfo (0x59 bytes)
|  |    30 59 
|  |    |- AlgorithmIdentifier (0x13 bytes)
|  |    |  30 13
|  |    |     06 07 2a 86 48 ce 3d 02 01     ;Algorithm Object Identifier - 1.2.840.10045.2.1   ecPublicKey (ANSI X9.62 public key type)
|  |    |     06 08 2a 86 48 ce 3d 03 01 07  ;Algorithm Object Identiifer - 1.2.840.10045.3.1.7 prime256v1  (ANSI X9.62 named elliptic curve)
|  |    |- SubjectPublicKey (0x42 bytes)
|  |       03 42           
|  |          00 04 a0 f1 8c af a7 39 88 68  5b 13 56 0e 15 15 b4 a7 45 ef 
|  |          1b c7 e5 85 3c 2b 04 d4 65 8a  31 31 22 ea a3 92 ed 64 9d ba 
|  |          65 81 e3 b6 12 76 d8 b3 0b 45  f1 ff 0a 28 14 9c 4f dc 73 a9 
|  |          b3 49 2d a0 76 d3
|  |- issuerUniqueID [0]
|       a3 82 05 4a
|          30 82 05 46 30 1f 06 03 55 1d  23 04 18 30 16 80 14 51 68 ff  90 af 02 07 75 3c cc d9 65 64  62 a2 12 b8 59 72 3b 30 1d 06 
|          4b 8f 54 e3 e7 11 5a a1 5a 07 74 6a 8b 09 ff c7 8b e5 6f d0 84 72 78 f2 85 04 24 96 d3 ed de 03 9f 3d f9 69 c2 0c cc 1c 
|          26 50 58 79 95 7c 32 5b c7 15 98 37 6b ae 94 87 1f ce 02 fa 1e b5 bd 26 0a d5 29 9e 62 04 53 02 d7 fd e3 0d 12 f8 e0 da 
|          a4 c7 df fd f7 ca c0 a8 da 5d b9 fb f1 1c 47 cb a9 17 ed 8a 21 c9 a7 93 95 b0 68 9c df ab b7 05 3d 07 38 0a f7 33 99 31 
|          da b0 98 bf 8e 65 5a 21 a2 7d 1c 2e 74 83 77 71 e7 ce 13 41 7d ba 94 32 dd 74 5f cb 8b 8b 84 6c 9e d3 4a 8a 67 4f 38 d0 
|          75 60 6d 59 b3 05 87 76 dc 7e 11 42 29 aa 8a da 42 09 57 76 e0 ba 9e 47 89 b1 27 67 62 cf 9b a9 5e 91 8d 3b d9 91 42 18 
|          ce 10 61 ce 2e 92 ac e8 bb 62 56 09 19 86 a3 47 4c 1c 98 67 bd 05 e9 9c 84 06 c0 04 ea 08 3e 10 d4 00 76 00 56 14 06 9a 
|          2f d7 c2 ec d3 f5 e1 bd 44 b2 3e c7 46 76 b9 bc 99 11 5c c0 ef 94 98 55 d6 89 d0 dd 00 00 01 58 e5 d3 62 b9 00 00 04 03 
|          00 47 30 45 02 20 1a 15 d7 6f 05 0e e5 b0 f8 4e cf d0 d2 0a 99 c1 44 b6 be 5f c0 e0 77 a6 93 ba 2f c6 5f 36 bf da 02 21 
|          00 9b b6 47 e5 0d 76 dc ba 76 38 30 04 02 6c a9 67 7a c3 c6 73 f9 df b4 0f 38 c4 38 49 a7 11 47 59 00 77 00 ee 4b bd b7 
|          75 ce 60 ba e1 42 69 1f ab e1 9e 66 a3 0f 7e 5f b0 72 d8 83 00 c4 7b 89 7a a8 fd cb 00 00 01 58 e5 d3 64 11 00 00 04 03 
|          00 48 30 46 02 21 00 ab 9b 9e 04 28 6b 92 1a 93 c7 82 3a b7 df 1f b5 f1 dc 03 f5 34 c6 f9 a4 5c 37 e6 7b 76 55 27 91 02 
|          21 00 e3 b2 aa d5 44 1c 0d 72 04 b1 5f 96 9e e3 dd f4 b3 39 92 97 5e bb 4f 93 88 72 ad 4c b4 50 af 4b 
|- signatureAlgorithm
|    30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 
|- signatureValue
     03 82 01 01
        00 3a cd 4a ca 28 9d b8 f5  60 68 f0 cb db 7d c0 ff  7e 91 90 70 ac d3 0e da  7e 4d e5 f4 0d 84 66 b0 
        90 40 17 fa 55 e5 ce 09 b7  4e a6 25 4c d8 ba b0 21  5b 3c 10 04 ae 29 b7 68  c5 65 5a e3 a5 72 d8 27 
        8e d0 1d 99 d5 99 e2 a1 0e  36 b0 4b 1c f1 a0 ba 40  c9 dd 47 a7 fc 40 bf 83  02 ba 29 d0 42 6f 84 ed 
        a7 a3 0c 3d 8d 5c 85 bf dc  89 32 e2 dd 05 14 53 88  78 38 95 aa 52 3b dc 70  10 83 b3 f2 f2 74 d8 ca 
        59 96 53 c4 b2 66 c5 14 a6  7e 9c 82 53 7b 94 d9 71  c7 30 d9 68 f1 44 c8 96  a6 6c 3a d7 6a 86 0e ff 
        43 f7 2f 30 31 c3 91 c2 3f  b6 a7 a5 9a 0d 0c 0f 61  fd 2a 97 26 02 f5 64 c2  08 e7 f8 15 69 bf 91 c4 
        2e 5f b4 10 fd 14 85 89 27  23 50 7a 2c 17 9c 26 e8  fb 8c 8d ba 79 76 5d 5f  7e 42 62 4a 48 fd 26 40 
        f4 a2 be 39 82 87 87 ab c2  c4 aa a7 45 9f 59 41 43  a3 5e 72 16 29 07 95 e4  78

Перекрестная проверка

Если взять только эти байты:

SubjectPublicKeyInfo (0x59 bytes)
|    30 59 
|    |- AlgorithmIdentifier (0x13 bytes)
|    |  30 13
|    |     06 07 2a 86 48 ce 3d 02 01     ;Algorithm Object Identifier - 1.2.840.10045.2.1   ecPublicKey (ANSI X9.62 public key type)
|    |     06 08 2a 86 48 ce 3d 03 01 07  ;Algorithm Object Identiifer - 1.2.840.10045.3.1.7 prime256v1  (ANSI X9.62 named elliptic curve)
|    |- SubjectPublicKey (0x42 bytes)
|       03 42           
|          00 04 a0 f1 8c af a7 39 88 68  5b 13 56 0e 15 15 b4 a7 45 ef 
|          1b c7 e5 85 3c 2b 04 d4 65 8a  31 31 22 ea a3 92 ed 64 9d ba 
|          65 81 e3 b6 12 76 d8 b3 0b 45  f1 ff 0a 28 14 9c 4f dc 73 a9 
|          b3 49 2d a0 76 d3

И запустите их через SHA256, вы получите:

30 59 30 13 06 07 2a 86 48 ce  3d 02 01 06 08 2a 86 48 ce 3d
03 01 07 03 42 00 04 a0 f1 8c  af a7 39 88 68 5b 13 56 0e 15 
15 b4 a7 45 ef 1b c7 e5 85 3c  2b 04 d4 65 8a 31 31 22 ea a3 
92 ed 64 9d ba 65 81 e3 b6 12  76 d8 b3 0b 45 f1 ff 0a 28 14 
9c 4f dc 73 a9 b3 49 2d a0 76  d3

Вы затем кодируете это base64, и вы получаете:

  • base64: hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY =

Это хеш, который вы добавляете в заголовки HTTP-ответа:

  • показатель степени (например, 65 537)

Наши вычисленные значения соответствуют хешу PKP, который возвращает < / а>:

Public-Key-Pins: max-age=31536000; pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY=";

Почему SubjectPublicKeyInfo?

введите описание изображения здесь

Вы также можете вставить исходный сертификат в кодировке PEM (base64) в https://certpins.appspot.com/pin и убедитесь, что он возвращает тот же хеш PKP:

Пины с открытым ключом: max-age = 31536000; pin-sha256 = "hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY =";

Открытый ключ - это число (или, в случае RSA, пара чисел):

открытый ключ - это число

За прошедшие годы появилось несколько способов сохранить эти два числа:

  • модуль (например, сто пятьдесят четыре миллиона гугол гугол гугол)
  • извлеките блок SubjectPublicKeyInfo и сохраните его как файл BEGIN PUBLIC KEY

SHH:

XML

[lenghPrefix]ssh-rsa[lengthPrefix][exponent][lengthPrefix][modulus]

PKCS # 1

<RSAKeyValue>
   <Modulus>ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9V</Modulus>
   <Exponent>AQAB</Exponent>
</RSAKeyValue>

PKCS # 1 выбрал вариант DER кодировки ASN.1 со следующей структурой:

-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXY
UMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE
3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dV
ek9b9VAgMBAAE=
-----END RSA PUBLIC KEY-----

Позже, когда появились новые системы шифрования с открытым ключом, они «позаимствовали» структуру RSAPublicKey, но снабдили ее префиксом идентификатора алгоритма:

RSAPublicKey ::= SEQUENCE {
      modulus           INTEGER,  -- n
      publicExponent    INTEGER   -- e
  }

Где AlgorithID для PKCS # 1 RSAPublicKey - 1.2. 840.113549.1.1.1, которое происходит от:

SubjectPublicKeyInfo  ::=  SEQUENCE  {
    algorithm            AlgorithmIdentifier,
    subjectPublicKey     RSAPublicKey }

Затем этот формат будет отображаться в файлах с кодировкой base64 как:

  • 1 - ISO assigned OIDs
    • 1.2 - ISO member body
    • 1.2.840 - USA
      • 1.2.840.113549 - RSADSI
      • 1.2.840.113549.1 - PKCS
        • 1.2.840.113549.1.1 - PKCS-1

Это SubjectPublicKeyInfo, для которого вы получаете хэш sha256.

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcZ/r0nvJyHUUstIB5BqCUJ1CC
Cd1nzle4bEpPQJ/S0Wn7mV2FDAeh+UcbVhZu9n+5zypYNjeZKapPqBLoT8eCK51y
Kpzeb8LuEm3P8PK4xN18XBrIF1GprN8IIgSdK9f5SwnemutcURrY+PlWnvj7N5s/
03RlJA3/NHVXpPW/VQIDAQAB
-----END PUBLIC KEY-----

Внутри каждого сертификата находится SubjectPublicKeyInfo; даже сертификат Windows EFS.

Вы можете использовать OpenSSL для:

Людям нужно перестать относиться к OpenSSL как к волшебному шифровальному ящику. Слишком часто люди просто вводят эзотерические команды openssl, чтобы что-то сделать, вместо того, чтобы понимать, что они делают. Даже сам RFC о закреплении открытого ключа не пытается объяснить, что это такое, а просто говорит вам перейти к всезнающему openssl. OpenSSL - это не главное и не завершение управления шифрованием.

  • хэшировать
  • base64 это
  • Есть действительно простой способ сделать это. Я потратил некоторое время на то, чтобы собрать все вместе, чтобы создать решение, которое можно использовать повторно. К сожалению, я сделал это только на OSX, но вы сможете довольно легко выполнить это, если используете другую ОС.
    Для этого метода вам понадобятся:

Сертификат - это не (просто) открытый ключ

person Ian Boyd    schedule 19.09.2017
comment
@Tommy У него нет пользовательского интерфейса. - person Tommy; 12.07.2018
comment
Спасибо! они должны это задокументировать! - person Ian Boyd; 12.07.2018
comment
Привет, @IanBoyd! Не могли бы вы взглянуть на мой вопрос: stackoverflow.com/questions/59310730/ и скажите мне, что я делаю не так ... Мне нужно закрепить открытый ключ? Если да, то как мне это сделать? В Интернете нет надлежащей информации о том, как закрепить открытый ключ. Пожалуйста, помогите - person Jonathan; 11.10.2019
comment
Ответ на получение идентификатора ключа темы можно найти на странице security.stackexchange.com/a/128956/158091 - person YogiAR; 13.12.2019
comment
RFC, конечно же, определяет контакты и отпечатки SPKI: rfc-editor. org / rfc / rfc7469.html # section-2.4 - person Jari Turkia; 01.03.2020
comment
TrustKit предоставляет для этого сценарий Python: github.com/datatheorem/TrustKit/blob / master / - person Tobu; 30.06.2020

Установите Homebrew

  • OpenSSL (brew install openssl в терминале после установки Homebrew)

  • Создайте новый файл .sh и установите его содержимое следующим образом:

  • Сохранить файл на диск

    openssl s_client -servername $1 -connect $1:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

  • Из окна терминала вызовите bash <new sh file directory> www.google.com

  • Теперь он должен вернуть требуемый хеш и оставить у вас приятное небольшое решение для повторного использования. Возможно, вам придется нажать ctrl + c после того, как хеш будет возвращен.

Должно получиться что-то вроде следующего:  введите описание изображения здесь
Надеюсь, это кому-то поможет.
Спасибо

Также см. Связывание сертификатов и открытых ключей OWASP. Изображение закрепления в сети - это шутка ...

person mylogon    schedule 03.11.2016
comment
@Nabla Да, но для этого требуется, чтобы на вашем компьютере был файл .pem или .der, что не всегда возможно / требует гораздо больше работы. Мое решение помогает, если вы пытаетесь легко закрепить чужой сертификат. - person Nabla; 17.11.2016
comment
удивительный! для ubuntu вы можете установить его с помощью команды sudo apt install linuxbrew-wrapper - person mylogon; 17.11.2016
comment
где я могу найти резервный ключ? - person digulino; 13.05.2019
comment
@ChangdeoJadhav Какой резервный ключ? Если это отдельный вопрос, создайте новый вопрос по SO, чтобы привлечь к нему больше внимания. - person Changdeo Jadhav; 26.06.2019
comment
Это кажется отличным и простым ответом. Только один вопрос - у меня другой результат для google.com _1_ Я думал, что открытый ключ статичен и никогда не меняется? - person mylogon; 26.06.2019
comment
Вышеупомянутый двоичный файл закодирован в версии DER ASN.1. Мы можем использовать отличный JavaScript ASN. 1 декодер, который расшифрует его для нас: - person Dror Bar; 06.07.2021