Проверка подписи JAVA в php - PullRequest
0 голосов
/ 01 ноября 2019

Это был день, когда я застрял на этом. Я много осматривался, но не смог решить проблему.

Код JAVA:

public String generateDigitalSignedToken(String requestData) throws Exception 
{
    Signature signature = Signature.getInstance("SHA1withRSA");
    PrivateKey privateKey = this.readPrivateKeyFromFile(busPrivateFile);
    signature.initSign(privateKey, new SecureRandom());
    byte[] message = requestData.getBytes();
    signature.update(message);
    byte[] sigBytes = signature.sign();
    return Base64.getEncoder().encodeToString(sigBytes);
}

Код PHP:

$rsa = new RSA();
$rsa->loadKey($publicKey);
$rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
$rsa->setHash("sha1");
$rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
$receivedHash = $rsa->decrypt($decodedHash);

TODOS

  1. Расшифруйте токен, чтобы получить полученный хэш.
  2. Вторая задача - воссоздать хэш и сравнить его сполученный хеш.

Код для воссоздания хеша

$temp = new RSA();
$temp->setHash('sha1');
$temp->setSignatureMode(RSA::SIGNATURE_PKCS1);
$generatedHash1 = $temp->hash->_sha1($decryptedBody);

//Or simply

$generatedHash2 = sha1($data, true);

Ниже приведены значения:

"receiveHash "=> b" 0! 0 \ t \ x06 \ x05 + \ x0E \ x03 \ x02 \ x1A \ x05 \ x00 \ x04 \ x14 ÖRM▀ÿuï®▀Q ÷ Å \ x06M¬ \ x16 {M^"

" generateHash1 "/" generateHash2 "=> b" öRM▀ÿuï®▀Q ÷ Å \ x06M¬Õ \ x16 {M ^"

Как видно, хеш частично совпадает, даже если на обоих концах использовались одинаковые строки.

Может кто-нибудь помочь мне решить эту проблему? Буду признателен за любую помощь.

РЕДАКТИРОВАТЬ:

Используемая библиотека PHP: https://github.com/phpseclib/phpseclib

1 Ответ

0 голосов
/ 04 ноября 2019

Одной из проблем является то, что «hashised» не является просто хэшем. Это хеш, завернутый в структуру ASN.1. Если вы выполните openssl asn1parse, вы получите следующее:

    0:d=0  hl=2 l=  33 cons: SEQUENCE
    2:d=1  hl=2 l=   9 cons:  SEQUENCE
    4:d=2  hl=2 l=   5 prim:   OBJECT            :sha1
   11:d=2  hl=2 l=   0 prim:   NULL
   13:d=1  hl=2 l=  20 prim:  OCTET STRING

Вы можете получить фактический хэш sha1 (в PHP), выполнив это:

substr(base64_decode('MCEwCQYFKw4DAhoFAAQUlFJN35h1i6nfUfaPBk2q5RZ7TV4='), 13 + 2, 20)

Есть и другиевозможно лучшие способы сделать это, которые на самом деле анализируют ASN.1 и «отображают» его, но они более многословны, и это все равно выходит за рамки этого «ответа».

Другая проблема заключается в том, что receivedHash isn 't фактическая подпись и не является действительным зашифрованным текстомВаш ключ RSA составляет 2048 бит. Это 256 байт. И подпись / зашифрованный текст должен быть такой же длины. Конечно, я полагаю, это может быть меньше, если вы урежете начальное или конечное пустое пространство, но даже тогда сигнатура / зашифрованный текст не должны иметь «структуру», как у вас. Может быть, до модульного возведения в степень, но не после. Поэтому я думаю, что большая часть проблемы, вероятно, в вашем коде Java. Возможно, когда я вернусь домой, я смогу запустить ваш код Java локально и посмотреть, получу ли я вывод, аналогичный вашему receivedHash. Если это так, я могу сделать свой собственный пост на стеке, спрашивающий, что с этим. Но пока я посмотрю на ваш код Java.

...