2010-09-02 12 views
7

Próbuję sprawdzić certyfikat X.509 przy użyciu C# i .NetCF. Mam certyfikat CA, a jeśli dobrze rozumiem, muszę użyć klucza publicznego z tego certyfikatu CA, aby odszyfrować podpis niezaufanego certyfikatu. To powinno dać mi obliczoną wartość mieszającą niezaufanego certyfikatu. Powinienem następnie obliczyć wartość mieszającą samego certyfikatu i upewnić się, że te dwie wartości są zgodne.Jak sprawdzić certyfikat X.509 w języku C# za pomocą Compact Framework

Bawiłem się tym przez kilka dni i nie zajmuję się daleko. Korzystam z klas X509Certificate i RSACryptoServiceProvider. Po pierwsze, próbowałem uzyskać klucz publiczny i podpis z klasy X509Certificate. Udało mi się zdobyć klucz publiczny, ale nie podpis. Następnie próbowałem analizować dane binarne składające się na certyfikat, co pozwoliło mi uzyskać podpis (i wszelkie inne dane, które chciałem), ale nie udało mi się odszyfrować podpisu za pomocą RSACryptoServiceProvider. Próbowałem rzeczy jak to, ale ciągle się wyjątki powiedzenie „Bad Key”, kiedy starałem się odszyfrować:

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

Wszelkie porady będą bardzo mile widziane.

Edytuj: Próbowałem czegoś, co wydaje się być lepsze, ale zwraca dziwny wynik. Pracuję z klasą X509Certificate2 tutaj, ponieważ jest nieco łatwiejsze do testowania, ale będę musiał przejść do certyfikatu X509Certyfikat dla .NetCF później. Myślę, że RSACryptoServiceProvider.VerifyData może być tym, czego potrzebuję. Próbowałem poniższy kod.

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

Jak powiedziałem, jestem w stanie ręcznie dekodować i interpretować dane binarne zaświadczenia, więc jestem dość pewny cert.RawData jest podpisane dane świadectwa i ostatnie 256 bajtów są szyfrowane podpis . Łańcuch jest identyfikatorem OID algorytmu mieszania, który otrzymałem z certyfikatu, ale nie jestem w 100% pewien, czy jest poprawny. VerifyData zwraca false, ale nie jestem jeszcze pewien, dlaczego.

Myśli?

Odpowiedz

3

Oto moja kod.

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 
} 

Mam nadzieję, że pomoże każdemu, kto pracuje nad tym problemem.

1

Czy program WinCE obsługuje coś kompatybilnego z Win32 MSCrypto.dll? Jeśli tak, spójrz na klasę .NET X509Certificate2, a także na CLR Security library on Codeplex. Zawiera wiele przydatnych podprogramów .NET, które znajdują się na rdzennej bibliotece kryptograficznej OS. Można pobrać źródła i zobaczyć jak to kompiluje dla .NetCF

Aby załadować i sprawdzić poprawność certyfikatu X509, zrobić coś takiego (niesprawdzone):

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

Istnieje prawie tuzin konstruktorów dla X509Certificate2 skonstruować z wielu różnych źródeł - plik na dysku, tablica bajtów w pamięci, obciążenie z lokalnego magazynu certyfikatów itp.

Główny urząd certyfikacji używany do podpisywania certyfikatu będzie musiał zostać zainstalowany w lokalnym magazynie certyfikatów. Jeśli certyfikat nie zawiera pośrednich urzędów certyfikacji w łańcuchu zaufania, te półprodukty również muszą znajdować się na komputerze lokalnym, aż do głównego urzędu certyfikacji znajdującego się w zaufanym magazynie certyfikatów na komputerze lokalnym.

Niestety, nie mogę stwierdzić z dokumentacji MSDN, czy X509Certificate2 jest dostępny na .NetCF.

+0

Ograniczenia WinCE mogą być trudne i jestem zupełnie nowy w X.509, więc próbowałem uruchomić to w normalnym środowisku Win32, a nawet nie jestem w stanie tego zrobić. Rzuciłem okiem na bibliotekę bezpieczeństwa CLR, na którą wskazałeś, ale nie widziałem niczego, co by potwierdzało certyfikat X509. Czy możesz dać mi trochę więcej, aby kontynuować? – Ben

+0

Zaktualizowałem odpowiedź za pomocą przykładowego kodu. – dthorpe

+0

Certyfikat X509Certyfikat2 nie jest dostępny w .NetCF, ale jest to pomocne. Dzięki. – Ben

0

To działa na mnie w win32, ale w Compact Framework Mam stoi ten sam problem, nie ma X509Certificate2 więc ja faktycznie zablokowane, z win32 możemy zrobić:

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

Wyobraziłem to jakiś czas temu i zapomniałem opublikować odpowiedź. Zajrzę do mojego kodu źródłowego i otrzymam odpowiedź wysłaną do poniedziałku. – Ben

Powiązane problemy