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!
Aveva quasi lo stesso problema: assicurati di basare 64_decode la firma! Trascurato un paio di volte – xXx