【问题标题】:SSL Certificate add failed, Error: 1312SSL 证书添加失败,错误:1312
【发布时间】:2015-12-08 14:23:45
【问题描述】:

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

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

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

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

到目前为止,我的部分 [1.][2.] 工作正常,但在 [3.] 我' m 被无用和非正式的错误信息所困扰:

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 命令,则将 openssl 生成的 .pfx 文件导入 IIS,最后使用上面所示的 netssh 命令和正确的证书哈希,而不是这样整个事情完美无缺。但是当你在上面的 C# 代码中自动执行我刚才所说的操作时,我得到了错误。

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

有人有什么想法吗?

【问题讨论】:

  • 您不需要在代码中运行 netsh,因为 PInvoking HTTP API 更容易。

标签: c# iis openssl http.sys


【解决方案1】:

如果使用 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();

【讨论】:

  • 这个解决方案确实对我有用 :) 拯救了我的一天。谢谢。 X509Certificate2 的第二个参数是“密码”。
猜你喜欢
  • 2019-09-08
  • 2015-06-05
  • 2015-11-19
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 2019-12-06
  • 2018-03-16
相关资源
最近更新 更多