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

I am trying to validate an X.509 certificate using C# and .NetCF. 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. 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. First, I tried to get the public key and signature out of the X509Certificate class. 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. I tried things like this but kept getting exceptions saying "Bad Key" when I tried to decrypt:

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. I think that RSACryptoServiceProvider.VerifyData might be what I need. I tried the following code.

X509Certificate2 cert = new X509Certificate2(certBytes);
X509Certificate2 certCA1 = new X509Certificate2(@"C:certscertCA1.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. The string is the OID of the hash algorithm, which I got from certificate, but I'm not 100% sure that it's correct. VerifyData returns false, but I'm not sure why yet.

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? If yes, take a look at the .NET X509Certificate2 class and also the CLR Security library on Codeplex. It contains a lot of helpful routines for .NET that sit on top of the core OS crypto library. You can download the source and see how it compiles for .NetCF

To load and validate an X509 certificate, do something like this (untested):

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.

The root CA used to sign the certificate will need to be installed in the local cert store. 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.

Unfortunately, I can't tell from the MSDN docs whether X509Certificate2 is available on .NetCF.


它在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);
链接地址: http://www.djcxy.com/p/47766.html

上一篇: 如何在所有现代浏览器中检测页面缩放级别?

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