我正在尝试编写一个通用的服务器客户端应用程序,它将能够在服务器之间交换数据。我已经阅读了相当多的 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.错误:[('SSL 例程', 'SSL3_READ_BYTES', 'sslv3 警报握手失败'), ('SSL 例程', 'SSL3_WRITE_BYTES', 'ssl 握手失败')]

有人可以解释一下这是否是 SSL 的预期行为。我真的需要将私钥和公共证书分发给所有客户吗?我试图避免任何巨大的安全问题,而泄露私钥往往会是一个大问题......

谢谢您的帮助!

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

感谢caf帮我解决了这个问题。根据他的建议,我创建了两个新的证书对:太空人和 dmgr。然后,我将两个“spaceman”部分(密钥、证书)放入客户端程序中,“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')
有帮助吗?

解决方案

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

该证书/私钥对是您正在设置的 use_privatekey_file()use_certificate_file(). 。这应该是一个 不同的 服务器和客户端上的证书/密钥对。

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

  • 该证书是 有效的 (即由您对此申请信任的 CA 签署、未过期、未撤销);和
  • 对应于您的同行 思考 您已连接到(即证书与对等方声明的身份匹配)。该身份存储在 SubjectName 证书的字段,以及如何将其映射到对等身份(可能是用户登录名、DNS 名称或其他名称)是特定于应用程序的。
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top