Генерация пар ключей RSA

483 views
Skip to first unread message

Artem Miolini

unread,
Feb 25, 2011, 4:10:21 AM2/25/11
to erlang-...@googlegroups.com
Здравствуйте!

Подскажите, пожалуйста, способо генерации пар ключей RSA в erlang.


Андреенко Артём.

Valentin Nechayev

unread,
Feb 25, 2011, 4:17:29 AM2/25/11
to erlang-...@googlegroups.com
2011/2/25 Artem Miolini <mio...@gmail.com>:

> Здравствуйте!
>
> Подскажите, пожалуйста, способо генерации пар ключей RSA в erlang.

Я бы вызвал чего-то из OpenSSL, как внешнюю программу.
В стандартных модулях такого не видно, а задача в общем достаточно
нетривиальная, если учесть, что может быть разный уровень проверок
правильности формирования ключа.

--
-netch-

Alexander Dergachev

unread,
Feb 25, 2011, 4:25:45 AM2/25/11
to erlang-...@googlegroups.com
для "ленивых", в аппликейшене crypto все есть

2011/2/25 Valentin Nechayev <net...@gmail.com>

--
Страница рассылки: http://groups.google.com/group/erlang-russian
 Jabber-конференция: erl...@conference.jabber.ru
 Новости: http://erlanger.ru
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com



--
With Best Regards,
Alexander Dergachev

Valentin Nechayev

unread,
Feb 25, 2011, 4:29:48 AM2/25/11
to erlang-...@googlegroups.com
2011/2/25 Alexander Dergachev <cy6er...@gmail.com>:

> для "ленивых", в аппликейшене crypto все есть

Это где? В R14B01 в списке функций есть rsa_sign, rsa_verify,
rsa_{private,public}_{en,de}crypt и всё. Покажите мне там функцию
_генерации_ ключей.

--
-netch-

Alexander Dergachev

unread,
Feb 25, 2011, 4:52:32 AM2/25/11
to erlang-...@googlegroups.com
ок, в далеком 2009 была тема http://groups.google.com/group/erlang-russian/browse_thread/thread/dcafc203ef41306b

для совсем ленивых Ъ, неходящих по ссылкам, приведу код из последнего сообщения:

N=9676388573028346607648827639044480354350734446440837605277805507263079714 60619683126465685994589442949811931966094798480668769197, 

D=4147023674155005688992354702447634437578886191331787545119059502839432302 45925749951816401493352286133311189794309745737857051223, 

E=7, 
PrivKey = [crypto:mpint(E), crypto:mpint(N), crypto:mpint(D)] , 
PubKey = [crypto:mpint(E), crypto:mpint(N)], 
Crypted = crypto:rsa_public_encrypt("123456789",PubKey,rsa_pkcs1_padding), 

Decrypted = crypto:rsa_private_decrypt(Crypted,PrivKey,rsa_pkcs1_padding). 

N и D - два prime'а, а еще в crypto.erl есть

mod_exp(N, P, M) -> Result

   Types  N, P, M, Result = Mpint

          Mpint = binary()

   This function performs the exponentiation N ^ P mod M , using the crypto library.

уж два prime'а сгенерировать мы сумеем?

2011/2/25 Valentin Nechayev <net...@gmail.com>

-netch-

--
Страница рассылки: http://groups.google.com/group/erlang-russian
 Jabber-конференция: erl...@conference.jabber.ru
 Новости: http://erlanger.ru
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com

Valentin Nechayev

unread,
Feb 25, 2011, 5:07:50 AM2/25/11
to erlang-...@googlegroups.com
2011/2/25 Alexander Dergachev <cy6er...@gmail.com>:

> N и D - два prime'а, а еще в crypto.erl есть
[...]

> уж два prime'а сгенерировать мы сумеем?

