Шифры EXP (ORT) и M2Crypto / OpenSSL

Мне сложно работать с SSLS-сервером M2Crypto с шифрами класса EXPORT.

НИЗКИЕ / СРЕДНИЕ / ВЫСОТЫЕ ЦИФЕРЫ работают без проблем, но ЭКСПОРТ просто не будет. Кроме того, когда OpenSSL запускается в режиме сервера из командной строки, он без проблем принимает классы класса EXPORT.

Таким образом, либо я что-то упустил, либо возникла проблема в модуле M2Crypto. Любая помощь приветствуется.

Используемый код python ( ssl-server.py ) выглядит так:

 import M2Crypto import socket CERTFILE = "dummy_cert.pem" KEYFILE = "dummy_key.pem" PROTOCOL = "sslv3" HOST = "0.0.0.0" PORT = 4433 def main(): print "[i] Initializing context ..." ctx = M2Crypto.SSL.Context(protocol=PROTOCOL, weak_crypto=True) ctx.load_cert_chain(certchainfile=CERTFILE, keyfile=KEYFILE) ctx.set_options(M2Crypto.m2.SSL_OP_ALL) ctx.set_cipher_list("ALL") print "[i] Initializing socket ..." sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((HOST, PORT)) sock.listen(1) conn, addr = sock.accept() print "[i] SSL handshake ..." ssl_conn = M2Crypto.SSL.Connection(ctx=ctx, sock=conn) ssl_conn.setup_ssl() try: ssl_conn_res = ssl_conn.accept_ssl() except Exception, ex: print "[x] SSL connection failed: '%s'" % str(ex) else: if ssl_conn_res == 1: print "[i] SSL connection accepted" else: print "[x] SSL handshake failed: '%s'" % ssl_conn.ssl_get_error(ssl_conn_res) if __name__ == "__main__": main() 

