【问题标题】:C# - Export .pfx certificate and import it later as a fileC# - 导出 .pfx 证书并稍后将其作为文件导入
【发布时间】:2017-06-03 06:08:59
【问题描述】:

我基本上需要将.pfx 证书导出为Base64string,将其存储在数据库中并稍后恢复,从Base64string 转换。 我目前使用的是X509Certificate2 类,如下所示:

转换它并将 cert64 字符串存储在数据库中:

X509Certificate2 pfx = new X509Certificate2(@"C:\originalcert.pfx", "password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.UserKeySet);

string cert64 = Convert.ToBase64String(pfx.RawData);

稍后从 DB 中获取(我需要将其存储为 Base64 字符串):

X509Certificate2 cert = new X509Certificate2();
cert.Import(Convert.FromBase64String(string64cert), "password", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.UserKeySet);

File.WriteAllBytes(@"C:\copycert.pfx", cert.Export(X509ContentType.Pfx, "password"));

当我使用以下方法比较 C:\originalcert.pfxC:\copycert.pfx 时,它返回 true:

X509Certificate2.Equals

对于我正在运行的需要证书才能正常工作的应用程序,我有时会收到一些错误,因为提供给我的一些不同的 .pfx 证书用于解决导入/安装到机器并通过 Web 导出它的问题浏览器,创建一个新的.pfx 文件,然后瞧。

使用copycert.pfx 文件给我同样的错误,但是当我尝试通过文件安装copycert.pfx 或使用网络浏览器导入它时,我得到:“导入成功”消息,但找不到在“个人”选项卡下安装证书,就像我安装原始 originalcert.pfx 一样。

另外,我从.pfx 文件导出并稍后将其导入.pfx 文件也很重要。

我做错了什么/在代码导出/导入中缺少什么?

【问题讨论】:

    标签: c# certificate x509certificate2


    【解决方案1】:

    您的解决方案永远不会以您描述的方式起作用。原因如下:

    string cert64 = Convert.ToBase64String(pfx.RawData);

    此行仅转换证书的 public 部分。没有私钥信息存储在RawData 属性中。这意味着您无法从此字符串恢复原始 PFX。您真正应该做的是读取文件的内容并将其转换为 Base64 字符串,而无需触及 X509Certificate2 类。用这两行替换发布的前两行代码:

    Byte[] rawCert = File.ReadAllBytes(@"C:\originalcert.pfx");
    String cert64 = Convert.ToBase64String(bytes);
    

    PFX 证书仅支持纯二进制编码(即 PFX 不能以 PEM 格式存储),因此只需读取原始字节并进行转换即可。

    var cert = new X509Certificate2();
    cert.Import(Convert.FromBase64String(string64cert), "password", 
        X509KeyStorageFlags.Exportable | 
        X509KeyStorageFlags.PersistKeySet | 
        X509KeyStorageFlags.UserKeySet);
    

    此命令仅将证书导入X509Certificate2 对象并将私钥安装到 PFX 中指定的 CSP(如果 PFX 中没有存储提供者信息,则安装到默认 CSP)。要将其安装到个人商店,您需要这样做:

    var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
    store.Open(OpenFlags.ReadWrite);
    store.Certificates.Add(cert);
    store.Close();
    

    从 .NET 4.6 开始,X509Store 实现了IDisposable,所以你应该使用using 子句来处理对象:

    using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser)) {
        store.Open(OpenFlags.ReadWrite);
        store.Add(cert);
    }
    

    注意上面的代码只需要安装证书到证书存储。要将其从数据库恢复为 PFX 文件,只需将二进制数据保存到文件中即可:

    Byte[] rawCert = Convert.FromBase64String(string64cert);
    File.WriteAllBytes(@"C:\copycert.pfx");
    

    总结

    只是总结所有写的。要将 PFX 转换为 Base64 字符串:

    Byte[] rawCert = File.ReadAllBytes(@"C:\originalcert.pfx");
    String cert64 = Convert.ToBase64String(bytes);
    

    从 Base64 字符串恢复 PFX 并保存到文件:

    Byte[] rawCert = Convert.FromBase64String(string64cert);
    File.WriteAllBytes(@"C:\copycert.pfx");
    

    【讨论】:

    • 谢谢!我已经在这样做来存储 xml 文件,我不知道为什么,但前段时间我尝试这样做,但对我来说没有用,并且认为证书没有以像这样简单的方式工作我正在处理我的 xml 文件。
    • 这仅适用于 Windows 和 .NET Framework 吗?还是 Linux 上的 .NET 5+ 也一样?
    • 这适用于 Linux 上的 .NET Core 和 .NET 5+。代码 sn-ps 与平台无关。
    猜你喜欢
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2010-11-13
    • 2019-01-02
    • 2022-01-01
    • 2017-02-03
    • 1970-01-01
    • 2014-10-21
    相关资源
    最近更新 更多