Извините, ничего личного, но Вы проявили в этом сообщении
катастрофический уровень ламерства, который был бы где-то в другом
месте ещё допустим, но никак не в криптографии. Ибо:
1. N - public modulus - это _не_ простое число. Это произведение двух
(в идеале простых) чисел, которые обычно обозначаются P и Q. Защита
RSA как метода основана на проблемах разложения числа N на простые
сомножители.
2. Для генерации ключа надо сгенерировать P и Q нужных размеров (чтобы
их произведение имело нужный размер в битах). Они должны быть
простыми, но на практике используется не полная проверка на простоту
(которая по цене где-то 1/4 от вообще взлома ключа), а ряд упрощённых
методов косвенной проверки. Качество генерации зависит от качества
реализации этих методов. Вы можете, конечно, считать задачу генерации
большого простого числа простой, но чтобы Ваш результат был хоть
как-то полезным - надо её делать с достаточным уровнем качества, а не
просто "предположим, оно простое", и не писать так, чтобы ныдо было
ждать тысячу лет для полной проверки.
3. Выбор числа E надо основывать на оценке необходимой скорости работы
с публичным ключом и качестве реализации, тут тоже есть несколько
нетривиальных эмпирических критериев.

Можете почитать основу, например, тут:
http://www.ietf.org/rfc/rfc2313.txt
(для реализации следует использовать версию 2.0, но в 1.5 более
простые для освоения обозначения, поэтому даю ссылку на неё).

В общем случае я _настаиваю_, что в криптографии надо доверять
профессионалам и ни в коем случае не пытаться делать закат солнца
вручную по принципу "а мы что, рыжие?" Я сам не являюсь профессионалом
в криптографии и не собираюсь им быть, но моего уровня достаточно,
чтобы быть в курсе тематики отрасли и уметь фильтровать заведомо
негодные подходы, и, разумеется, не пытаться делать самому то, для
чего есть готовые средства. Чего и Вам желаю.

--
-netch-

Alexander Dergachev

unread,
Feb 25, 2011, 5:44:15 AM2/25/11
to erlang-...@googlegroups.com
ок, моя ошибка, признаю. только давай узнаем у ТС что он хочет вообще сделать? какова серьезность его программы. сдается мне, если бы человек серьезно занимался криптографией, он бы не задавал этот вопрос тут. а для "на посмотреть", моего предложения должно быть достаточно. а вообще, если уж использовать что-то внешнее, то проще дописать одну функцию в crypto, потому как в С`шной реализации есть функции для генерации ключей, и просто никто не сделал к ним интерфейс в crypto аппликейшене (я делал в 2009ом, или еще раньше, но кода сейчас нет уже).

2011/2/25 Valentin Nechayev <net...@gmail.com>
-netch-

--
Страница рассылки: http://groups.google.com/group/erlang-russian
 Jabber-конференция: erl...@conference.jabber.ru
 Новости: http://erlanger.ru
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com

Alexander Dergachev

unread,
Feb 25, 2011, 5:45:36 AM2/25/11
to erlang-...@googlegroups.com
под C`шной реализацией я подразумеваю libcrypto из поставки libssl

2011/2/25 Alexander Dergachev <cy6er...@gmail.com>

Valentin Nechayev

unread,
Feb 25, 2011, 6:01:03 AM2/25/11
to erlang-...@googlegroups.com
2011/2/25 Alexander Dergachev <cy6er...@gmail.com>:

> ок, моя ошибка, признаю. только давай узнаем у ТС что он хочет вообще
> сделать? какова серьезность его программы. сдается мне, если бы человек
> серьезно занимался криптографией, он бы не задавал этот вопрос тут. а для
> "на посмотреть", моего предложения должно быть достаточно.

"На посмотреть" достаточно поиграться с ключами, которые делаются
вручную. Например, e = 3, d = 7, N = 55. Можете проверить на паре
значений данных:

6> A = 16.
16
7> B = trunc(math:pow(A,3)) rem 55.
26
8> A = trunc(math:pow(B,7)) rem 55.
16

А для более серьёзного испытания таки лучше взять готовое:

