5

我正在构建一个 C# 控制台应用程序,它将:

[1.] 生成自签名证书。

[2.] 将其添加到个人(本地计算机商店)

[3.] 最后使用 netsh 命令将该证书分配给机器上的端口号。

到目前为止,我的部分[1.][2.]工作得很好,但是在[3.]上,我被无用和非正式的错误消息所困扰:

SSL 证书添加失败,错误:1312 指定的登录会话不存在。它可能已经被终止。

当我去看微软关于这个问题的官方页面时:https: //support.microsoft.com/en-us/kb/981506

它基本上告诉我这是一个 Windows 操作系统错误,我应该请求一个修补程序。

我对这个问题的破解解决方案:

我最终绕过此错误的一种方法是打开 IIS 主页>打开“服务器证书”功能>然后导入我的 .pfx 证书。

通过将 .pfx 导入 IIS,我似乎能够毫无问题地解决这个问题。我只需要按顺序运行这两个命令来生成 .pfx

1.)C:\OpenSSL-Win32\bin>openssl req -x509 -sha256 -nodes -days 365 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=www.example.com" -newkey rsa:2048 -keyout privateKey.key -out certificate.crt

2.)C:\OpenSSL-Win32\bin>openssl pkcs12 -export -out cert.pfx -inkey privateKey.key -in certificate.crt -passout pass:

因此,如果我现在将这两个命令运行到 openssl,并通过 IIS 将它们导入我的个人本地计算机证书存储区,我将没有SSL Certificate add failed, Error: 1312问题。

但是,如果我以编程方式将新生成的证书添加到我的个人本地计算机证书存储中,那么我确实会遇到错误:1312 问题。

这是我的代码:

using CERTENROLLLib;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Diagnostics;

namespace Generate_X509_Certificate
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine(Guid.NewGuid().ToString());
            Console.ReadLine();

            // Launch OpenSSL:
            string cPath = @"C:\OpenSSL-Win32\bin\";
            string filename = Path.Combine(cPath, @"openssl.exe");

            // Generate a .crt file
            Console.WriteLine(@"Generating SSL Certificate...");
            ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\OpenSSL-Win32\bin\openssl.exe", @"req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey.key -out certificate.crt -subj ""/C=US/ST=California/L=SanFrancisco/CN=SecurityEncryption""");
            Process.Start(startInfo);

            // Combine the .crt with the .key to form a more Windows friendly .pfx
            Console.WriteLine(@"Combining Private Key With Certificate...");
            Process proc2 = Process.Start(filename, "pkcs12 -export -out cert.pfx -inkey privateKey.key -in certificate.crt -passout pass:");
            proc2.Close();

            // Store our newly created .pfx file as a variable
            X509Certificate2 cert = new X509Certificate2(Directory.GetCurrentDirectory()+@"\cert.pfx");

            // Add our .pfx file into the Personal Local Computer store:
            var store = new X509Store(StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadWrite);
            store.Add(cert);
            store.Close();

            // Finally, use netsh to assign this newly generated certificate to port 6613
            string s1 = "netsh http add sslcert ipport=0.0.0.0:6613 certhash=‎‎‎" + cert.GetCertHashString() + " appid={" + Guid.NewGuid().ToString() + "}";
            Process p1 = new Process();
            p1.StartInfo.FileName = "netsh.exe";
            p1.StartInfo.Arguments = s1;
            p1.StartInfo.UseShellExecute = false;
            p1.StartInfo.RedirectStandardOutput = true;

            //  this is where I get the error "SSL Certificate add failed, Error: 1312"
            p1.Start();
        }
    }
}

这是 netsh 命令,只要我不在这个 C# 程序中执行它,它就可以正常工作:

netsh http 添加 sslcert ipport=0.0.0.0:6613 certash=‎‎‎‎8834efd403687b331363ce9e5657ba4ffba0075b appid={e604f84f-e666-4ccf-af52-fdeca666b5e9}

令人困惑的部分

因此,如果您openssl要从该线程逐字执行我的命令,而不是将.pfxopenssl 生成的文件导入 IIS 并最终使用netssh如上所示的带有正确证书哈希的命令,那么整个事情就可以完美运行。但是当你在上面的 C# 代码中自动执行我刚才所说的操作时,我得到了错误。

另一件事是,当您尝试netsh通过命令行手动操作时,生成的 .pfx 将不会从该代码导入到商店中。

有没有人有任何想法?

4

1 回答 1

4

如果使用 C#,在存储之前尝试将 pfx 显式包含到证书中

    var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
            store.Open(OpenFlags.ReadWrite);
    //ensure pfx in cert.
    byte[] pfx = cert.Export(X509ContentType.Pfx);
    cert = new X509Certificate2(pfx, (string)null, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

    //then store
    store.Add(cert);
    store.Close();
于 2017-03-12T04:54:21.733 回答