This is what I want to do:
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With