问题描述
我们的应用程序适用于 Active Directory 用户和组.我们在端口 389 上使用 LDAP 进行 Active Directory 操作.现在,我们的一位客户希望我们添加一个使用 LDAP + SSL 进行 Active Directory 通信的选项.
Our application works with Active Directory users and groups. We are using LDAP on port 389 for Active Directory operations. Now, one of our clients want us add an option for using LDAP + SSL for Active Directory communication.
他们告诉我们,他们在其域中安装了本地 CA,并为 LDAPS 使用自签名证书.他们还告诉我们他们会提供证书,不需要相互信任,我们应该使用 Windows 证书存储.
They told us that they have a local CA installed on their domain and using self signed certificate for LDAPS. They also told us that they will provide the certificate, no mutual-trust needed and we should use Windows certificate store.
我为 LDAP+SSL 操作开发了一个测试应用程序,并看到当客户端启动 LDAP+SSL 连接时服务器会发送其证书.我只能通过服务器证书验证方法返回true来建立连接.
I have developed a test application for LDAP+SSL operations and saw that server sends its certificate when a client initiates an LDAP+SSL connection. I can establish the connection only by returning true from the server certificate verification method.
问题是;- 客户应该给我们哪个证书(root,用于 LDAP+SSL 的证书...)?
The questions are; - Which certificate (root, the ceritificate used for LDAP+SSL...) should the customer give us?
在.Net环境下工作的证书应该是什么格式?
What should be the format of the certificate for working on .Net environment?
连接服务器时如何验证服务器证书?
How should I verify the server's certificate when connecting the server?
我们应该使用 Windows 证书存储"是什么意思?他们是否希望我们将服务器的证书自动添加到本地计算机的受信任证书存储中?
What they mean by "we should use Windows certificate store"? Do they want us add the server's certificate automatically to trusted certificate store of the local machine?
我用于 LDAP+SSL 连接的示例代码,
Sample code I used for LDAP+SSL connection,
LdapConnection _connection = new LdapConnection(new LdapDirectoryIdentifier(m_DomainName, m_PortNo));
_connection.Timeout = TimeSpan.FromMinutes(10);
_connection.AuthType = AuthType.Basic;
_connection.Credential = new NetworkCredential(m_UserName, m_Password);
_connection.SessionOptions.ProtocolVersion = 3;
_connection.SessionOptions.SecureSocketLayer = true;
_connection.SessionOptions.VerifyServerCertificate = (ldapCon, serverCertificate) =>
{
//TODO: Verify server certificate
return true;
};
_connection.SessionOptions.QueryClientCertificate = (con, trustedCAs) => null;
_connection.Bind();
推荐答案
客户应该给我们哪个证书(root,用于LDAP+SSL的证书...)?
签署 LDAP 服务器证书的根证书.他们也可以提前给你整个链,但无论如何都会在 TLS 握手期间发送.您只需要提前获得根证书即可.
The root certificate that signed the LDAP server cert. They can also give you the whole chain in advance, but that will be sent during TLS handshake anyway. You only need to have the root cert in advance.
在.Net环境下工作的证书应该是什么格式?
您可以导入 certmgr.msc 的任何内容.Pfx 是 Windows 上的常用选择.
Anything that you can import into certmgr.msc. Pfx is the usual choice on Windows.
连接服务器时如何验证服务器证书?
您不应该自己编写验证.证书验证是一项棘手的工作,并且已经为您完成了.使用内置的东西(见下文).
You should not write validation yourself. Certificate validation is tricky business, and it's already done for you. Use the built-in stuff (also see below).
我们应该使用 Windows 证书存储"是什么意思?他们是否希望我们将服务器的证书自动添加到本地计算机的受信任证书存储中?
是的.他们向您发送他们用于签署 ldap 服务器证书的根证书,然后您可以将其作为受信任的根导入.完成此操作后,您无需进行任何手动验证,它只适用于 :) 有效证书,不适用于无效证书.
Yes. They send you the root cert they used for signing the ldap server cert, which you can then import as a trusted root. Once this is done, you don't need to do any manual validation, it will just work :) with valid certificates and will not work with invalid ones.
请注意,一旦您将他们的根证书添加为受信任,他们就可以为安装其根的客户端伪造任何服务器证书,并且他们签署的任何内容都将被视为在该客户端上有效.
Note that once you add their root cert as trusted, they can forge any server certificate for the client their root is installed on, and anything they sign will be considered valid on that client.
奖励:添加半自定义验证和调试证书错误
您可能面临的一个问题是错误消息不是很有帮助.如果无法验证证书,您将收到一条非常笼统的错误消息,其中没有任何关于实际问题的提示.出于其他原因,您可能还想加入验证过程.
One problem that you may face is that error messages are not very helpful. If the certificate cannot be validated, you will get a very generic error message that has no hint about the actual problem. You may want to hook into the validation process for other reasons too.
为此,您可以定义自己的验证:
For this purpose, you can define your own validation:
private bool VerifyServerCertificate(LdapConnection ldapConnection, X509Certificate certificate)
{
X509Certificate2 certificate2 = new X509Certificate2( certificate );
return certificate2.Verify();
}
然后将其添加到ldap连接中:
And then add it to the ldap connection:
_connection.SessionOptions.VerifyServerCertificate =
new VerifyServerCertificateCallback( VerifyServerCertificate );
这样您可以在 Verify()
等上捕获异常.但同样,如果证书有效(可以由客户端验证),这不是严格需要的,无论如何它都是自动完成的.如果您想要一些未实现的东西,您只需要这个,例如,您可以在 VerifyServerCertificate
中返回 true 以接受任何证书,包括无效证书(这将是一个 Bad Idea并使安全连接无用,但可能有利于调试等).
This way you can catch exceptions on Verify()
etc. But again, if the certificate is valid (can be verified by the client), this is not strictly needed, it's done automatically anyway. You only need this if you want something not implemented, like for example you could just return true in VerifyServerCertificate
to accept any cert including the invalid ones (this would be a Bad Idea and makes a secure connection useless, but may be good for debugging, etc).
您可以在此方法中实现的另一件事是 证书固定 以提高安全性,但这超出了这个答案的范围.
Another thing you could implement in this method is certificate pinning for additional security, but that's beyond the scope of this answer.
这篇关于如何为 LDAP+SSL 连接验证服务器 SSL 证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!