使用SSL和SslStream用于点对点的认证? [英] Using SSL and SslStream for peer to peer authentication?
问题描述
我需要提供使用TCP / IP套接字通信各工序间的安全通信。我想这两个身份验证和加密。而不是重新发明轮子我真的想使用SSL和SslStream类和自签名的证书。我想要做的就是验证远程进程的证书对我的本地应用程序的一个已知的副本。 (这里并不需要一个证书颁发机构,因为我打算在证书手动复制左右)。
I need to provide secure communication between various processes that are using TCP/IP sockets for communication. I want both authentication and encryption. Rather than re-invent the wheel I would really like to use SSL and the SslStream class and self-signed certificates. What I want to do is validate the remote process's certificate against a known copy in my local application. (There doesn't need to be a certificate authority because I intend for the certificates to be copied around manually).
要做到这一点,我希望应用程序能够自动生成一个新的certifiate它运行的第一次。除了makecert.exe,它看起来像<一个href=\"http://blogs.msdn.com/dcook/archive/2008/11/25/creating-a-self-signed-certificate-in-c.aspx\">this链接显示了一种方法来自动生成自签名证书,所以这是一个开始。
To do this, I want the application to be able to automatically generate a new certifiate the first time it is run. In addition to makecert.exe, it looks like this link shows a way to automatically generate self-signed certificates, so that's a start.
我看SslStream的AuthenticateAsServer和AuthenticateAsClient方法。您可以为验证提供回调,所以看起来这是可能的。但现在,我把它的细节,我真的不认为这是可能做到这一点。
I've looked at the AuthenticateAsServer and AuthenticateAsClient methods of SslStream. You can provide call-backs for verification, so it looks like it's possible. But now that I'm into the details of it, I really don't think it's possible to do this.
我在正确的方向前进?有没有更好的选择吗?有没有人(基本上是对等网络SSL,而不是客户端 - 服务器)做过这样的事?
Am I going in the right direction? Is there a better alternative? Has anyone done anything like this before (basically peer-to-peer SSL rather than client-server)?
推荐答案
第1步:生成自签名证书:
- 我下载的<一个href=\"http://blogs.msdn.com/dcook/archive/2008/11/25/creating-a-self-signed-certificate-in-c.aspx\">Certificate.cs类张贴由道格·库克
-
我用这个code生成一个.pfx证书文件:
- I downloaded the Certificate.cs class posted by Doug Cook
I used this code to generate a .pfx certificate file:
byte[] c = Certificate.CreateSelfSignCertificatePfx(
"CN=yourhostname.com", //host name
DateTime.Parse("2000-01-01"), //not valid before
DateTime.Parse("2010-01-01"), //not valid after
"mypassword"); //password to encrypt key file
using (BinaryWriter binWriter = new BinaryWriter(
File.Open(@"testcert.pfx", FileMode.Create)))
{
binWriter.Write(c);
}
第二步:加载证书
X509Certificate cert = new X509Certificate2(
@"testcert.pfx",
"mypassword");
第3步:将其组合在一起
- 我根据它这个非常简单的例子SslStream
- 您将获得有关SslProtocolType枚举一个编译时错误。只要改变,从SslProtocolType.Default到SslProtocols.Default
- 大约有去precated功能3警告。我更换了他们所有建议的替代品。
-
我取代的Program.cs一行的文件从服务器在此行第2步:
- I based it on this very simple SslStream example
- You will get a compile time error about the SslProtocolType enumeration. Just change that from SslProtocolType.Default to SslProtocols.Default
- There were 3 warnings about deprecated functions. I replaced them all with the suggested replacements.
I replaced this line in the Server Program.cs file with the line from Step 2:
X509证书证书= getServerCert();
X509Certificate cert = getServerCert();
在客户端的Program.cs文件,请确保您设置服务器名= yourhostname.com(以及它的证书中的名称一致)
In the Client Program.cs file, make sure you set serverName = yourhostname.com (and that it matches the name in the certificate)
第四步:客户端身份验证
下面是我的客户如何验证(它比服务器略有不同):
Here's how my client authenticates (it's a little different than the server):
TcpClient client = new TcpClient();
client.Connect(hostName, port);
SslStream sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(CertificateValidationCallback),
new LocalCertificateSelectionCallback(CertificateSelectionCallback));
bool authenticationPassed = true;
try
{
string serverName = System.Environment.MachineName;
X509Certificate cert = GetServerCert(SERVER_CERT_FILENAME, SERVER_CERT_PASSWORD);
X509CertificateCollection certs = new X509CertificateCollection();
certs.Add(cert);
sslStream.AuthenticateAsClient(
serverName,
certs,
SslProtocols.Default,
false); // check cert revokation
}
catch (AuthenticationException)
{
authenticationPassed = false;
}
if (authenticationPassed)
{
//do stuff
}
的CertificateValidationCallback是一样的,在服务器的情况下,但请注意AuthenticateAsClient如何发生的证书的集合,而不是仅仅一个证书。所以,你必须添加一个LocalCertificateSelectionCallback,像这样(在这种情况下,我只有一个客户端证书,所以我只返回集合中的第一个):
The CertificateValidationCallback is the same as in the server case, but note how AuthenticateAsClient takes a collection of certificates, not just one certificate. So, you have to add a LocalCertificateSelectionCallback, like this (in this case, I only have one client cert so I just return the first one in the collection):
static X509Certificate CertificateSelectionCallback(object sender,
string targetHost,
X509CertificateCollection localCertificates,
X509Certificate remoteCertificate,
string[] acceptableIssuers)
{
return localCertificates[0];
}
这篇关于使用SSL和SslStream用于点对点的认证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!