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

我正在尝试使用C#和.NetCF来验证X.509证书。 我有CA证书,如果我理解正确,我需要使用此CA证书中的公钥来解密不可信证书的签名。 这应该给我不可信证书的计算哈希值。 然后我应该自己计算证书的散列值,并确保两个值匹配。

我一直在玩这个几天,而且我没有走得很远。 我一直在使用X509Certificate和RSACryptoServiceProvider类。 首先,我试图从X509Certificate类中获取公钥和签名。 我能够获得公钥,但没有签名。 接下来,我尝试解析构成证书的二进制数据,这使得我可以获得签名(以及我想要的任何其他数据),但是我无法使用RSACryptoServiceProvider解密签名。 我尝试过这样的事情,但当我试图解密时,不断收到异常说“坏钥匙”:

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

任何建议将不胜感激。

编辑:我尝试了一些似乎更好,但返回一个奇怪的结果。 我在这里使用X509Certificate2类,因为它测试起来更容易一些,但是稍后我需要为.NetCF切换到X509Certificate。 我认为RSACryptoServiceProvider.VerifyData可能是我需要的。 我试了下面的代码。

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);

正如我所说的,我能够手动解码和解释证书的二进制数据,所以我非常肯定cert.RawData是证书的签名数据,最后256个字节是加密签名。 字符串是散列算法的OID,我从证书中获得,但我不能100%确定它是正确的。 VerifyData返回false,但我不确定为什么。

思考?


这是我的代码。

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
}

我希望能帮助任何正在解决这个问题的人。


WinCE是否支持与Win32 MSCrypto.dll兼容的东西? 如果是,请查看.NET X509Certificate2类以及Codeplex上的CLR安全库。 它包含了许多有用的.NET例程,它们位于核心操作系统加密库之上。 您可以下载源代码并查看它如何编译.NetCF

要加载和验证X509证书,请执行以下操作(未经测试):

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

X509Certificate2有几十种构造函数可以从各种各样的源代码构建 - 磁盘上的文件,内存中的字节数组,从本地证书存储区加载等等。

用于签署证书的根CA将需要安装在本地证书存储区中。 如果证书不包含信任链中的中间CA,则这些中间件也需要位于本地计算机上,一直到位于本地计算机中可信任证书存储区中的根CA。

不幸的是,我无法从MSDN文档中知道X509Certificate2是否可用于.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/47765.html

上一篇: How to validate X.509 Certificate in C# using Compact Framework

下一篇: Projecting a texture in OpenGL