Pull to refresh

Генерируем цепочку сертификатов с эллиптическими кривыми при помощи OpenSSL

Reading time 8 min
Views 25K
график функции y^2 = x^3-x+1Думаю многие слышали о криптографии эллиптических кривых, о том
что работает она во много раз быстрее RSA и при несоизмеримо меньшей длине ключа обеспечивает несоизмеримо большую стойкость ко взлому. Если не слышали, то можно глянуть на wiki или почитать в книгах А.А. Болотова.
К сожалению, данный вид шифрования слабо распространен. Я постараюсь объяснить как им пользоваться и поможет мне в этом OpenSSL.

Чтобы не быть голословным приведу сравнение необходимых длин ключей для обеспечения сравнимой стойкости ко взлому для различных алгоритмов. Нам интересна правая часть.
Сравнение алгоритмов
Видно, что популярным сегодня ключам RSA длиной 1024-2048 бит соответствует всего навсего 160-224битный ключ ECC (Elliptic Curve Cryptography)

Ну а чтобы понять какой RSA тормоз достаточно попробовать сгенерировать самый длинный из предложенных в таблице ключей (и пойти вздремнуть):

openssl genrsa 15360

Желающих прикоснуться к «next gen» криптографии, придуманной аж в 1985 году, прошу под кат.

Перво наперво определимся какой длины ключ нам нужен. В ECC определенной длине ключа соответствуют определенные параметры кривой. Но нам их подбирать не надо, за нас это сделали умные дядьки из NIST.
Посмотреть список доступных кривых можно командой
openssl ecparam -list_curves

Список эта команда выдает внушительный, и если у вас нет определенных предпочтений, выбирайте ту что нравится и больше 160 бит, например одну из самых длинных:
secp521r1: NIST/SECG curve over a 521 bit prime field

Создадим папку, например c:\ec\ и будем всё туда складывать. В папку CA всё для корневого сертификата, в папку Client — всё для клиентского сертификата.

Нам необходимо
  1. Сгенерировать корневой самоподписанный сертификат (CA)
  2. Сгенерировать клиентский сертификат
  3. Подписать клиентский сертификат корневым

1) Генерируем корневой сертификат.
1.1) Генерируем ключ для корневого сертификата:
openssl ecparam -name secp521r1 -genkey -out c:\ec\CA\CA.key

Получим что то вроде
-----BEGIN EC PARAMETERS-----
BgUrgQQAIw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MIHcAgEBBEIBrtyWCH0+OAZqbr84CLFvsxbB2/AfjKD6+fpXQF5qs7n1yRmxItRH
vNlylh7dNZEwYwleI5RLQV3pz6p06hgo6c2gBwYFK4EEACOhgYkDgYYABAEx+OTa
s3/djxFMW7GNcWWVGv5Y7Vwvr2k00gXVyUpSySSudXKSaWYrblBtPKOWRcuHzkq5
tks3vTKclq3NgPpdjgAPk4ha68UTdX+JI/oK+EMUwCdaCuIYMDeRO1VHByEx+3/1
XlkYPvEKRkQDLJP22vXE/NEirdZ/WzO6QTWku5q0UQ==
-----END EC PRIVATE KEY-----
Вначале идут параметры кривой (её название secp521r1), а потом уже сгенерированный на её основе ключ.

1.1.1) При желании защищаем его паролем (шифруем по алгоритму AES с длиной ключа 256 бит):
openssl ec -in c:\ec\CA\CA.key -out c:\ec\CA\ca.protected.key -aes256

Получаем вот такую красоту (пароль — qwerty):
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,E34E27512B4DCB01524A5F17937DA7D5

xF7XZyLtpqofqkl0PVCf/1cOEygL82itDrz7k5tVqJLMDYzG9RnTTPwJgOXsZkV1
dk5MQe9h/ixPkFE/B/Ox1OH5SI4Frb8dgS8mT9mq620A4RJdD6yAZcpicnuyyXma
1dZ+xoyRiGeHxcnErDJpvA7H6BpIAzinz4lMzY1pz2TXTdGLU+0bK1bMiDFxRvwA
jyUEsrZA2kZ5v++MZzmxTsJZ6XTCRzeUPhhvNE0VKF8xPSWMEB6WeJPr+rl3zBZ7
sE71UwiaIddFHkOe3UnlAxjohABpZytUud8uS0Wi+5E=
-----END EC PRIVATE KEY-----

2) Генерируем запрос на сертификат. Запрос — это структура из открытого ключа, его хэша и данных о владельце сертификата. Алгоритм хэширования ключа выбираем SHA512:
openssl req -new -key c:\ec\CA\ca.protected.key -sha512 -out c:\ec\CA\CA.req

