2009-08-19 9 views
6

Obecnie otrzymuję następujący błąd przy użyciu języka Java do odszyfrowania Base64 zakodowane RSA zaszyfrowany ciąg znaków, który został wykonany w C#:Wypełnienie błąd podczas korzystania z szyfrowania RSA w C# i odszyfrowywania w Javie

javax.crypto.BadPaddingException : Nie PKCS # 1 blok typu 2 lub Zero wyściółka

proces konfiguracji między wymiany z .NET i Java odbywa się poprzez utworzenie klucza prywatnego w magazynie kluczy .NET następnie z pliku PEM wydobyte, utworzonego użytku keytool do tworzenia wersji JKS z kluczem prywatnym. Java ładuje już utworzony JKS i dekoduje ciąg Base64 do tablicy bajtów, a następnie używa klucza prywatnego do odszyfrowania.

Oto kod, który mam w C#, który tworzy zaszyfrowany ciąg:

public string Encrypt(string value) { 
    byte[] baIn = null; 
    byte[] baRet = null; 
    string keyContainerName = "test"; 

    CspParameters cp = new CspParameters(); 
    cp.Flags = CspProviderFlags.UseMachineKeyStore; 
    cp.KeyContainerName = keyContainerName; 
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp); 

    // Convert the input string to a byte array 
    baIn = UnicodeEncoding.Unicode.GetBytes(value); 

    // Encrypt 
    baRet = rsa.Encrypt(baIn, false); 

    // Convert the encrypted byte array to a base64 string 
    return Convert.ToBase64String(baRet); 
} 

Oto kod, który mam w Javie, który odszyfrowuje wprowadzoną ciąg:

public void decrypt(String base64String) { 
    String keyStorePath = "C:\Key.keystore"; 
    String storepass = "1234"; 
    String keypass = "abcd"; 
    byte[] data = Base64.decode(base64String); 
    byte[] cipherData = null; 

    keystore = KeyStore.getInstance("JKS"); 
    keystore.load(new FileInputStream(keyStorePath), storepass.toCharArray()); 

    RSAPrivateKey privateRSAKey = (RSAPrivateKey) keystore.getKey(alias, keypass.toCharArray()); 

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
    cipher.init(Cipher.DECRYPT_MODE, privateRSAKey); 
    cipherData = cipher.doFinal(data); 

    System.out.println(new String(cipherData)); 
} 

Czy ktoś widzisz brakujący krok lub gdzie należy zmienić dopełnienie lub element? Przez wiele godzin czytałem na tej stronie i innych, ale tak naprawdę nie znalazłem konkretnego rozwiązania.

Twoja pomoc jest ogromnie doceniana.

Dzięki. -Matt

+0

Gdzie jest dopełnienie określone w kodzie C#? Skąd wiadomo, że OAEP (który jest PKCS # 1 wer. 2) nie jest używany podczas szyfrowania? – erickson

+1

Najpierw wyizoluj szyfrowanie i kodowanie na osobne probelmy. To znaczy. sprawdź, czy zdekodowany bajt Java [] jest identyczny z oryginalnym bajtem C# []. wtedy możesz zapytać, czy jest to problem RSA, czy problem Base64. Jak powiedział erickson, prawdopodobnie jest różnica w domyślnym PKCS między bibliotekami C# i Java. –

+0

@erickson - drugi parametr metody .NET Encrypt() wybiera padding - true określa OAEP, a false (użyte w przykładzie) określa PKCS # 1 ver 1.5. –

Odpowiedz

2

Sprawdź, czy poprawnie wymieniłeś klucz.

Próba odszyfrowania za pomocą niepoprawnego klucza jest nieodróżnialna od odszyfrowania źle wypełnionych danych.

0

Domyślam się, że wersja C# emituje bajty w małym formacie endian, a wersja Java importuje bajty oczekujące, że będą w formacie big endian. Spróbuj zamienić bajty w baRet od końca do końca, zanim skonwertujesz je do bazy 64 i sprawdź, czy twój program Java może je odszyfrować.

Tylko zgadnij.

2

pracuję przez podobny problem działającej między .NET i iPhone rzeczy w celu - C, i myślę, że odpowiedź leży w tym mały klejnot z dokumentacją RSACryptoServiceProvider:

przeciwieństwie realizacji RSA w niekontrolowana CAPI , klasa RSACryptoServiceProvider odwraca kolejność zaszyfrowanych tablic bajtów po zaszyfrowaniu i przed odszyfrowaniem. Domyślnie dane zaszyfrowane przez klasę RSACryptoServiceProvider nie mogą zostać odszyfrowane przez funkcję CAPI CryptDecrypt, a dane zaszyfrowane za pomocą metody CAPI CryptEncrypt nie mogą zostać odszyfrowane przez klasę RSACryptoServiceProvider.

Zobacz tutaj po więcej szczegółów: http://msdn.microsoft.com/en-us/library/s575f7e2(v=VS.90).aspx

4

exactely miałem ten sam problem, a ja w końcu znaleźć rozwiązanie!

Byłem uparty przy użyciu PKCS1Padding, ale nie udało mi się go uruchomić.

Najlepszy wynik mam użyciem "rsa.Encrypt (Bain, fałszywe)" po stronie C# i "RSA/brak/NoPadding" na stronie Java była tego rodzaju wyrażenie: „☻ O? + _> ?? 5? L0Q * ??? *? R ▲ ??? ♀7 ... ", a następnie mój odszyfrowany ciąg.W pewnym sensie został odszyfrowany, ale ponieważ nie ma określonego dopełnienia, dane są przesunięte. Tak więc wypróbowałem wszystkie podkładki dostępne w bouncycastle, ale zawsze otrzymywałbym błędy takie jak "zablokuj nieprawidłowy rozmiar" lub "dane hash źle".

Więc postanowiłem rozpocząć próby OAEP Uszczelki i udało mi się go uruchomić za pomocą "rsa.Encrypt (Bain, true)" po stronie C# i "RSA/brak/OAEPWithSHA1AndMGF1Padding" w sprawie strona java!

To zadziałało dla mnie, mam nadzieję, że zadziała również dla Ciebie! Jeśli to nie zadziała, upewnij się, że używasz właściwego klucza, bardzo często problem pochodzi z klucza.

+0

To położyło kres dwudniowemu bólowi !. Wielkie dzięki. –

0

Miałem ten sam problem podczas korzystania z Bouncy Castle 1.48, ale nie było to związane z kluczem. Zamiast tego stwierdziłem, że muszę ustawić następującą właściwość systemową:

-Dorg.bouncycastle.pkcs1.strict=false 
Powiązane problemy