使用 SSL 和 SslStream 进行对等身份验证? [英] Using SSL and SslStream for peer to peer authentication?

查看:44
本文介绍了使用 SSL 和 SslStream 进行对等身份验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在使用 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).

为此,我希望应用程序能够在第一次运行时自动生成新的证书.除了makecert.exe,它看起来像这个链接 展示了一种自动生成自签名证书的方法,所以这是一个开始.

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: 生成自签名证书:

  • 我下载了 Certificate.cs 类 由 Doug Cook 发布
  • 我使用此代码生成了一个 .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);
    }

第 2 步:加载证书

    X509Certificate cert = new X509Certificate2(
                            @"testcert.pfx", 
                            "mypassword");

第 3 步:组合起来

  • 我基于这个非常简单的 SslStream 示例
  • 您将收到有关 SslProtocolType 枚举的编译时错误.只需将其从 SslProtocolType.Default 更改为 SslProtocols.Default
  • 有 3 条关于已弃用函数的警告.我用建议的替代品替换了它们.
  • 我用步骤 2 中的行替换了 Server Program.cs 文件中的这一行:

  • 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:

X509Certificate cert = getServerCert();

X509Certificate cert = getServerCert();

在 Client Program.cs 文件中,确保设置 serverName = yourhostname.com(并且它与证书中的名称匹配)

In the Client Program.cs file, make sure you set serverName = yourhostname.com (and that it matches the name in the certificate)

第 4 步:客户端身份验证

以下是我的客户端进行身份验证的方式(与服务器略有不同):

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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