我有一个用于测试目的的pfx文件,没有特殊的安全性。
我需要使用此文件来加密XML文件。方案是,我需要将密码邮编文件以及与邮编有关的元数据文件发送给客户端。该Zip实际上将包含用于更新软件安装的文件。起初,我虽然会加密Zip本身。但是,随后决定使用一个简单的密码对其进行保护,并将其上传到客户端的网站(ASP.NET)。客户端还将上载将与压缩更新一起提供的元数据文件。此元数据文件将包含诸如客户端标识符,MAC地址,更新zip文件的MD5哈希等内容。...在客户端上载ZIP和Meta后,发送和解密之前,我需要先加密此元数据文件。解密后,我将尝试验证客户端,当前安装以及补丁本身。
PFX是为我生成的。
我需要从PFX中提取什么
我可以在这里使用BouncyCastle。
这样的想法是,一旦客户端在终端安装了软件,便会生成X509证书请求。这将创建两件事:请求和私钥。客户将保留私钥并将请求发送给我们。我们将验证客户(付款和全部),并为其生成证书并通过电子邮件将其发送回(PFX)。然后,他将其导入以解锁软件上的功能,并能够获取压缩更新和更多内容
问题有点像是完整的解决方案需求,但是我要面对真正的困难,那就是与X509签名。我正在看BouncyCastle文档。
感谢您的阅读。任何帮助将不胜感激。
最佳答案
抱歉,答案很长。
是的,您可以使用Bouncycastle从pfx中提取证书。
var pkcs = new Pkcs12Store(File.Open("path.pfx", FileMode.Open), "password".ToCharArray());
pkcs.Aliases // is a list of certificate names that are in the pfx;
pkcs.GetCertificate(alias); // gets a certificate from the pfx
我们使用了一种非常相似的方法,但是我们将没有私钥的证书发送回PEM,因为它不包含任何“秘密”
这是您发出证书签名请求的方式:
//generate a privatekey and public key
RsaKeyPairGenerator rkpg1 = new RsaKeyPairGenerator();
rkpg1.Init(new KeyGenerationParameters(new SecureRandom(), Keystrength));
AsymmetricCipherKeyPair ackp1 = rkpg1.GenerateKeyPair();
RsaPrivateCrtKeyParameters privateKey = (RsaPrivateCrtKeyParameters)ackp1.Private;
RsaKeyParameters publicKey = (RsaKeyParameters)ackp1.Public;
X509Name comonname = new X509Name (cname);
Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest ("SHA1WITHRSA", comonname, publicKey, null, privateKey);
csr.Verify ();
StringBuilder sb = new StringBuilder();
PemWriter pw = new PemWriter (new StringWriter (sb));
pw.WriteObject (csr);
pw.Writer.Flush ();
var pemstring = sb.ToString ();
这是在服务器端对证书签名请求进行签名时发生的情况:
据我了解,根证书可以是您拥有私钥的任何证书。如果要在其他应用程序(例如浏览器)中使用它,则需要将其插入名为“受信任的根证书颁发机构”(如果是自签名证书)的证书存储,如果需要,则需要将其插入“受信任的中间证书颁发机构”如果没有pirvate密钥,则不能在客户端计算机上自签名。
带有私钥的证书可以通过添加到图标的小钥匙来识别(请参见此处)。
//rootCert contains the rootcertificate in bouncycastle format
var pemstring = "a string containing the PEM";
PemReader pr = new PemReader (new StringReader (pemstring));
Pkcs10CertificationRequest csr = (Pkcs10CertificationRequest)pr.ReadObject ();
X509V3CertificateGenerator certgen = new X509V3CertificateGenerator();
certgen.SetSubjectDN(csr.GetCertificationRequestInfo().Subject);
certgen.SetIssuerDN(rootCert.SubjectDN);
certgen.SetPublicKey(csr.GetPublicKey());
certgen.SetSignatureAlgorithm(csr.SignatureAlgorithm.ObjectID.Id);
certgen.SetNotAfter(validThrough); //a datetime object
certgen.SetNotBefore(validFrom); //a datetime object
certgen.SetSerialNumber(serialNumber); //a biginteger
X509Certificate clientcert = certgen.Generate(rootPrivateKey);
//to send the certificate without the private key to the client you'll have to
//convert it to PEM:
StringBuilder sb = new StringBuilder();
PemWriter pw = new PemWriter (new StringWriter (sb));
pw.WriteObject (clientcert);
pw.Writer.Flush ();
var pemstring = sb.ToString ();
//to make it a .net certificate use:
X509Certificate2 netcert = DotNetUtilities.ToX509Certificate (clientcert);
客户端证书不包含私钥atm。这就是在客户端再次发生的情况,如下所示:
//where pemstring contains the certificate in a PEMstring like shown above.
//and privateKey is the one we had in the first part over at the client.
PemReader pr = new PemReader(new StringReader(pemstring));
X509Certificate2 cert = DotNetUtilities.ToX509Certificate((Bouncy.X509Certificate)pr.ReadObject());
CspParameters cparms = new CspParameters
{
CryptoKeySecurity = new CryptoKeySecurity(),
Flags = CspProviderFlags.UseMachineKeyStore
};
RSACryptoServiceProvider rcsp = new RSACryptoServiceProvider(cparms);
RSAParameters parms = new RSAParameters
{
Modulus = privateKey.Modulus.ToByteArrayUnsigned (),
P = privateKey.P.ToByteArrayUnsigned (),
Q = privateKey.Q.ToByteArrayUnsigned (),
DP = privateKey.DP.ToByteArrayUnsigned (),
DQ = privateKey.DQ.ToByteArrayUnsigned (),
InverseQ = privateKey.QInv.ToByteArrayUnsigned (),
D = privateKey.Exponent.ToByteArrayUnsigned (),
Exponent = privateKey.PublicExponent.ToByteArrayUnsigned ()
};
rcsp.ImportParameters(parms);
netcert.PrivateKey = rcsp;
关于c# - 使用PFX文件X509进行加密/解密,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11428182/