2011-01-05 102 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