2011-02-07 28 views
8

Próbuję przenieść do systemu Windows strukturę AquaticPrime.CryptoAPI: Używanie CryptVerifySignature do sprawdzania podpisu z openssl za pomocą klucza publicznego

Na Macu używa biblioteki opensll i próbuję zrozumieć, jak przenieść to do Windowsa, gdzie, jak sądzę, muszę używać CryptoAPI.

Potrzebuję głównie kodu do sprawdzania poprawności wygenerowanego podpisu z podanym kluczem publicznym.

Oto jak weryfikacja odbywa się z OpenSSL:

  1. wejścia: dane licencyjne, klucza publicznego i podpis, zarówno 128 bajtów.
  2. Skrócona treść SHA1 jest obliczana na podstawie danych licencji.
  3. Kontekst RSA jest skonfigurowany z danymi klucza publicznego
  4. Wywoływana jest funkcja RSA_public_decrypt(), biorąc pod uwagę klucz RSA i podpis, który zwraca 20-bajtowy skrót SHA1 - czy to podsumowanie jest równe temu z kroku 2, podpis jest ważny.

Jak to zrobić z CryptoAPI? I dotarłeś tak daleko:

  1. Uruchom z CryptAcquireContext (CTX, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
  2. Korzystanie CryptImportKey z pomocą this oddelegowania, z pubexp = 3 i bitlen = 1024. To wszystko działa, tj. Nie dostaję błędów, a ja spojrzałem na dane binarne, aby sprawdzić, czy pasuje do tego, co pokazuje artykuł MSDN.
  3. Utwórz wyciąg SHA1 z danych licencji. Pobrałem wynikową wartość mieszania 20 bajtów i widzę, że pasuje do tego, co otrzymuję z openssl na Macu.

W tym momencie, wzywam:

CryptVerifySignature (hashHdl, sig, sigLen, keyHdl, 0, 0) 

To nie z kodem błędu ERROR_INVALID_PARAMETER.

Dziwne jest to, że gdy po raz pierwszy przypadkowo zapisałem dwa razy większy klucz publiczny w strukturze PUBLICKEYBLOB, otrzymałem błąd NTE_BAD_SIGNATURE. Może to sugerować, że klucz publiczny, który teraz przekazuję, jest poprawny.

Dlaczego teraz wystąpił błąd ERROR_INVALID_PARAMETER? Zweryfikowałem, że wartość skrótu jest poprawna, a klucz wydaje się również akceptowany. Parametr "sig" jest po prostu wskaźnikiem do 128 bajtów podpisu, a sigLen to 128.

Czego tu mi brakuje?

+1

Pytanie: Dlaczego po prostu nie skorzystasz z wersji OpenSSL z [Windows port] (http://www.slproweb.com/products/Win32OpenSSL.html)?Chodzi mi o to, że nie ma nic złego w korzystaniu z CryptoAPI, ale openSSL już istnieje i oznaczałoby to mniej pracy ... – erloewe

+0

Nie chcę, aby ludzie instalowali nowe składniki systemu tylko po to, aby uruchomić aplikację, która nie wymaga instalatora w inny sposób. –

Odpowiedz

9

OK, rozwiązałem problem po wielu próbach i błędach.

Zarówno dane podpisu, jak i klucza publicznego, w postaci ciągu bajtowego, muszą być odwrócone, tj. Pierwszy bajt na ostatnią pozycję i tak dalej. Następnie powyższe działa.

+1

Myślę, że mam podobny problem, jak się dowiedziałeś, że dane dotyczące podpisu i klucza publicznego muszą zostać odwrócone? –

+0

Got to !, wyjście funkcji podpisywania i szyfrowania CryptoAPI jest w małym formacie endian! –

+0

Cieszę się, że możesz zweryfikować moje wyniki. Wtedy mój post tutaj nie był na darmo :) –

-3

Skompiluj i połącz statycznie bibliotekę OpenSSL libCrypto. Można to zrobić, widziałem to u byłego pracodawcy.