Это то, что я хочу сделать:
Что я получил до сих пор:
На стороне 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, которое, хотя и более безопасно, не так широко поддерживается и не является стандартным для большинства вещей.