在 php 中验证来自 java 的 rsa 签名

发布于 2025-01-02 19:24:06 字数 2884 浏览 1 评论 0原文

几天以来,我遇到了一个我自己无法解决的问题:

在JavaCard上,我生成了一个RSA密钥对(长度:1024)和一个签名(模式:ALG_RSA_MD5_PKCS1)。 现在我必须验证 php.ini 中的签名。

从我的 JavaCard 中,我得到了十六进制的指数、模数和签名:

    $mod = '951ADDA04637190B6202BB52787D3C19160A383C80C2E7242D0A7850FDD80C1CD1CCCF1395F8CA0B20270E3BC6C86F78232D65D148258BEFD0884563C60AB2C327506FB4FA0095CF0B1C527D942155731451F790EC0A227D38613C9EBFB2E04A657B3BA5456B35F71E92E14B7E1CB38DB6572559BFCA3B0AD8AA061D48F68931';
    $exp = '010001';
    $sign ='75867D42BDE6DF1066D4AF69418FCDD4B0F19173141128DFEBC64AF6C014CB92D38F4824E52BB064A610E07C7783AE57AE993A792F15208FB199CB1F45B64623AACB7FBA07AD89513C8DBA893C9FA6939857AA2CA53AAD99D9A9C1C32DF4E2769FCACB72E2C2C495727D368D953A911D32E79E230751202714DD15C0B6A34782';
    $plaintext = '01020304';

Java 中的验证没有问题。但知道我必须验证 PHP 中的签名(我采用 phpseclib)。

在 PHP 中,我使用 CRYPT_RSA_PUBLIC_FORMAT_RAW 生成我的 public_key:

    $rsa = new Crypt_RSA();
    $pk = array(
        'e' => new Math_BigInteger($exp, 16),
        'n' => new Math_BigInteger($mod, 16)
    );
    $rsa->loadKey($pk, CRYPT_RSA_PUBLIC_FORMAT_RAW);

    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    echo $rsa->verify($plaintext, $sign) ? 'verified' : 'unverified';

知道的问题是在函数 verify 中设置正确的值。 如果我只是将签名设置为十六进制,我会收到通知:

Invalid signature: length = 256, k = 128 in C:\xampp\php\PEAR\Crypt\RSA.php on line 2175

所以我必须自定义签名的长度:

    $sign_bigInteger = new Math_BigInteger($sign, 16);
    $sign_bytes = $sign_bigInteger->toBytes();

    echo $rsa->verify($plaintext, $sign_bytes) ? 'verified' : 'unverified';

但验证是错误的。

我在 RSA.php (_rsassa_pkcs1_v1_5_verify) 中得到验证函数的输出,其中将明文与签名进行比较:

    //sign
    "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0 0*†H†÷ ÖÀZ!Q*y¡ßë*&/" 
    //plaintext
    "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0!0 +•q£îê“O•äQ».åüÓSœÝ["

我不太明白 RSA.php 类中发生了什么。 谁能帮助我并说出我做错了什么?

编辑:

现在我尝试转换我的十六进制字符串。

    $plaintext_bin = pack("H*", $plaintext);
    $sign_bin = pack("H*", $sign);

我认为我的公钥是正确生成的,因此我只需更改验证的输入:

    $rsa->verify($plaintext_bin, $sign_bin) ? 'verified' : 'unverified';

输出:

    em: string(128) "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0 0*†H†÷ ÖÀZ!Q*y¡ßë*&/"
    em2: string(128) "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0!0 +ÚÚÿMG‡­ã31G ,;D>7o" 

仍然不一样。

编辑:

我解决了我的问题。我忘记设置哈希值:

    $rsa1->setHash('md5');

现在可以了!

谢谢格雷格。

Since a few days I've got a problem that I can't solve on my own:

On a JavaCard I generate a RSA KeyPair (length: 1024) and a signature (Mode:ALG_RSA_MD5_PKCS1).
Now I have to verify the signature in php.

From my JavaCard I get the exponent, modulus and the signature in hexadecimal:

    $mod = '951ADDA04637190B6202BB52787D3C19160A383C80C2E7242D0A7850FDD80C1CD1CCCF1395F8CA0B20270E3BC6C86F78232D65D148258BEFD0884563C60AB2C327506FB4FA0095CF0B1C527D942155731451F790EC0A227D38613C9EBFB2E04A657B3BA5456B35F71E92E14B7E1CB38DB6572559BFCA3B0AD8AA061D48F68931';
    $exp = '010001';
    $sign ='75867D42BDE6DF1066D4AF69418FCDD4B0F19173141128DFEBC64AF6C014CB92D38F4824E52BB064A610E07C7783AE57AE993A792F15208FB199CB1F45B64623AACB7FBA07AD89513C8DBA893C9FA6939857AA2CA53AAD99D9A9C1C32DF4E2769FCACB72E2C2C495727D368D953A911D32E79E230751202714DD15C0B6A34782';
    $plaintext = '01020304';

A Verification in Java is no problem. But know I have to verify the signature in PHP (I take phpseclib).

In PHP I generate my public_key with CRYPT_RSA_PUBLIC_FORMAT_RAW:

    $rsa = new Crypt_RSA();
    $pk = array(
        'e' => new Math_BigInteger($exp, 16),
        'n' => new Math_BigInteger($mod, 16)
    );
    $rsa->loadKey($pk, CRYPT_RSA_PUBLIC_FORMAT_RAW);

    $rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
    echo $rsa->verify($plaintext, $sign) ? 'verified' : 'unverified';

The problem know is to set the correct values in the function verify.
If I just set my signature in hexadecimal I get the notice:

Invalid signature: length = 256, k = 128 in C:\xampp\php\PEAR\Crypt\RSA.php on line 2175

So I have to customize the length of my signature:

    $sign_bigInteger = new Math_BigInteger($sign, 16);
    $sign_bytes = $sign_bigInteger->toBytes();

    echo $rsa->verify($plaintext, $sign_bytes) ? 'verified' : 'unverified';

But the verification is false.

I get the output of the verification function in RSA.php (_rsassa_pkcs1_v1_5_verify) where plaintext is compared with the signature :

    //sign
    "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0 0*†H†÷ ÖÀZ!Q*y¡ßë*&/" 
    //plaintext
    "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0!0 +•q£îê“O•äQ».åüÓSœÝ["

I don't really understand whats happening in the Class RSA.php.
Can anyone help me and say what I do wrong?

EDIT:

Now I tried to convert my hexString.

    $plaintext_bin = pack("H*", $plaintext);
    $sign_bin = pack("H*", $sign);

I think that my public key is correct generated, so I just change the input of my verify:

    $rsa->verify($plaintext_bin, $sign_bin) ? 'verified' : 'unverified';

Output:

    em: string(128) "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0 0*†H†÷ ÖÀZ!Q*y¡ßë*&/"
    em2: string(128) "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0!0 +ÚÚÿMG‡­ã31G ,;D>7o" 

It's still not the same.

EDIT:

I fixed my problem. I forgot to set the Hash:

    $rsa1->setHash('md5');

Now it works!

Thank you GregS.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梨涡少年 2025-01-09 19:24:06

您的所有值都是十六进制字符串。只需使用 hex2bin()pack("H*", $hex_string); 转换它们

All your values are hex strings. Just convert them using hex2bin() or pack("H*", $hex_string);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文