返回

如何在 PHP 中验证 Java 签名的 OpenSSL 数据?解决“无效填充”错误

php

使用 PHP 验证 Java 签名的 OpenSSL 数据

前言

在构建安全和可靠的应用程序时,使用数字签名来验证数据的完整性和真实性至关重要。然而,当使用不同编程语言(例如 PHP 和 Java)处理 OpenSSL 数据时,验证过程可能会遇到挑战。本文将探讨当使用 PHP 的 openssl_verify() 函数验证 Java 端签名的 OpenSSL 数据时遇到的一个常见错误,即 error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding

可能的原因

此错误通常是由以下几个原因引起的:

1. 填充算法不匹配

PHP 中使用的填充算法与 Java 端生成签名时使用的算法不一致。

2. 证书链不完整

用于验证签名的 PHP 证书链可能不完整或无效。

3. 密钥大小问题

PHP 中使用的 RSA 密钥大小与 Java 端使用的 RSA 密钥大小不同。

解决方法

为了解决此错误,我们需要解决潜在的根本原因:

1. 检查填充算法

确保 PHP 中 openssl_verify() 函数使用的填充算法与 Java 端签名时使用的算法匹配。常见的算法包括 SHA1withRSA、SHA256withRSA 和 SHA512withRSA。

2. 验证证书链

使用 openssl x509 -noout -text 命令检查用于验证签名的证书链,确保链条完整且所有证书都有效。

3. 检查密钥大小

使用 openssl rsa -text 命令比较 PHP 和 Java 中使用的 RSA 密钥大小,确保它们一致。

4. 其他可能的方法

  • 尝试使用不同版本的 PHP OpenSSL 或其他 OpenSSL 库。
  • 使用 PEM 格式的密钥(而不是 DER 格式)。
  • 确保使用的 PHP 和 Java 版本都支持所需的 OpenSSL 算法。

代码示例

以下代码演示如何使用正确的填充算法和证书链进行 PHP 验证:

<?php

$data = 'B00202|20240226201949|405700076195|20240226203753|06||AC|681708957177|BY||90.0|IN';
$signature = hex2bin('3DDA6FD0EFE0F1031E391B214977A7C6CBD57151E39F42EA3AC20A77E1924FABA829CCFE8222F4C42052843F1FBADC8BD038BE3AD744B1788550A17734974516D0F70896ABA8F09D0F359D0FD2CB14DD41ED532F1BAF27ABCF0F70B8A15FB263718AB088DFCE14497097921C7B655A9C1D5AEE3404C39CCB11244314D76917A42F6EE6064910F9AD0B1432363D98931DB4059EBCF04A481D3BA9B290EFA5EED98BA576623F1F45CAF182D1697EEBD044E362BA6ACCC2BC76C2BC385E8B65F90419317E3FFBFA5CB8A68859C90D3A4F9E0313186E78FEEFCEA74C7482932E7CDEC9C7F771F59B39DB42855183E91B67164C37B391E8340E8FEE07A2BDD11B8366');
$crt = '-----BEGIN CERTIFICATE-----
MIIENzCCAx+gAwIBAgIGEmiK5GVbMA0GCSqGSIb3DQEBCwUAMHgxDzANBgNVBAYT
...
-----END CERTIFICATE-----';

$verified = openssl_verify($data, $signature, $crt, OPENSSL_ALGO_SHA1);

if ($verified === 1) {
    echo 'Verified successfully';
} else {
    echo 'Verification failed with error code ' . $verified;
}

常见问题解答

1. 为什么会收到 invalid padding 错误?

这通常是由于填充算法不匹配或密钥大小问题引起的。

2. 如何查看证书链?

使用 openssl x509 -noout -text 命令查看用于验证签名的证书链。

3. 如何检查密钥大小?

使用 openssl rsa -text 命令比较 PHP 和 Java 中使用的 RSA 密钥大小。

4. 可以使用不同的 OpenSSL 库吗?

是的,你可以尝试使用不同版本的 PHP OpenSSL 或其他 OpenSSL 库。

5. 我还可以尝试哪些其他方法?

使用 PEM 格式的密钥并确保使用的 PHP 和 Java 版本都支持所需的 OpenSSL 算法。

结论

通过解决填充算法、证书链和密钥大小问题,我们可以成功验证使用 Java 签名的 OpenSSL 数据。遵循本文中概述的步骤,你可以避免 error:0407008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding 错误,并确保数据的完整性和真实性。