使用phpseclib验证在Java(Android)中生成的SHA1withRSA签名

时间:2012-01-06 19:22:36

标签: java php android rsa signature

这就是我想要做的事情:

  • 在Java / Android中生成512位RSA密钥对
  • 为Java中的某些消息生成SHA1withRSA签名
  • 向PHP发送消息,签名和公钥(用于测试将同时进行)
  • 使用phpseclib
  • 验证PHP中的消息

到目前为止我得到了什么:

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

在PHP方面:

编辑:正如neubert所说,解决方案是添加$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);。另外,我在$_POST['pubkey']附近添加了trim函数,因为我注意到base64编码的键以换行符结束。

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';

会发生什么:

phpseclib给了我一个php通知“无效签名”,结果是“未经验证”。

我已经在PHP方面测试了不同的变体,例如: base64 - 在将公钥交给loadKey(...)之前解码公钥,而不是base64解码签名,留下“----- BEGIN PUBLIC KEY ----- \ n”的东西,但没有任何帮助远。

那么我需要做些什么来完成这项工作呢?

编辑:现在可以了!

1 个答案:

答案 0 :(得分:3)

好像$ _POST ['msg']似乎也需要是base64_decode()'d?另外,尝试$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1)。默认情况下,phpseclib会执行OAEP填充,虽然它更安全,但不是广泛支持,也不是大多数东西的默认设置。