$ openssl genrsa 1024
Generating RSA private key, 1024 bit long modulus
.....++++++
...................................++++++
e is 65537 (0x10001)
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC6ayzO2oGLxMHdbM2igYCox8gs9wYMgAYofu3vQAtXSl0W7dLt
Lxs1XTUHVqU2VLeVXKb6qBvWqF7XIlkxxfwxeu9PsroqsTjjjzSp0aRtyBNtZjqi
w1YwVIcPMg6aVlX4uCSf3PB7KDTyZzY2jy7wy/L+CU3+THzYjhgsIGPxKwIDAQAB
AoGBAJrW2IH8JmwUgr5LWEYpcNdAEbmfeKu7TuImA7WcqY7Ympen9HHDlcLuZ1Rw
GIwXM+Fg8uTx6yWR9iyVQCbCfySi5iwrfppiCtVbxePWxGJ2UA/bq9yIjJsp+hpw
zXPU+x1VodtqampZrwsv41Kpprh6iGciW3qIW3yY7cjZPl2pAkEA5HNEBl0XyyLg
NJvf4+Zh7d0Wj/cUQzap8UpGZFptbs8782yDsjDrTK4r7HYRrGSEctsbpVD9DzC+
+XEnxgHkRQJBANDmTmr1EhsMbUJmQ1upQ2dpvs3k5YZglese2ntlGT1eKN6WtJXV
R+TZsloBwq0f5tjKX5iKMwBKrgxDWIBKrq8CQAXd2+pZ66mAzMctFZPRr8QfAFxU
GQYc2kJjCOm81MCau8xlhgBGd1RxyJj68zs9HZWhgNU+/jCsrMrVGBNiqw0CQBpV
znEBcETkril+xuMZVZwF4r4GK0Fjj8LSYuzHdAUeh7x391AkUSnyn99k9Wvp56pQ
6PhMA933jDWTj+asg5UCQC4vCcW+LNY0ah3ogOH7yo1FLE0cuAjPo0LkdUkqSvDv
6qH2P3CH/S/krwz60xPKFDdkyZKWDVQRZFrFlh/cxUI=
-----END RSA PRIVATE KEY-----

Да, ещё потребуется чуть повозиться с расшифровкой упакованного по
PKCS#8 ключа, но вполне решается.

Если такого командного интерфейса к OpenSSL нет - поставить, в
нормальной поставке оно обязано быть.

> а вообще, если уж
> использовать что-то внешнее, то проще дописать одну функцию в crypto,

Проще ли? У нас даже тривиальные патчи маринуются, извините, слишком
долго в Erlang team, а тут новая функция в очень сложной тематике.

