2012-06-19 38 views
14

Tôi gặp khó khăn khi chạy một SSLServer M2Crypto với mật mã lớp xuất.Mật mã EXP (ORT) và M2Crypto/OpenSSL

Mật mã LOW/MEDIUM/HIGH làm việc mà không gặp bất kỳ sự cố nào, nhưng EXPORT sẽ không hoạt động. Ngoài ra, khi OpenSSL được chạy trong một chế độ máy chủ từ một dòng lệnh, nó chấp nhận mật mã lớp XUẤT KHẨU mà không có bất kỳ vấn đề gì.

Vì vậy, tôi thiếu một số thứ hoặc có sự cố trong mô-đun M2Crypto. Bất kỳ trợ giúp được đánh giá cao.

đã qua sử dụng mã python (ssl-server.py) trông như thế này:

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() 

Các triệu chứng bao gồm:

$ 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) 
--- 

Nội dung của một dummy_cert.pem là như sau:

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

Nội dung của một dummy_key.pem như sau:

-----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----- 

Cập nhật: ở cấp thấp gói bắt tay dường như là giống nhau ngoại trừ việc random[32] lĩnh vực làm này thậm chí nhiều hơn lạ.

SSL bãi (ssldump -a -A -H -i lo) cho cả hai trường hợp có thể được tìm thấy ở đây:

http://pastebin.com/YuC7d8zg (KHÔNG trường hợp OK)

http://pastebin.com/U6YGQmv9 (OK trường hợp)

+0

PKI của bạn chưa được thiết lập chính xác, trường hợp OK của bạn chỉ hiển thị kết nối SSL ẩn danh, không được phép. Máy chủ của bạn không gửi bất kỳ chứng chỉ nào đến máy khách. Lưu ý rằng gỡ lỗi thông qua các ngăn xếp SSL là một chút nhiều cho diễn đàn này; nó thường chứa rất nhiều lần thử/thử/thử lại mà không thể thực sự được thể hiện tốt, và có xu hướng mất nhiều thời gian. –

+0

Chúng tôi chỉ đang cố gắng tái tạo trường hợp OK đó (openssl s_server) bằng lập trình với M2Crypto. PKI không liên quan ở đây. Trong trường hợp OK, mã hóa XUẤT KHẨU được chọn trong khi trong M2Crypto thì không. Thing là tất cả mọi thứ hoạt động đúng với LOW, MEDIUM và HIGH, nhưng không phải với EXPORT. – stamparm

+0

Chỉ cần tự hỏi tại sao bạn muốn sử dụng thuật toán mã hóa XUẤT KHẨU ở nơi đầu tiên. [Chúng được coi là đủ yếu để bị cấm trong TLS 1.1] (http://tools.ietf.org/html/rfc4346#appendix-A.5) (hoàn thành 6 năm trước): "* TLS 1.1 khách hàng PHẢI kiểm tra rằng máy chủ không chọn một trong các bộ mã hóa này trong quá trình bắt tay. * " – Bruno

Trả lời

5

tôi cần hai chỉnh sau để kịch bản python để làm cho nó hoạt động với bộ mã hóa xuất khẩu:

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") 

Đó là:

  1. Sử dụng SSLv23 làm định danh giao thức (chế độ tương thích SSLv2/v3). Không chắc chắn tại sao nó là cần thiết trong trường hợp này, nhưng có vẻ như không làm việc khác.
  2. Đặt khóa RSA tạm thời, không lâu trên bối cảnh sử dụng set_tmp_rsa(). Điều này là bắt buộc vì với mật mã xuất, khóa RSA (1024 bit) được cung cấp chỉ được sử dụng để xác thực (ký), trong khi khóa RSA 512 bit tạm thời, xuất hiện được sử dụng để bảo mật (mã hóa). OpenSSL yêu cầu bạn thiết lập khóa này trong ngữ cảnh (xem documentation of SSL_set_tmp_rsa()).

thật là thú vị đủ, nó cũng làm việc trong chế độ SSLv2 chỉ (sử dụng -ssl2 trên openssl s_client khi thử nghiệm) mà không cần thiết lập một khóa RSA tạm thời (gọi để set_tmp_rsa nhận xét ra trong kịch bản). Tôi không biết tại sao.

Nói chung, một số bộ mã hóa yêu cầu thêm các phím đặc biệt vào ngữ cảnh, ví dụ: các bộ sử dụng DH (tham số nhóm) hoặc ECDH (đường cong). Để xem chính xác những gì được sử dụng cho mỗi bộ mã hóa, openssl ciphers -v có thể sâu sắc, ví dụ::

% 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 trong respone cho câu hỏi về DSS bộ mã hoá:

DSS/DSA bộ mã hoá cần các thông số DH, và dĩ nhiên một DSS/DSA dựa server certificate thay vì (chỉ) một RSA một. Điều này đúng không chỉ đối với các bộ mã hóa xuất khẩu, mà còn cho tất cả các dãy phòng sử dụng DSS/DSA để xác thực. DSS/DSA có thể bằng cách thiết kế chỉ được sử dụng cho chữ ký, không phải để mã hóa, để cho phép xuất khẩu vào các nước không đáng tin cậy. Bởi vì DSS/DSA chỉ có thể được sử dụng cho chữ ký, nó cần một trao đổi khóa Diffie-Hellman tạm thời để thiết lập một khóa phiên chia sẻ. Đó là những gì EDH trong bộ mã hóa đại diện cho. Để thiết lập thông số DH, bạn sẽ sử dụng tương đương M2Crypto của API OpenSSL SSL_set_tmp_dh().

Lưu ý rằng OpenSSL cho phép tải cả RSA và cặp khóa/chứng chỉ DSA/DSS vào cùng một ngữ cảnh SSL.

+0

Xin chào Daniel. Cảm ơn bạn vì câu trả lời. Vẫn còn một câu hỏi liên quan (phụ) để xóa tất cả điều này. Mật mã "EXP-EDH-DSS-DES-CBC-SHA" có thể cần các tham số DSS được thiết lập để sử dụng nhưng chúng tôi không thể tìm thấy hàm thích hợp bên trong M2Crypto/OpenSSL để làm điều đó (như set_tmp_rsa() và/hoặc set_tmp_dh() được sử dụng trong các trường hợp khác). Thật tuyệt vời nếu bạn (hoặc ai đó khác) có thể chỉ cho chúng tôi đúng hướng làm thế nào để làm điều đó. – stamparm

+0

Bạn cần thiết lập thông số DH cho bộ mã hóa DSS, xem phần chỉnh sửa ở trên. Và tất nhiên là một chứng chỉ máy chủ DSS, không phải (chỉ) một RSA. –

+0

Cảm ơn bạn rất nhiều Daniel. Câu trả lời của bạn là một trợ giúp tuyệt vời – stamparm

Các vấn đề liên quan