我正在尝试以编程方式将证书及其私钥导出到 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/
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我有一个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";我尝试了所有不同的路径格式,但它
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务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
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
当谈到运行时自省(introspection)和动态代码生成时,我认为ruby没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
我有一个.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
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.