Симптомы:

 $ uname -a Linux XYZ 2.6.38-15-generic #59-Ubuntu SMP Fri Apr 27 16:03:32 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=11.04 DISTRIB_CODENAME=natty DISTRIB_DESCRIPTION="Ubuntu 11.04" $ python -c "import M2Crypto;print M2Crypto.version_info" (0, 20, 1) $ openssl version OpenSSL 0.9.8o 01 Jun 2010 1) NOT OK SERVER (terminal 1): $ python ssl-server.py CLIENT (terminal 2): $ openssl s_client -connect localhost:4433 -cipher EXPORT CONNECTED(00000003) 28131:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:602: 2) OK SERVER (terminal 1): $ openssl s_server -cert dummy_cert.pem -key dummy_key.pem -ssl3 -no_tls1 -no_ssl2 -cipher EXPORT CLIENT (terminal 2): $ openssl s_client -connect localhost:4433 -cipher EXPORT CONNECTED(00000003) depth=0 C = BE, CN = www.example.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 C = BE, CN = www.example.com verify error:num=27:certificate not trusted verify return:1 depth=0 C = BE, CN = www.example.com verify error:num=21:unable to verify the first certificate verify return:1 --- Certificate chain 0 s:/C=BE/CN=www.example.com i:/C=BE/CN=test-ca --- Server certificate -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- subject=/C=BE/CN=www.example.com issuer=/C=BE/CN=test-ca --- No client certificate CA names sent --- SSL handshake has read 1141 bytes and written 242 bytes --- New, TLSv1/SSLv3, Cipher is EXP-EDH-RSA-DES-CBC-SHA Server public key is 1024 bit Secure Renegotiation IS supported Compression: zlib compression Expansion: zlib compression SSL-Session: Protocol : SSLv3 Cipher : EXP-EDH-RSA-DES-CBC-SHA Session-ID: B052D5D5A436F9A0B9D3FB24F2E32A8A06A0B6828230621C4CFAEB82A0A9AE0C Session-ID-ctx: Master-Key: 47F6E3720D06518B961FE389F13BCDE42C37F703099ABBB9B3DA35383C420F519D4F4773D35E470CF6FF7BB243B29069 Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Compression: 1 (zlib compression) Start Time: 1340644713 Timeout : 300 (sec) Verify return code: 21 (unable to verify the first certificate) --- при $ uname -a Linux XYZ 2.6.38-15-generic #59-Ubuntu SMP Fri Apr 27 16:03:32 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=11.04 DISTRIB_CODENAME=natty DISTRIB_DESCRIPTION="Ubuntu 11.04" $ python -c "import M2Crypto;print M2Crypto.version_info" (0, 20, 1) $ openssl version OpenSSL 0.9.8o 01 Jun 2010 1) NOT OK SERVER (terminal 1): $ python ssl-server.py CLIENT (terminal 2): $ openssl s_client -connect localhost:4433 -cipher EXPORT CONNECTED(00000003) 28131:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:s23_clnt.c:602: 2) OK SERVER (terminal 1): $ openssl s_server -cert dummy_cert.pem -key dummy_key.pem -ssl3 -no_tls1 -no_ssl2 -cipher EXPORT CLIENT (terminal 2): $ openssl s_client -connect localhost:4433 -cipher EXPORT CONNECTED(00000003) depth=0 C = BE, CN = www.example.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 C = BE, CN = www.example.com verify error:num=27:certificate not trusted verify return:1 depth=0 C = BE, CN = www.example.com verify error:num=21:unable to verify the first certificate verify return:1 --- Certificate chain 0 s:/C=BE/CN=www.example.com i:/C=BE/CN=test-ca --- Server certificate -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE----- subject=/C=BE/CN=www.example.com issuer=/C=BE/CN=test-ca --- No client certificate CA names sent --- SSL handshake has read 1141 bytes and written 242 bytes --- New, TLSv1/SSLv3, Cipher is EXP-EDH-RSA-DES-CBC-SHA Server public key is 1024 bit Secure Renegotiation IS supported Compression: zlib compression Expansion: zlib compression SSL-Session: Protocol : SSLv3 Cipher : EXP-EDH-RSA-DES-CBC-SHA Session-ID: B052D5D5A436F9A0B9D3FB24F2E32A8A06A0B6828230621C4CFAEB82A0A9AE0C Session-ID-ctx: Master-Key: 47F6E3720D06518B961FE389F13BCDE42C37F703099ABBB9B3DA35383C420F519D4F4773D35E470CF6FF7BB243B29069 Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Compression: 1 (zlib compression) Start Time: 1340644713 Timeout : 300 (sec) Verify return code: 21 (unable to verify the first certificate) --- 

Содержимое dummy_cert.pem выглядит следующим образом:

 -----BEGIN CERTIFICATE----- MIICkTCCAfqgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAfMQswCQYDVQQGEwJCRTEQ MA4GA1UEAxMHdGVzdC1jYTAeFw0xMjA1MDYwODQyNDlaFw0yMjA1MDMwODQyNDla MCcxCzAJBgNVBAYTAkJFMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wgZ8wDQYJ KoZIhvcNAQEBBQADgY0AMIGJAoGBAL7OBv9wRwtNjN984XSy22/rw6tHM6Lq/Ccf NoHKbqwC+PsxgmgJJiGBGewrzBR42toqHJi7EjHhuvrgqV9s2duPQBAANh7tzY1h 6VekrwhIIt4o1h0F2KB16VXA8s918d+8pRGt2T11GUh/QT3m9yY1VzqdIBeAfklC ET6ncPK/AgMBAAGjgdQwgdEwCQYDVR0TBAIwADARBglghkgBhvhCAQEEBAMCBkAw KwYJYIZIAYb4QgENBB4WHFRpbnlDQSBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYD VR0OBBYEFNGQArEZPKprJTn7A64qEFfl0m4xME8GA1UdIwRIMEaAFFuITOUJlGrJ 9lKufs8cm1MpwXrroSOkITAfMQswCQYDVQQGEwJCRTEQMA4GA1UEAxMHdGVzdC1j YYIJALimgW7YUgdrMAkGA1UdEgQCMAAwCQYDVR0RBAIwADANBgkqhkiG9w0BAQUF AAOBgQDWh8A0eBxI9XHy68xdjFsk2oerJeV6qqlcmtPZgz3GlarRcWcKsRJOyLLL dCOe7tY5isWQAoLt6XALzDWjbQkTJnxBaKHif1MIikuajaYKT7LA1MvFn50Qrm6n f9hG7gvdTpm1rlPcs0qibp1vJVubkU51mT6JT4UnLfeVIjtL7Q== -----END CERTIFICATE----- 