Получаем еще одну красоту:
-----BEGIN CERTIFICATE REQUEST-----
MIIBrzCCARACAQAwazELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1vc2NvdzEPMA0G
A1UEBwwGTW9zY293MRIwEAYDVQQKDAloYWJyYWhhYnIxCzAJBgNVBAsMAklUMRkw
FwYDVQQDDBB3d3cuaGFicmFoYWJyLnJ1MIGbMBAGByqGSM49AgEGBSuBBAAjA4GG
AAQBMfjk2rN/3Y8RTFuxjXFllRr+WO1cL69pNNIF1clKUskkrnVykmlmK25QbTyj
lkXLh85KubZLN70ynJatzYD6XY4AD5OIWuvFE3V/iSP6CvhDFMAnWgriGDA3kTtV
RwchMft/9V5ZGD7xCkZEAyyT9tr1xPzRIq3Wf1szukE1pLuatFGgADAKBggqhkjO
PQQDBAOBjAAwgYgCQgHa0d5nc9UX41jj42lOnv0Hh9EXfROFm7QoUSoKdye7s7uE
nZPmGTM+h5bRG8Y+hHD3QQyM8vY9TnMVVp0r2xmYHwJCAbE5CTRDoeXf3ZpKUW77
SpXtPgYEEelkOm3Ua+/0XVoZviBT7wF5nrqTYnMJ2MQtyvKKMCO74qqUiMoudZ7z
MSgO
-----END CERTIFICATE REQUEST-----

3) Финальный шаг. Подписываем наш запрос нашим же закрытым ключом. Подписываться будет не весь запрос, а только его хэш, поэтому мы на предыдущем шаге указывали какой алгоритм хэширования выбрать
Для этого нам нужно будет
3.1) Изменить в openssl.cfg в разделе [ CA_default ] dir на «c:/ec» вместо ./DemoCA по умолчанию
3.2) В папке c:\ec создать 2 файла: пустой index.txt и файл serial, в который записать 01 без пробелов и переносов строк.

3.3) Выполнить волшебную команду
openssl ca -days 365 -policy policy_anything -keyfile c:\ec\CA\CA.protected.key -in c:\ec\CA\CA.req -selfsign -out c:\ec\CA\ca.crt -outdir c:\ec\CA

На вход мы подаем запрос на сертификат, путь до закрытого ключа и говорим, что сертификат будет самоподписанный (-selfsign). На выходе получаем настоящий красивый сертификат (сохранить как ca.crt, потом можно просмотреть средствами windows):
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: ecdsa-with-SHA1
        Issuer: C=RU, ST=Moscow, L=Moscow, O=habrahabr, OU=IT, CN=www.habrahabr.ru
        Validity
            Not Before: Jun 11 05:12:03 2010 GMT
            Not After: Jun 11 05:12:03 2011 GMT
        Subject: C=RU, ST=Moscow, L=Moscow, O=habrahabr, OU=IT, CN=www.habrahabr.ru
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
                Public-Key: (521 bit)
                pub:
                    04:01:31:f8:e4:da:b3:7f:dd:8f:11:4c:5b:b1:8d:
                    71:65:95:1a:fe:58:ed:5c:2f:af:69:34:d2:05:d5:
                    c9:4a:52:c9:24:ae:75:72:92:69:66:2b:6e:50:6d:
                    3c:a3:96:45:cb:87:ce:4a:b9:b6:4b:37:bd:32:9c:
                    96:ad:cd:80:fa:5d:8e:00:0f:93:88:5a:eb:c5:13:
                    75:7f:89:23:fa:0a:f8:43:14:c0:27:5a:0a:e2:18:
                    30:37:91:3b:55:47:07:21:31:fb:7f:f5:5e:59:18:
                    3e:f1:0a:46:44:03:2c:93:f6:da:f5:c4:fc:d1:22:
                    ad:d6:7f:5b:33:ba:41:35:a4:bb:9a:b4:51
                ASN1 OID: secp521r1
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                3D:FF:46:92:1C:7E:C1:F3:84:D0:26:BA:CD:5D:AD:25:B8:CC:DE:44
            X509v3 Authority Key Identifier:
                keyid:3D:FF:46:92:1C:7E:C1:F3:84:D0:26:BA:CD:5D:AD:25:B8:CC:DE:44

    Signature Algorithm: ecdsa-with-SHA1
        30:81:88:02:42:01:bf:ca:f1:4c:51:85:b4:65:26:de:eb:14:
        ee:07:a1:1f:97:1d:35:1a:c3:61:8a:82:97:96:7b:f4:d4:95:
        73:4d:84:d2:78:b2:35:fd:72:05:ea:6d:a4:49:e1:18:a0:ff:
        13:60:7e:b0:67:ba:7f:cd:8b:ef:15:a6:5d:30:a3:48:9c:02:
        42:01:53:27:2c:2c:b9:79:b1:0f:9a:c3:f6:a0:c9:dc:82:cb:
        2f:3c:d8:0a:c1:53:d7:3c:37:af:54:39:78:de:ae:d9:d7:55:
        6f:de:cc:9c:75:cf:d5:8e:8e:cc:2d:0c:da:d1:be:c5:8d:2d:
        2b:68:94:9d:0d:8c:89:aa:b9:1d:e8:a2:05
