2013-03-14 13 views
5

Si supponga Ho il seguente codice Java per generare una coppia di chiavi pubblica-privata:crittografia RSA in Java, decriptare in 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(); 

come si potrebbe fare per e decrittografare il file "sig" in PHP? Ho letto il post: https://stackoverflow.com/a/1662887/414414 che fornisce una funzione per convertire un file DER in PEM (si supponga che salvi anche la chiave pubblica da Java).

Ho provato qualcosa di simile:

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

Decripta correttamente il messaggio, ma è molti personaggi strani.

Il nostro scenario è un client Java che invia messaggi a un server PHP, ma crittografa i dati con una chiave privata. PHP conosce la chiave pubblica, che dovrebbe usare per decifrare e convalidare il messaggio.

Ho letto molti post su questo problema qui su SO, ma ho capito che questo è un problema un po 'specifico, soprattutto se ci sono algoritmi diversi in uso, ecc. Quindi scusa se questo può essere un duplicato

Qualsiasi feedback è molto apprezzato!

+2

"Decifra correttamente il messaggio, ma sono molti caratteri strani." - puoi essere più specifico a riguardo? Potrebbe semplicemente essere un problema di codifica? –

+1

Il messaggio decodificato assomiglia al testo originale o è completamente confuso? –

+0

stai provando a verificare i messaggi inviati tra Java e PHP o crittografarli? o entrambi? –

risposta

3

una "firma RSA" è in genere più di una semplice "crittografia con chiave privata, decrittografia con chiave pubblica", poiché i protocolli di chiave pubblica come PKCS # 1 specificano anche schemi di riempimento e tutti gli schemi di firma crittografano un digest del messaggio , invece del messaggio completo. Non riesco a trovare alcuna documentazione se lo schema di firma di java utilizza lo schema di riempimento della firma specificato in PKCS # 1, ma il mio sospetto è che lo sia.

Se lo è, si preferisce utilizzare il metodo openssl_verify in PHP, documentato here. Ciò restituirà uno 0 o 1 se la firma non è valida o valida, rispettivamente.

Nel caso in cui Java non utilizzi uno schema di riempimento, il problema è che i dati crittografati nella firma sono un hash del messaggio, invece del messaggio stesso (nel codice Java è possibile vedere che utilizza il Algoritmo hash SHA-1). Pertanto, sul lato PHP, dovrai utilizzare l'hash sha1 del tuo messaggio utilizzando sha1 method con $raw_output impostato su true e confrontare tali stringhe per garantire che il tuo messaggio sia valido.

+0

Grazie mille! Poiché la firma sarà basata su varie intestazioni HTTP e sui relativi valori, posso metterlo insieme sul lato server e controllare se la firma è valida: 'openssl_verify (" Hello, World ", file_get_contents ('sig'), $ pubkey) '. E questo funziona ;-) – DavidS

+0

Penso di avere la stessa domanda .... ma openssl_verify() non funziona per me .... [Domanda link] (http://stackoverflow.com/questions/16370046/use -php-openssl-verify-function-to-verify-signature-and-data-created-by-androi) Si prega di aiutare, grazie in anticipo – shanwu

-1

Dal frammento di

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

Sembra che tu stia riferimento alla chiave pubblica, che sarebbe quello sbagliato per decifrare. Doppio controllo?

+0

E 'la verifica della firma, quindi l'uso della chiave pubblica mi sembra corretto. – Henrik

+0

È una verifica della firma, sì, quindi il server non dovrebbe mai conoscere la chiave privata .. – DavidS

Problemi correlati