Содержимое dummy_key.pem выглядит следующим образом:

 -----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQC+zgb/cEcLTYzffOF0sttv68OrRzOi6vwnHzaBym6sAvj7MYJo CSYhgRnsK8wUeNraKhyYuxIx4br64KlfbNnbj0AQADYe7c2NYelXpK8ISCLeKNYd BdigdelVwPLPdfHfvKURrdk9dRlIf0E95vcmNVc6nSAXgH5JQhE+p3DyvwIDAQAB AoGBAIZldIRkP4Z0n2+j9OJQQUS6Wl7AjlyJDAc6cxhE0GOUzG+S1foVx6f92ZaC 2wLoha75zp691fkQuLWRnXu7nk9QwxQdOppKijIPHdL2cYtUc9UCedN5rExjpcOP 4Hjwf17YOxK2J0zzmG1djTBB47BKGUedSQ7E1QxGcrESS2XxAkEA+6ey2jy8etWi QmCdJJIxXwKRVHCmt5LVwj+IOk/u3sr1AGfBm7spKGU3boCiFt4FmjGMax7B9r/e zPaMb34guwJBAMIZX7Vv5gfjvWtgp6pyE/UkjRSOKBpuy9gyiqtLBJwehj/qsBqr O6tFmjMFiudVusnVSrEFGAPLV52xf0U4580CQQDkEQ1UH2spX2dYBLslo6A+3NLc 1eMhx18WVgGd50cyfnkfzuh1vF8GjwR3jvhXBQvKvFDn284pU6YV1vNbL9F1AkEA o2CwSwyRV3q+6i9Fchbr7aCCkBbIctdoBeclCeHvU2nuHsbwzMHtS9EeZmv365kh zNoYMMDU4fy7FyVct2ua0QJASXtIwYKZ2CAP+lAQqfh+knRRqtqdLt4Lt0mpML5m UtsECS8frKeF3mynXfsyRkvC8F2WFiJVJ3+D+y3zYNGlZg== -----END RSA PRIVATE KEY----- 

Обновление : при использовании пакетов подтверждения низкого уровня, похоже, одно и то же, за исключением того, что random[32] поле random[32] делает это еще более странным.

SSL-дамп ( ssldump -a -A -H -i lo ) для обоих случаев можно найти здесь:

http://pastebin.com/YuC7d8zg (НЕ ОК)

http://pastebin.com/U6YGQmv9 (OK)

One Solution collect form web for “Шифры EXP (ORT) и M2Crypto / OpenSSL”

Мне понадобились следующие два твика для скрипта python, чтобы он работал с наборами экспортных шифров:

 PROTOCOL = "sslv23" ... print "[i] Initializing context ..." ctx = M2Crypto.SSL.Context(protocol=PROTOCOL, weak_crypto=True) ctx.load_cert_chain(certchainfile=CERTFILE, keyfile=KEYFILE) ctx.set_options(M2Crypto.m2.SSL_OP_ALL) ctx.set_tmp_rsa(M2Crypto.RSA.gen_key(512, 65537)) ctx.set_cipher_list("ALL") 

То есть:

  1. Использовать SSLv23 в качестве идентификатора протокола (режим совместимости SSLv2 / v3). Не уверен, зачем это нужно в этом случае, но, похоже, не работает иначе.
  2. Установите временный, эфемерный ключ RSA в контексте, используя set_tmp_rsa() . Это необходимо, потому что с помощью экспортных шифров предоставленный (1024-разрядный) ключ RSA используется только для аутентификации (подписи), а временный, поврежденный экспортю 512-разрядный ключ RSA используется для обеспечения конфиденциальности (шифрования). OpenSSL требует, чтобы вы установили этот ключ в контексте (см. Документацию по SSL_set_tmp_rsa () ).