-----BEGIN CERTIFICATE-----
MIICxjCCAiigAwIBAgIBATAJBgcqhkjOPQQBMGsxCzAJBgNVBAYTAlJVMQ8wDQYD
VQQIDAZNb3Njb3cxDzANBgNVBAcMBk1vc2NvdzESMBAGA1UECgwJaGFicmFoYWJy
MQswCQYDVQQLDAJJVDEZMBcGA1UEAwwQd3d3LmhhYnJhaGFici5ydTAeFw0xMDA2
MTEwNTEyMDNaFw0xMTA2MTEwNTEyMDNaMGsxCzAJBgNVBAYTAlJVMQ8wDQYDVQQI
DAZNb3Njb3cxDzANBgNVBAcMBk1vc2NvdzESMBAGA1UECgwJaGFicmFoYWJyMQsw
CQYDVQQLDAJJVDEZMBcGA1UEAwwQd3d3LmhhYnJhaGFici5ydTCBmzAQBgcqhkjO
PQIBBgUrgQQAIwOBhgAEATH45Nqzf92PEUxbsY1xZZUa/ljtXC+vaTTSBdXJSlLJ
JK51cpJpZituUG08o5ZFy4fOSrm2Sze9MpyWrc2A+l2OAA+TiFrrxRN1f4kj+gr4
QxTAJ1oK4hgwN5E7VUcHITH7f/VeWRg+8QpGRAMsk/ba9cT80SKt1n9bM7pBNaS7
mrRRo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy
YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUPf9Gkhx+wfOE0Ca6zV2tJbjM3kQw
HwYDVR0jBBgwFoAUPf9Gkhx+wfOE0Ca6zV2tJbjM3kQwCQYHKoZIzj0EAQOBjAAw
gYgCQgG/yvFMUYW0ZSbe6xTuB6Eflx01GsNhioKXlnv01JVzTYTSeLI1/XIF6m2k
SeEYoP8TYH6wZ7p/zYvvFaZdMKNInAJCAVMnLCy5ebEPmsP2oMncgssvPNgKwVPX
PDevVDl43q7Z11Vv3sycdc/Vjo7MLQza0b7FjS0raJSdDYyJqrkd6KIF
-----END CERTIFICATE-----

.

Готово! Теперь давайте сгенерируем клиента.

Шаги 1-2 очень похожи. Отличаются только пути:
openssl ecparam -name secp521r1 -genkey -out c:\ec\Client\Client.key
openssl ec -in c:\ec\Client\Client.key -out c:\ec\Client\Client.protected.key -aes256
openssl req -new -key c:\ec\Client\Client.protected.key -sha512 -out c:\ec\Client\Client.req

Шаг 3 отличается кроме путей тем, что на вход мы подаем сертификат CA, закрытый ключ CA, клиентский запрос и убираем -selfsign
openssl ca -days 365 -policy policy_anything -keyfile c:\ec\CA\CA.protected.key -cert c:\ec\CA\CA.crt -in c:\ec\Client\Client.req -out c:\ec\Client\Client.crt -outdir c:\ec\Client


Всё! Можно установить CA.crt в хранилище доверенных корневых сертификатов, открыть Client.crt и наслаждаться тем, что все работает (не обращайте внимания на небольшую ругань относительно корневого сертификата, там видимо нужно еще какие то расширения указать)

Теперь немного о минусах:
  1. По умолчанию не поддерживается в XP. Возможно есть альтернативные security провайдеры
  2. Не всеми браузерами все кривые поддерживаются даже на Vista\7. IE умеет почти всё, Chrome вообще всё, а Opera ничего.


Протестировать браузер на совместимость с такими сертификатами можно, например на сайте Fedora.

Have fun!


UPD:
Архив содержимого папки ec доступен тут
Tags:
Hubs:
+73
Comments 27
Comments Comments 27

Articles