2012-01-06 12 views
5

Questo è quello che voglio fare:Verifica firma SHA1withRSA generato in Java (Android) con phpseclib

  • generare una coppia di chiavi RSA 512 bit in Java/Android
  • generare una firma SHA1withRSA per qualche messaggio in Java
  • Invia un messaggio, la firma e la chiave pubblica a PHP (per testare questo sarà fatto allo stesso tempo)
  • verificare il messaggio in PHP utilizzando phpseclib

quello che ho ottenuto finora:

Sul lato Java:

String msg = "Test message"; 

// generate keypair 
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); 
keyGen.initialize(512); 
KeyPair keyPair = keyGen.generateKeyPair(); 

// generate signature 
Signature signature = Signature.getInstance("SHA1withRSA"); 
signature.initSign(keyPair.getPrivate(), SecureRandom.getInstance("SHA1PRNG")); 
signature.update(msg.getBytes()); 
byte[] sigBytes = signature.sign(); 

// send message, signature and public key to php script 
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(uploadNum + 1); 
nameValuePairs.add(new BasicNameValuePair("msg", msg)); 
nameValuePairs.add(new BasicNameValuePair("signature", Base64.encodeToString(sigBytes, 
     Base64.DEFAULT))); 
nameValuePairs.add(new BasicNameValuePair("pubkey", Base64.encodeToString(keyPair 
     .getPublic().getEncoded(), Base64.DEFAULT))); 

HttpClient httpClient = new DefaultHttpClient(); 
HttpPost httpPost = new HttpPost(UPLOAD_SCRIPT); 
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
HttpResponse response = httpClient.execute(httpPost); 

Sul lato PHP:

EDIT: Come Neubert accennato, la soluzione è quella di aggiungere $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);. Inoltre ho aggiunto la funzione di ritaglio attorno a $_POST['pubkey'] perché ho notato che la chiave codificata in base64 termina con un'interruzione di riga.

include('Crypt/RSA.php'); 
$rsa = new Crypt_RSA(); 
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); 
$rsa->loadKey("-----BEGIN PUBLIC KEY-----\n" . trim($_POST['pubkey']) . "\n-----END PUBLIC KEY-----"); 
echo $rsa->verify($_POST['msg'], base64_decode($_POST['signature'])) ? 'verified' : 'unverified'; 

ciò che accade è:

phpseclib mi dà un avviso di php "Firma non valida" e il risultato è "non verificato".

Ho già provato questo con diverse varianti sul lato PHP, ad es. base64-decodifica la chiave pubblica prima di passarla a loadKey (...), non a base64-decodifica la firma, lasciando via le cose "----- BEGIN PUBLIC KEY ----- \ n", ma nulla è stato di aiuto lontano.

Quindi cosa devo fare per farlo funzionare?

MODIFICA: Ora funziona!

+0

Aveva quasi lo stesso problema: assicurati di basare 64_decode la firma! Trascurato un paio di volte – xXx

risposta

3

Sembra che $ _POST ['msg'] possa essere necessario anche base64_decode() 'd? Inoltre, prova a fare $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1). Per impostazione predefinita, phpseclib esegue il riempimento OAEP che, sebbene più sicuro, non è ampiamente supportato, né è l'impostazione predefinita per la maggior parte delle cose.

+0

Grazie neubert, '$ rsa-> setEncryptionMode (CRYPT_RSA_ENCRYPTION_PKCS1)' ha fatto il trucco. Aggiornerò il mio post originale. –