我现在正在编写一个C#客户端(使用SSL的Mono)用于用C ++编写的已经存在的OpenSSL服务器。我知道理论上他们应该能够沟通,但我总是得到一个例外:
身份验证或解密失败。
当我调用sslStream.AuthenticateAsClient(ServerName)
时, Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback 会发生;
我不需要客户端身份验证,所以我不使用任何客户端证书,我无法将我的服务器证书加载到客户端的信任存储区,因为我无法使用该命令在客户端。
在服务器上,我似乎收到一些随机数据,这不应该发生,因为我从不在客户端代码中调用sslStream.Write()
。也许我不完全理解握手是如何发生的。我有一个完美的OpenSSL C ++客户端。
有人知道我怎么能让这个工作?
我在服务器端使用由OpenSSL生成的自签名证书,我将其转换为DER格式。
我正在尝试使用改编自this topic中的临时客户端进行连接。
sslStream.Write
,但执行永远不会到达。我非常感谢任何帮助,因为我不确定sslStream内部是如何工作的。
答案 0 :(得分:0)
好的,明白了。实际上,我是以错误的顺序设置BIO
和SSL
个变量。您必须创建BIO并将其附加到SSL BEFORE ,实际上在OpenSSL中调用SSL_Accept
,否则无法完成身份验证,这似乎是合乎逻辑的。
此外,我在客户端使用C#中的SSLStream
发送消息,而我在服务器端使用BIO_read
和BIO_write
使用OpenSSL。
这可能不有效,因为BIO_read
和BIO_write
与SSL_read
和SSL_write
不等同。这两个函数只在底层套接字上读写,没有任何加密或解密,使得SSL握手几乎无用(除了检查线路另一端的标识)。
这解释了为什么我无法进行沟通,因为两端不会说同一种语言:一个发送未加密的消息,另一个发送SSL包装的消息,反之亦然。
SSL_read
和SSL_Write
函数负责加密和解密,因此它们是在这里使用的。现在它完美无缺。
如果您需要有关我如何做到这一点的任何进一步细节,请评论此答案。