2011-01-05 70 views
0

我想寫一個通用的服務器客戶端應用程序,它將能夠在服務器之間交換數據。 我已經閱讀了很多OpenSSL文檔,並且已經成功設置了自己的CA並創建了用於測試目的的證書(和私鑰)。我需要爲Python w/SSL-socket連接分發(密鑰,證書)?

我被Python 2.3卡住了,所以我不能使用標準的「ssl」庫。相反,我堅持使用PyOpenSSL,這看起來並不壞,但沒有太多關於它的文檔。

我的問題並不在於讓它工作。我對證書和他們需要去的地方感到困惑。

這裏是我的兩個程序工作:

服務器:

#!/bin/env python 

from OpenSSL import SSL 
import socket 
import pickle 

def verify_cb(conn, cert, errnum, depth, ok): 
    print('Got cert: %s' % cert.get_subject()) 
    return ok 


ctx = SSL.Context(SSL.TLSv1_METHOD) 
ctx.set_verify(SSL.VERIFY_PEER|SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb) 

# ?????? 
ctx.use_privatekey_file('./Dmgr-key.pem') 
ctx.use_certificate_file('Dmgr-cert.pem') 
# ?????? 
ctx.load_verify_locations('./CAcert.pem') 

server = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) 

server.bind(('', 50000)) 
server.listen(3) 

a, b = server.accept() 

c = a.recv(1024) 
print(c) 

客戶:

from OpenSSL import SSL 
import socket 
import pickle 


def verify_cb(conn, cert, errnum, depth, ok): 
    print('Got cert: %s' % cert.get_subject()) 
    return ok 

ctx = SSL.Context(SSL.TLSv1_METHOD) 
ctx.set_verify(SSL.VERIFY_PEER, verify_cb) 

# ?????????? 
ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem') 
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem') 
# ????????? 
ctx.load_verify_locations('/home/justin/code/work/CA/CAcert.pem') 

sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) 
sock.connect(('10.0.0.3', 50000)) 

a = Tester(2, 2) 
b = pickle.dumps(a) 
sock.send("Hello, world") 

sock.flush() 
sock.send(b) 
sock.shutdown() 
sock.close() 

我發現從ftp://ftp.pbone.net/mirror/ftp.pld-linux.org/dists/2.0/PLD/i586/PLD/RPMS/python-pyOpenSSL-examples-0.6-2.i586.rpm這個信息裏面包含了一些示例腳本秒。

正如你可能收集的,我不完全理解「#????????」之間的部分。我不明白爲什麼客戶端和服務器都需要證書和私鑰。我不確定每個人應該去哪裏,但是不應該只需要分配一部分密鑰(可能是公共部分)?它破壞了非對稱密鑰的目的,如果你仍然需要在每個服務器上,對吧?

我試圖交替在任箱中取出要麼p鍵或證書,我也得到了下面的錯誤無論哪個我刪除:

OpenSSL.SSL.Error: [('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert handshake failure'), ('SSL routines', 'SSL3_WRITE_BYTES', 'ssl handshake failure')]

有人能解釋這是否是SSL的預期行爲。我真的需要將私鑰和公共證書分發給所有客戶嗎? 我試圖避免任何巨大的安全問題,並泄漏私人鑰匙往往會是一個大...

感謝您的幫助!

============================================== ====================

感謝caf幫我找出問題所在。根據他的建議,我創建了兩個新的證書對:spaceman和dmgr。然後,我將兩個「太空人」部件(鑰匙,證書)放在客戶端程序中,而「dmgr」鑰匙也一樣。

基本上,客戶端中只有以下兩行發生了變化,儘管openssl的工作非常繁忙。

ctx.use_privatekey_file('/home/justin/code/work/CA/private/Dmgr-key.pem') 
ctx.use_certificate_file('/home/justin/code/work/CA/Dmgr-cert.pem') 

更正版本:

ctx.use_privatekey_file('/home/justin/code/work/CA/private/spaceman-key.pem') 
ctx.use_certificate_file('/home/justin/code/work/CA/spacemancert.pem') 
+0

我在遇到麻煩(ssl握手失敗)的事情。你能準確地告訴我你的每個pem文件是什麼嗎?因爲我有這個:1)client.key包含客戶端的私鑰。 (我在use_privatekey_file中使用)2)ca.crt在一個以=== BEGIN CERTIFICATE ===開頭並以=== END CRTIFICATE ===結尾的塊中只有ca的證書3)client.crt,它具有整個證書作爲客戶端通用名稱,狀態信息....然後另一個隨機字符塊 – 2011-04-25 06:20:01

回答

4

在SSL事務,每一方可以呈現證書以驗證其身份到另一側。爲此,它需要擁有與該證書相對應的私鑰。這些打算是兩個不同的證書,所以每一方都會有兩個不同的私鑰。

此證書/私鑰對是您使用use_privatekey_file()use_certificate_file()設置的證書/私鑰對。這應該是服務器和客戶端上的不同的證書/密鑰對。

當驗證雙方的證書,您則需要檢查:

  • 該證書是有效(即,由你爲這個應用程序信任的CA簽署的,沒有過期,沒有被撤銷) ;和
  • 對應於您連接到的認爲的對等體(即,證書與對等體聲明的身份相匹配)。此標識存儲在證書的SubjectName字段中,並且它是特定於應用程序的,如何將其映射到對等標識(可能是用戶登錄名,DNS名稱或其他名稱)。
+0

非常感謝caf。我正在考慮SSL更像SSH密鑰。我忘記了SSL的整個想法是不需要預先分配密鑰,只需要根CA.沒有必要將我的公鑰或私鑰複製到其他服務器。之前我的程序工作的原因與計算機之間的鍵匹配無關,而是兩個「驗證」功能中的鍵(公共,私有)匹配。查看上面更正的代碼。 – fandingo 2011-01-06 06:01:52