Как ни странно, он также работает только в режиме -ssl2 (используя -ssl2 on openssl s_client при тестировании) без установки временного ключа RSA (вызов в set_tmp_rsa закомментирован в скрипте). Понятия не имею почему.

В общем, для некоторых наборов шифров в контекст добавляются специальные ключи, например, с использованием DH (параметры группы) или ECDH (кривая). Чтобы точно увидеть, что используется для каждого набора openssl ciphers -v , openssl ciphers -v могут быть проницательными, например:

 % openssl ciphers -v EXPORT EXP-EDH-RSA-DES-CBC-SHA SSLv3 Kx=DH(512) Au=RSA Enc=DES(40) Mac=SHA1 export EXP-EDH-DSS-DES-CBC-SHA SSLv3 Kx=DH(512) Au=DSS Enc=DES(40) Mac=SHA1 export EXP-ADH-DES-CBC-SHA SSLv3 Kx=DH(512) Au=None Enc=DES(40) Mac=SHA1 export EXP-DES-CBC-SHA SSLv3 Kx=RSA(512) Au=RSA Enc=DES(40) Mac=SHA1 export EXP-RC2-CBC-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export EXP-RC2-CBC-MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export EXP-ADH-RC4-MD5 SSLv3 Kx=DH(512) Au=None Enc=RC4(40) Mac=MD5 export EXP-RC4-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export EXP-RC4-MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export 

EDIT в ответ на вопрос о наборах шифрования DSS:

Для наборов шифров DSS / DSA требуются параметры DH и, конечно же, серверный сертификат DSS / DSA вместо (только) RSA. Это справедливо не только для наборов экспортных шифров, но и для всех наборов с использованием DSS / DSA для аутентичности. DSS / DSA могут быть разработаны только для подписей, а не для шифрования, чтобы обеспечить экспорт в ненадежные страны. Поскольку DSS / DSA может использоваться только для подписей, ему нужен эфемерный обмен ключами Диффи-Хеллмана для создания общего сеансового ключа. Это то, что означает EDH в наборе шифров. Чтобы настроить параметры DH, вы должны использовать эквиваленты M2Crypto API OpenSSL SSL_set_tmp_dh () .

Обратите внимание, что OpenSSL позволяет загружать RSA и DSA / DSS cert / keypair в один и тот же контекст SSL.

  • Python: чтение сертификата pkcs12 с pyOpenSSL.crypto
  • Python и 'print ssl.OPENSSL_VERSION' печатает неправильную версию
  • используя pyOpenSSL для создания пользовательского открывателя urllib
  • AttributeError: объект «Контекст» не имеет атрибута «wrap_socket»
  • Как заблокировать SSL-протоколы в пользу TLS?
  • Веб-приложение висит в течение нескольких часов в ssl.py на self._sslobj.do_handshake ()
  • Python AttributeError: объект 'module' не имеет атрибута 'SSL_ST_INIT'
  • Ошибка загрузки закрытого ключа с помощью OpenSSL.crypto.Error:
  •  
    Interesting Posts for Van-Lav

    Захват опечаток на языках сценариев

    Python: как импортировать из файла __init__.py?

    класс __init __ () принимает ровно 2 аргумента (1 данный)

    Имейте указатель на данные. Нужен массив Numpy в порядке Fortran. Хотите использовать Cython

    Как TDD может быть применен к Generic Views на основе Django?

    cx_freeze, как включить сторонние модули, ImportError: нет модуля с именем progressbar

    Python – Дескриптор 'split' требует объекта 'str', но получил 'unicode'

    Mongoengine PointField дает ожидаемый объект местоположения, массив местоположений не соответствует правильной ошибке формата

    Как проверить подключение к базе данных в python?

    Расчет положения звезды в небе, PyEphem

    Преобразование даты, полученной с сервера ntp с помощью python

    Когда вычисляется хэш-объект python и почему хэш -1 отличается?

    Получить доменное имя из URL

    Ошибка gcc, пытающаяся установить PIL в виртуальный файл Python2.6

    NoSql с моими собственными бинарными файлами?

    Python - лучший язык программирования в мире.