简体   繁体   English

如何使用Compact Framework在C#中验证X.509证书

[英]How to validate X.509 Certificate in C# using Compact Framework

I am trying to validate an X.509 certificate using C# and .NetCF. 我正在尝试使用C#和.NetCF验证X.509证书。 I have the CA certificate, and if I understand correctly, I need to use the public key from this CA certificate to decrypt the signature of the untrusted certificate. 我有CA证书,如果我理解正确,我需要使用此CA证书中的公钥来解密不受信任证书的签名。 This should give me the computed hash value of the untrusted certificate. 这应该给我不受信任证书的计算哈希值。 I should then compute the hash of the certificate myself and make sure the two values match. 然后我应该自己计算证书的哈希值,并确保两个值匹配。

I've been playing with this for a few days and I'm not getting very far. 我已经玩了几天了,我没有走得太远。 I've been using the X509Certificate and RSACryptoServiceProvider classes. 我一直在使用X509Certificate和RSACryptoServiceProvider类。 First, I tried to get the public key and signature out of the X509Certificate class. 首先,我尝试从X509Certificate类中获取公钥和签名。 I was able to get the public key but not the signature. 我能够获得公钥而不是签名。 Next, I tried parsing the binary data that made up the certificate, which allowed me to get the signature (and any other data I wanted), but I was unable to decrypt the signature using the RSACryptoServiceProvider. 接下来,我尝试解析构成证书的二进制数据,这允许我获取签名(以及我想要的任何其他数据),但我无法使用RSACryptoServiceProvider解密签名。 I tried things like this but kept getting exceptions saying "Bad Key" when I tried to decrypt: 我试过这样的事情,但在我试图解密的时候不断得到说“Bad Key”的异常:

RSAParameters rsaParams = new RSAParameters();
rsaParams.Exponent = exp;
rsaParams.Modulus = mod;
RSACryptoServiceProvider rsaServ = new RSACryptoServiceProvider();
rsaServ.ImportParameters(rsaParams);
byte[] decryptedSig = rsaServ.Decrypt(encryptedSig, false);

Any advice would be greatly appreciated. 任何建议将不胜感激。

Edit: I tried something that seems to be better but is returning a strange result. 编辑:我尝试了似乎更好的东西,但返回了一个奇怪的结果。 I'm working with the X509Certificate2 class here because it's a little easier for testing, but I will need to switch to X509Certificate for .NetCF later. 我在这里使用X509Certificate2类,因为它更容易进行测试,但我需要稍后切换到.NetCF的X509Certificate。 I think that RSACryptoServiceProvider.VerifyData might be what I need. 我认为RSACryptoServiceProvider.VerifyData可能就是我所需要的。 I tried the following code. 我尝试了以下代码。

X509Certificate2 cert = new X509Certificate2(certBytes);
X509Certificate2 certCA1 = new X509Certificate2(@"C:\certs\certCA1.cer");

byte[] encryptedSig = new byte[256];
Array.Copy(certBytes, certBytes.Length - 256, encryptedSig, 0, 256);

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)certA1.PublicKey.Key;
bool good = rsa.VerifyData(cert.RawData, "1.3.14.3.2.26", encryptedSig);

As I said, I am able to manually decode and interpret the binary data of the certificate, so I'm pretty sure the cert.RawData is the certificate's signed data and the last 256 bytes are the encrypted signature. 正如我所说,我能够手动解码和解释证书的二进制数据,所以我很确定cert.RawData是证书的签名数据,最后256个字节是加密签名。 The string is the OID of the hash algorithm, which I got from certificate, but I'm not 100% sure that it's correct. 字符串是我从证书中获得的哈希算法的OID,但我不是100%确定它是正确的。 VerifyData returns false, but I'm not sure why yet. VerifyData返回false,但我不确定为什么。

Thoughts? 思考?

Here is my code. 这是我的代码。

RSACryptoServiceProvider rsa = signingCertificate_GetPublicKey();
return rsa.VerifyData( SignedValue(), CryptoConfig.MapNameToOID( "SHA1" ), Signature() );

RSACryptoServiceProvider signingCertificate_GetPublicKey()
{
    RSACryptoServiceProvider publicKey = new RSACryptoServiceProvider();

    RSAParameters publicKeyParams = new RSAParameters();
    publicKeyParams.Modulus = GetPublicKeyModulus();
    publicKeyParams.Exponent = GetPublicKeyExponent();

    publicKey.ImportParameters( publicKeyParams );

    return publicKey;
}

byte[] GetPublicKeyExponent()
{
    // The value of the second TLV in your Public Key
}

byte[] GetPublicKeyModulus()
{
    // The value of the first TLV in your Public Key
}

byte[] SignedValue()
{
    // The first TLV in your Ceritificate
}

byte[] Signature()
{
    // The value of the third TLV in your Certificate
}

I hope that helps anyone who is working on this problem. 我希望这有助于解决这个问题的任何人。

Does WinCE support something compatible with the Win32 MSCrypto.dll? WinCE是否支持与Win32 MSCrypto.dll兼容的东西? If yes, take a look at the .NET X509Certificate2 class and also the CLR Security library on Codeplex. 如果是,请查看.NET X509Certificate2类以及Codeplex上CLR安全库。 It contains a lot of helpful routines for .NET that sit on top of the core OS crypto library. 它包含许多有用的.NET例程,它们位于核心操作系统加密库之上。 You can download the source and see how it compiles for .NetCF 您可以下载源代码并查看它如何为.NetCF编译

To load and validate an X509 certificate, do something like this (untested): 要加载和验证X509证书,请执行以下操作(未经测试):

var cert = new X509Certificate2("mycert.cer");  
if (!cert.Verify())
{
    <fail>
}

There are nearly a dozen constructors for X509Certificate2 to construct from a wide variety of sources - file on disk, byte array in memory, load from local cert store, etc. X509Certificate2有近十二个构造函数可以从各种来源构建 - 磁盘上的文件,内存中的字节数组,本地证书存储区的加载等。

The root CA used to sign the certificate will need to be installed in the local cert store. 用于签署证书的根CA需要安装在本地证书库中。 If the certificate does not include the intermediate CAs in the trust chain, those intermediates will need to be on the local machine too, all the way up to a root CA that is in the trusted cert store in the local machine. 如果证书不包含信任链中的中间CA,则这些中间人也需要位于本地计算机上,一直到本地计算机中受信任证书存储中的根CA。

Unfortunately, I can't tell from the MSDN docs whether X509Certificate2 is available on .NetCF. 不幸的是,我无法从MSDN文档中看出X509Certificate2是否可用于.NetCF。

It works for me in win32, but in Compact Framework I'm facing the same problem, there is no X509Certificate2 so I'm actually blocked, with win32 we can do: 它在win32中适用于我,但在Compact Framework中我面临同样的问题,没有X509Certificate2所以我实际上已被阻止,我们可以使用win32:

X509Certificate2 l__PublicKeyCertificate = new X509Certificate2("cert.cer");

RSACryptoServiceProvider l__rsaCspPublic = (RSACryptoServiceProvider)l__PublicKeyCertificate .PublicKey.Key;

//...

l__isVerified = l__rsaCspPublic.VerifyData(l__fileData, CryptoConfig.MapNameToOID("SHA1"), l__fileSignature);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM