我需要提供安全的通信之间的各种过程使用TCP/IP socket进行通信。我想要两个身份验证和加密。而不是重新发明轮子我真的很喜欢使用SSL和SslStream类和自签证书。什么我想要做的是验证遥进程证书针对一个已知的副本,我的本地应用程序。(有不需要一个认证机构,因为我打算用于证书的复制约手动).

要做到这一点,我想要应用程序是能够自动生成一个新的certifiate第一次运行。除了makecert.exe它看起来像 这个链接 显示了一种可以自动生成的自签名证书,所以这是一个开始。

我已经看了该AuthenticateAsServer和AuthenticateAsClient方法的SslStream.你可以提供呼叫-最后验证,因此它看起来像它是可能的。但是现在我成的详细信息,我真的不认为这是可能做到这一点。

我走在正确的方向?是否有一个更好的选择吗?有没有人做过任何像这样的前的(基本上是对等SSL而不是客户机-服务器)?

有帮助吗?

解决方案

步骤1: 产生一个自签发的证书:

  • 我下载了 证书。cs类 发表道格的厨师
  • 我用这个代码生成的一个。pfx证书的文件:

    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.默认SslProtocols.默认的
  • 有3个警告有关废弃的功能。我代替他们的所有建议的替代品。
  • 我取代了这条线的服务器节目。cs文件的线从第2步:

    X509证书该cert=getServerCert();

  • 在客户程序。cs文件,确保你设置的服务器名称=yourhostname.com (并,它的名称匹配的证书)

  • 在客户程序。cs,CertificateValidationCallback功能失败,因为sslPolicyErrors包含一个RemoteCertificateChainErrors.如果你挖得更深一些,这是因为发放机构签署的证书不是一个受信任的根源。
  • 我不想进入具有用户进口证书为根储存等等, 所以我做了一个特殊的情况下为此,我检查证书。GetPublicKeyString()等于公共钥匙,我已在文件服务器。如果匹配,我回真正的自这一职能。这似乎工作。

步骤4: 客户身份验证

这里是我的客户进行身份验证(这一点不同于服务器):

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,像这样(在这种情况下,我只有一个客户证书,所以我只是回第一个在收集):

static X509Certificate CertificateSelectionCallback(object sender,
    string targetHost,
    X509CertificateCollection localCertificates,
    X509Certificate remoteCertificate,
    string[] acceptableIssuers)
{
    return localCertificates[0];
}

其他提示

你可以看看太这个例子 样品异步SslStream客户端/服务器实现 的http:// blogs.msdn.com/joncole/archive/2007/06/13/sample-asynchronous-sslstream-client-server-implementation.aspx

如果证书没有被正确生成,你可以得到例外的服务器模式SSL必须使用证书与关联的私钥。

基本证书示例

makecert -SR LOCALMACHINE -ss我-n CN =测试-sky交换-SK 123456

作为外部文件

makecert -SR LOCALMACHINE -ss我-n CN =测试-sky交换-SK 123456个C:\ Test.cer

证书创建工具(Makecert.exe),点击 http://msdn.microsoft.com/en-我们/库/ bfsktky3%28VS.80%29.aspx

什么你建议听起来不错,对我来说,除了它听起来就像你希望等到回调,以便生成证书调用。我不认为这会飞翔;据我所知,你有,当你调用AuthenticateAsX提供有效的证书。

但是,这些类是可重写的;因此在理论上,可以创建派生类,看是否有证书需要生成哪个首先检查,生成它,如果需要的话,然后调用父AuthenticateAsX方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top