使用/ SSL-socket连接分发Python(密钥,证书)需要什么?

时间:2011-01-05 22:29:41

标签: python ssl openssl pyopenssl

我正在尝试编写一个能够在服务器之间交换数据的通用服务器 - 客户端应用程序。 我已经阅读了不少OpenSSL文档,并且我已经成功设置了自己的CA并创建了一个证书(和私钥)用于测试目的。

我坚持使用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找到了包含一些示例脚本的信息。

正如你可能会收集的那样,我并不完全理解“#????????”之间的部分。我不明白为什么客户端和服务器上都需要证书和私钥。我不确定每个应该去哪里,但是我不应该只分发密钥的一部分(可能是公共部分)?如果在每台服务器上仍然需要两个密钥,它会破坏非对称密钥的目的,对吗?

我尝试交替删除任何一个框上的pkey或cert,无论我删除哪个,我都会收到以下错误:

  

OpenSSL.SSL.Error:[('SSL例程','SSL3_READ_BYTES','sslv3警报握手失败'),('SSL例程','SSL3_WRITE_BYTES','ssl握手失败')]

有人可以解释这是否是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')

1 个答案:

答案 0 :(得分:4)

在SSL交易中,每一方都可以出示证书以向另一方验证其身份。为此,它需要具有与该证书对应的私钥。这些是两个不同的证书,因此每一方都有两个不同的私钥。

此证书/私钥对是您使用use_privatekey_file()use_certificate_file()设置的证书/私钥对。这应该是服务器和客户端上的不同的证书/密钥对。

验证对等证书时,您需要检查:

  • 证书有效(即由您信任此应用程序的CA签名,未过期,未撤销);和
  • 对应您所连接的认为的对等方(即证书与对等方声明的身份相匹配)。此标识存储在证书的SubjectName字段中,并且它是特定于应用程序的,如何将其映射到对等标识(可能是用户登录名,DNS名称或其他内容)。