2013-03-14 12 views
5

Przyjmijmy, mam następujący kod Java, aby wygenerować parę kluczy publiczny-prywatny:szyfrowania RSA w Javie, odszyfrować w PHP

KeyPairGenerator generator = KeyPairGenerator.getInstance ("RSA"); 
SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 

generator.initialize (1024, random); 

KeyPair pair = generator.generateKeyPair(); 
RSAPrivateKey priv = (RSAPrivateKey)pair.getPrivate(); 
RSAPublicKey pub = (RSAPublicKey)pair.getPublic(); 

// Sign a message 
Signature dsa = Signature.getInstance("SHA1withRSA"); 
dsa.initSign (priv); 
dsa.update ("Hello, World".getBytes(), 0, "Hello, World".length()); 

byte[] out = dsa.sign(); 
/* save the signature in a file */ 
FileOutputStream sigfos = new FileOutputStream("sig"); 
sigfos.write(out); 
sigfos.close(); 

Jak można o i odszyfrować plik „sig” w PHP? Przeczytałem post: https://stackoverflow.com/a/1662887/414414, który dostarcza funkcję konwertowania pliku DER na PEM (Zakładam, że również zapiszę klucz publiczny z Java).

Próbowałem coś takiego:

$key = openssl_pkey_get_public ("file://pub_key.pem"); 
$data = null; 
openssl_public_decrypt (file_get_contents ("sig"), $data, $key); 
echo $data, "\n"; 

powodzeniem odszyfrowuje wiadomość, ale jest wiele dziwnych znaków.

Nasz scenariusz to klient Java, który wysyła wiadomości do serwera PHP, ale szyfruje dane za pomocą klucza prywatnego. PHP wie o kluczu publicznym, którego powinien użyć do odszyfrowania i sprawdzenia poprawności wiadomości.

Przeczytałem wiele postów dotyczących tego problemu tutaj na SO, ale zdałem sobie sprawę, że jest to nieco specyficzny problem, szczególnie jeśli używa się różnych algorytmów itp. Tak mi przykro, jeśli to może być duplikat.

Wszelkie opinie są bardzo mile widziane!

+2

"Pomyślnie odszyfrowuje wiadomość, ale ma wiele dziwnych postaci." - możesz o tym powiedzieć? Czy to może być problem z kodowaniem? –

+1

Czy zdekodowana wiadomość wygląda na oryginalny tekst, czy jest całkowicie zniekształcona? –

+0

czy próbujesz weryfikować wiadomości wysyłane między Javą i PHP, czy też je szyfrować? lub oba? –

Odpowiedz

3

"Podpis RSA" to zazwyczaj więcej niż "szyfrowanie kluczem prywatnym, odszyfrowywanie za pomocą klucza publicznego", ponieważ protokoły klucza publicznego, takie jak PKCS # 1, również określają schematy dopełnienia, a wszystkie schematy podpisu będą szyfrować podsumowanie wiadomości , zamiast pełnej wiadomości. Nie mogę znaleźć żadnej dokumentacji, jeśli schemat podpisu java używa schematu dopełniania podpisu określonego w PKCS # 1, ale podejrzewam, że tak jest.

Jeśli tak, zamiast tego będziesz chciał użyć metody openssl_verify w PHP, udokumentowanej jako here. To zwróci 0 lub 1, jeśli podpis jest nieprawidłowy lub ważny, odpowiednio.

W przypadku, gdy Java nie używa schematu dopełnienia, problem polega na tym, że dane zaszyfrowane w podpisie to skrót wiadomości, zamiast samej wiadomości (w kodzie Java widać, że używa Algorytm skrótu SHA-1). Tak więc, po stronie PHP, musisz wziąć mieszanie sha1 twojej wiadomości przy użyciu sha1 method z ustawieniem $raw_output na wartość true i porównać te łańcuchy, aby upewnić się, że twoja wiadomość jest ważna.

+0

Dziękuję bardzo! Ponieważ podpis będzie oparty na różnych nagłówkach HTTP i ich wartościach, mogę umieścić to razem po stronie serwera i sprawdzić, czy podpis jest poprawny: 'openssl_verify (" Hello, World ", file_get_contents ('sig'), $ pubkey) '. I to działa ;-) – DavidS

+0

Myślę, że mam to samo pytanie .... ale openssl_verify() nie działa dla mnie .... [Question link] (http://stackoverflow.com/questions/16370046/use -php-openssl-weryfikuj-funkcja-do-weryfikacji-podpis-i-danych-utworzonych przez-androi) Proszę o pomoc, z góry dzięki – shanwu

-1

Od fragmencie

$key = openssl_pkey_get_public ("file://pub_key.pem"); 

wygląda jakbyś przedstawieniu klucz publiczny, który byłby niewłaściwy jeden do odszyfrowania. Podwójne sprawdzenie ?

+0

Jest to weryfikacja podpisu, więc użycie klucza publicznego wydaje mi się poprawne. – Henrik

+0

Jest to weryfikacja podpisu, tak, więc serwer nigdy nie powinien znać klucza prywatnego. – DavidS

Powiązane problemy