This is what I want to do:
Generate a 512 bit RSA keypair in Java/Android
Generate a SHA1withRSA signature for some message in Java
Send message, signature and public key to PHP (for testing this will be done at the same time)
Verify the message in PHP using phpseclib
What I got so far:
On the Java side:
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 nameValuePairs = new ArrayList(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);
On the PHP side:
EDIT: As neubert mentioned, the solution is to add $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);. In addition I added the trim function around $_POST['pubkey'] as I noticed that the base64-encoded key ends with a linebreak.
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';
What happens is:
phpseclib gives me a php notice "Invalid signature" and the result is "unverified".
I already tested this with different variations on the PHP side, e.g. base64-decoding the public key before handing it to loadKey(...), not base64-decoding the signature, leaving away the "-----BEGIN PUBLIC KEY-----\n" things, but nothing helped so far.
So what do I have to do to make this work?
EDIT: Now it works!
解决方案
Seems like $_POST['msg'] might need to be base64_decode()'d as well? Also, try doing $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1). By default phpseclib does OAEP padding which, although more secure, is not as widely supported nor is it the default for most stuff.