草庐IT

c# - 在 c# 中导出到 p12 之前将私钥添加到 X509 证书

coder 2024-01-23 原文

我正在尝试以编程方式将证书及其私钥导出到 p12,而无需先将其导入证书存储区。

我试图复制的流程如下:

  1. 在 Mac 上使用钥匙串(keychain)创建证书签名请求。
  2. 使用它为 iOS 应用程序创建配置证书 Apple 的门户网站。
  3. 然后我下载 Apple 拥有的新 .cer 文件 从我的 csr 生成。
  4. 通常您要做的是双击 .cer 然后它 将导入 KeyChain Access 并作为一部分出现 创建的原始私钥。
  5. 然后您可以右键单击新的证书条目并导出 这是一个 .p12。

我需要在 C# 中复制最后 2 个步骤。我有一个来自 Apple 的 .cer,我有公钥和私钥,我需要以某种方式应用私钥,以便当我以编程方式将其导出为 p12 时,它与我在上面手动执行的匹配。

我可以像这样导入 .cer:

 X509Certificate2 originalCert = new X509Certificate2(@"c:\temp\aps.cer");
 //then export it like so
 byte[] p12 = originalCert.Export(X509ContentType.Pkcs12, "password");

但是当我将它与我用 KeyChain 手动创建的那个进行比较时,它不匹配,即:

  byte[] p12Bytes = File.ReadAllBytes(@"c:\temp\manual.p12");
  string manual = Convert.ToBase64String(p12Bytes);
  string generated = Convert.ToBase64String(p12);
  Assert.IsTrue(manual == generated);//this fails

我对这一切如何运作的理解当然可能有问题:)

我曾尝试使用 BouncyCaSTLe 库来执行此操作,但以下代码对最后的输出没有任何作用。

Org.BouncyCastle.X509.X509Certificate cert = Org.BouncyCastle.Security.DotNetUtilities.FromX509Certificate(originalCert);
X509CertificateEntry[] chain = new X509CertificateEntry[1];
X509CertificateEntry entry = new X509CertificateEntry(cert);
        chain[0] = entry;

        AsymmetricKeyEntry keyPair;
        using (StreamReader reader = File.OpenText(@"c:\temp\EXPORTED PRIVATE KEY.p12"))
        {
            Pkcs12Store store = new Pkcs12Store(reader.BaseStream, "Password".ToCharArray());
            foreach (string n in store.Aliases)
            {
                if (store.IsKeyEntry(n))
                {
                    AsymmetricKeyEntry key = store.GetKey(n);

                    if (key.Key.IsPrivate)
                    {
                        keyPair = key;
                        pfx.SetKeyEntry("TEST CERT", key, chain);
                        break;
                    }
                }
            }
        }

谁能给我指出正确的方向?

编辑:我又进行了一项更改,看起来很有希望,因为键的长度现在几乎匹配了。我现在像这样通过 BouncyCaSTLe 导出 p12:

     using (MemoryStream stream = new MemoryStream())
        {
            pfx.Save(stream, "password".ToCharArray(), new SecureRandom());

            byte[] p12Bytes = File.ReadAllBytes(@"c:\temp\newexported.p12");
            string realp12 = Convert.ToBase64String(p12Bytes);

            using (BinaryReader reader = new BinaryReader(stream))
            {
                byte[] p12 = stream.ToArray();
                string generated12 = Convert.ToBase64String(p12);
                Assert.IsTrue(realp12.Length == generated12.Length);
            }
       }

它似乎使用随机生成的字节来执行操作(请参阅新的 SecuredRandom()),我现在很困惑如果它是随机的,解密是如何发生的?

谢谢。

最佳答案

首先感谢上面的bartonjs帮忙解决了这个问题。不同的长度让我以不同的方式思考这个问题。

我上面的编辑解决了它。我假设通过调用:

 pfx.SetKeyEntry("MyKey", key, chain);

它会将 key 设置到链中的证书中。相反,我不得不像这样导出它们:

using (MemoryStream stream = new MemoryStream())
{
     pfx.Save(stream, "Password".ToCharArray(), new SecureRandom());//The SecureRandom must be responsible for the different strings/lengths when re-generated.
     using (BinaryReader reader = new BinaryReader(stream))
     {
         byte[] p12 = stream.ToArray();
         //then I can save this off somewhere - in my case the db.
     }
}

现在我有一个附有证书和私钥的 p12,它可以与 Apple 的推送通知系统一起使用。

关于c# - 在 c# 中导出到 p12 之前将私钥添加到 X509 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38910581/

有关c# - 在 c# 中导出到 p12 之前将私钥添加到 X509 证书的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

  2. ruby - 将 Bootstrap Less 添加到 Sinatra - 2

    我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它

  3. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  6. ruby - 可以通过多少种方法将方法添加到 ruby​​ 对象? - 2

    当谈到运行时自省(introspection)和动态代码生成时,我认为ruby​​没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby​​的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  9. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  10. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

随机推荐