Как проверить сертификат X.509 в C # с помощью Compact Framework - PullRequest
7 голосов
/ 02 сентября 2010

Я пытаюсь проверить сертификат X.509, используя C # и .NetCF. У меня есть сертификат 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);

Любой совет будет принят с благодарностью.

Edit: Я попробовал что-то, что кажется лучше, но возвращает странный результат. Я работаю с классом X509Certificate2 здесь, потому что его немного легче тестировать, но позже мне нужно будет переключиться на X509Certificate для .NetCF. Я думаю, что RSACryptoServiceProvider.VerifyData может быть то, что мне нужно. Я попробовал следующий код.

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

Как я уже сказал, я могу вручную декодировать и интерпретировать двоичные данные сертификата, поэтому я почти уверен, что cert.RawData - это подписанные данные сертификата, а последние 256 байтов - зашифрованная подпись. Строка - это OID алгоритма хеширования, который я получил из сертификата, но я не уверен на 100%, что это правильно. VerifyData возвращает false, но я пока не уверен, почему.

Мысли?

Ответы [ 3 ]

3 голосов
/ 13 декабря 2010

Вот мой код.

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
}

Надеюсь, это поможет любому, кто работает над этой проблемой.

1 голос
/ 02 сентября 2010

Поддерживает ли WinCE что-то совместимое с Win32 MSCrypto.dll?Если да, взгляните на класс .NET X509Certificate2 , а также на библиотеку CLR Security в Codeplex. Она содержит множество полезных подпрограмм для .NET, которые располагаются поверх ядра.Криптотека ОС.Вы можете скачать исходный код и посмотреть, как он компилируется для .NetCF

Чтобы загрузить и проверить сертификат X509, сделайте что-то вроде этого (не проверено):

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

Существует почти дюжина конструкторовдля X509Certificate2 для создания из самых разных источников - файла на диске, байтового массива в памяти, загрузки из локального хранилища сертификатов и т. д.

Корневой ЦС, используемый для подписи сертификата, должен быть установлен в локальномСертифицированный магазин.Если сертификат не включает промежуточные CA в цепочке доверия, эти промежуточные устройства также должны находиться на локальном компьютере, вплоть до корневого CA, который находится в хранилище доверенных сертификатов на локальном компьютере.

К сожалению, я не могу сказать из документов MSDN, доступен ли сертификат X509Certificate2 в .NetCF.

0 голосов
/ 10 декабря 2010

У меня работает в 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);
...