Проверьте подпись SHA1withRSA, сгенерированную на Java (Android), с помощью phpseclib

Это то, что я хочу сделать:

  • Создание 512-битной пары ключей RSA в Java / Android
  • Создайте подпись SHA1withRSA для некоторого сообщения в Java
  • Отправить сообщение, подпись и открытый ключ для PHP (для тестирования это будет сделано в одно и то же время)
  • Проверьте сообщение в PHP с помощью phpseclib

Что я получил до сих пор:

На стороне 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:

EDIT: Как было упомянуто ниже, решение заключается в добавлении $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1); , Кроме того, я добавил функцию обрезки вокруг $_POST['pubkey'] поскольку я заметил, что ключ, закодированный 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'; в 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 "вещи, но ничего не помогло до сих пор.

Итак, что я должен сделать, чтобы сделать эту работу?

EDIT: Теперь это работает!

Кажется, что $ _POST ['msg'] может быть также base64_decode () 'd? Также попробуйте сделать $rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1) . По умолчанию phpseclib делает дополнение OAEP, которое, хотя и более безопасно, не так широко поддерживается и не является стандартным для большинства вещей.