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<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);
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!