如何在Python中复制证书认证(Mumble(c/c++))?
好的,在我开始这个帖子之前,我得先提醒你,这可能不是一个简单的解决办法。能看到并回复这个帖子的朋友,应该对C/C++有一定了解,至少也要懂一些Python,才能回答我上面提到的问题。
简单来说,我有一个来自Mumble(一个语音聊天客户端)的连接方法,它可以连接到服务器,并发送一个SSL证书用于身份验证。同时,我还有一个Python脚本,它也能连接到同一个Mumble语音服务器,但我并没有发送证书。
我需要修改我现有的代码,让它像当前的Mumble客户端那样发送证书。
--
这是看起来能发送证书的C++代码:
ServerHandler::ServerHandler() {
MumbleSSL::addSystemCA();
{
QList<QSslCipher> pref;
foreach(QSslCipher c, QSslSocket::defaultCiphers()) {
if (c.usedBits() < 128)
continue;
pref << c;
}
if (pref.isEmpty())
qFatal("No ciphers of at least 128 bit found");
QSslSocket::setDefaultCiphers(pref);
}
void ServerHandler::run() {
qbaDigest = QByteArray();
QSslSocket *qtsSock = new QSslSocket(this);
qtsSock->setPrivateKey(g.s.kpCertificate.second);
qtsSock->setLocalCertificate(g.s.kpCertificate.first.at(0));
QList<QSslCertificate> certs = qtsSock->caCertificates();
certs << g.s.kpCertificate.first;
qtsSock->setCaCertificates(certs);
cConnection = ConnectionPtr(new Connection(this, qtsSock));
qtsSock->setProtocol(QSsl::TlsV1);
qtsSock->connectToHostEncrypted(qsHostName, usPort);
void ServerHandler::serverConnectionConnected() {
tConnectionTimeoutTimer->stop();
qscCert = cConnection->peerCertificateChain();
qscCipher = cConnection->sessionCipher();
if (! qscCert.isEmpty()) {
const QSslCertificate &qsc = qscCert.last();
qbaDigest = sha1(qsc.publicKey().toDer());
bUdp = Database::getUdp(qbaDigest);
} else {
bUdp = true;
}
QStringList tokens = Database::getTokens(qbaDigest);
foreach(const QString &qs, tokens)
mpa.add_tokens(u8(qs));
QMap<int, CELTCodec *>::const_iterator i;
for (i=g.qmCodecs.constBegin(); i != g.qmCodecs.constEnd(); ++i)
mpa.add_celt_versions(i.key());
sendMessage(mpa);
--
而现在,我在Python中连接的方式是这样的:
try:
self.socket.connect(self.host)
except:
print self.threadName,"Couldn't connect to server"
return
self.socket.setblocking(0)
print self.threadName,"connected to server"
--
所以……我需要在我的Python代码中做些什么,才能连接到需要证书的服务器呢?因为我现在的代码可以顺利连接到任何requirecert设置为false的Mumble服务器。我需要它能在所有服务器上都能工作,因为这将用于我自己的服务器(讽刺的是,我的服务器是需要证书的)。
我可以预先生成证书,格式可以是.p12或其他类型的文件,所以我不需要程序来生成证书。我只需要它按照服务器的要求发送证书(就像我发的C++代码那样)。
请尽快帮我!如果你需要更多信息,可以再给我发消息。我已经去掉了所有不相关的代码,现在只剩下处理SSL的代码。
1 个回答
从这段C++代码来看,你只需要有SSL支持,并且使用正确的证书文件进行协商,然后用正确的私钥来加密数据。那些证书和私钥很可能就存放在你原来的程序里。如果C++可能会加载一些非标准的认证机构,你需要找出把这些根认证机构放在哪里,或者确保Python忽略这些问题,但这样做安全性就会降低。
在Python中,你可以像上面那样创建一个套接字,不过可以用urllib这个库。这个库支持HTTPS,并且可以提供证书和私钥。URLOpener
使用示例:
opener = urllib.URLopener(key_file = 'mykey.key', cert_file = 'mycert.cer')
self.socket = opener.open(url)
你可能还需要加一些错误检查之类的,让它更稳健,但希望这些信息能对你有帮助。