我正在尝试编写一个能够在服务器之间交换数据的通用服务器客户端应用程序。我已经阅读了很多 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。然后,我将两个“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')