> потому
> как в С`шной реализации есть функции для генерации ключей, и просто никто не
> сделал к ним интерфейс в crypto аппликейшене (я делал в 2009ом, или еще
> раньше, но кода сейчас нет уже).

Ну если оно будет просто враппером вокруг OpenSSL - да, возможно, в
R15B успеете впихнуть.

--
-netch-

Alex Kutsko

unread,
Feb 25, 2011, 6:13:02 AM2/25/11
to erlang-...@googlegroups.com, Valentin Nechayev
        StrCmd = os:cmd("openssl genrsa 4096"),%% generation of RSA key
        Private = list_to_binary(StrCmd),
        {PrivKey, PubKey_0} = key_pem:read_key(Private),

key_pem:read_key делает чтото типа того же что есть в ssl_pem.erl можете посмотреть исходники в ssl модуле:

read_key(BinKey) ->
    {ok, [Entry]} = decode_file(split_bin(BinKey), no_passwd),
    {ok,{'RSAPrivateKey', 'two-prime', N , E, D, _P, _Q, _E1, _E2, _C,
         _Other}} =  public_key:pem_entry_decode(Entry),

    PrivKey = [crypto:mpint(E), crypto:mpint(N), crypto:mpint(D)] ,
    PubKey = [crypto:mpint(E), crypto:mpint(N)],
    {PrivKey, PubKey}.

decode_file(Bin, Passwd) ->
    %%io:format("decode_file/2 ~p\n", [Bin]),
    decode_file(Bin, [], [Passwd]).

decode_file([<<"-----BEGIN CERTIFICATE REQUEST-----", _/binary>>|Rest], Ens, Info) ->
    decode_file2(Rest, [], Ens, cert_req, Info);
decode_file([<<"-----BEGIN CERTIFICATE-----", _/binary>>|Rest], Ens, Info) ->
    decode_file2(Rest, [], Ens, cert, Info);
decode_file([<<"-----BEGIN RSA PRIVATE KEY-----", _/binary>>|Rest], Ens, Info) ->
    decode_file2(Rest, [], Ens, rsa_private_key, Info);
decode_file([<<"-----BEGIN DSA PRIVATE KEY-----", _/binary>>|Rest], Ens, Info) ->
    decode_file2(Rest, [], Ens, dsa_private_key, Info);
decode_file([<<"-----BEGIN DH PARAMETERS-----", _/binary>>|Rest], Ens, Info) ->
    decode_file2(Rest, [], Ens, dh_params, Info);
decode_file([_|Rest], Ens, Info) ->
    decode_file(Rest, Ens, Info);
decode_file([], Ens, _Info) ->
    {ok, lists:reverse(Ens)}.

decode_file2([<<"Proc-Type: 4,ENCRYPTED", _/binary>>| Rest0], RLs, Ens, Tag, Info0) ->
    [InfoLine|Rest] = Rest0,
    Info = dek_info(InfoLine, Info0),
    decode_file2(Rest, RLs, Ens, Tag, Info);
decode_file2([<<"-----END", _/binary>>| Rest], RLs, Ens, Tag, Info0) ->
    Cs = erlang:iolist_to_binary(lists:reverse(RLs)),
    Bin = base64:mime_decode(Cs),
    case Info0 of
    [Password, Cipher, SaltHex | Info1] ->
        Salt = unhex(SaltHex),
        Enc = {Cipher, Salt},
        Decoded = decode_key(Bin, Password, Cipher, Salt),
        decode_file(Rest, [{Tag, Decoded, Enc}| Ens], Info1);
    _ ->
        decode_file(Rest, [{Tag, Bin, not_encrypted}| Ens], Info0)
    end;
decode_file2([L|Rest], RLs, Ens, Tag, Info0) ->
    decode_file2(Rest, [L|RLs], Ens, Tag, Info0);
decode_file2([], _, Ens, _, _) ->
    {ok, lists:reverse(Ens)}.

decode_key(Data, no_passwd, _Alg, _Salt) ->
    Data;
decode_key(Data, Password, "DES-CBC", Salt) ->
    Key = password_to_key(Password, Salt, 8),
    IV = Salt,
    crypto:des_cbc_decrypt(Key, IV, Data);
decode_key(Data,  Password, "DES-EDE3-CBC", Salt) ->
    Key = password_to_key(Password, Salt, 24),
    IV = Salt,
    <<Key1:8/binary, Key2:8/binary, Key3:8/binary>> = Key,
    crypto:des_ede3_cbc_decrypt(Key1, Key2, Key3, IV, Data).


2011/2/25 Valentin Nechayev <net...@gmail.com>
-netch-

--
Страница рассылки: http://groups.google.com/group/erlang-russian
 Jabber-конференция: erl...@conference.jabber.ru
 Новости: http://erlanger.ru
Написать письмо: erlang-...@googlegroups.com
Отписаться: erlang-russia...@googlegroups.com



--
Best regards,
Alex Kutsko

Artem Miolini

unread,
Feb 25, 2011, 6:42:41 AM2/25/11
to erlang-...@googlegroups.com
Я не криптограф, а обычный серверный прикладной разработчик.
Столкнулся с задачей генерации ключа. Хочется без вызова решить
задачу.

25 февраля 2011 г. 13:44 пользователь Alexander Dergachev
<cy6er...@gmail.com> написал:

Artem Miolini

unread,
Feb 28, 2011, 7:21:55 AM2/28/11
to erlang-...@googlegroups.com
Без обращения к шеллу, т.е.

25 февраля 2011 г. 14:42 пользователь Artem Miolini <mio...@gmail.com> написал:

Valentin Nechayev

unread,
Mar 1, 2011, 3:55:42 AM3/1/11
to erlang-...@googlegroups.com, Artem Miolini
2011/2/28 Artem Miolini <mio...@gmail.com>:

>> Я не криптограф, а обычный серверный прикладной разработчик.
>> Столкнулся с задачей генерации ключа. Хочется без вызова решить
>> задачу.

К сожалению, на такое можно предложить только взять код genrsa и
портировать под Erlang. Ну или сделать патченый crypto вместе с
драйвером - переходником на OpenSSL. Думаю, такое и в апстрим примут с
радостью.

--
-netch-

Reply all
Reply to author
Forward
0 new messages