如何在 PHP 中验证 Java 签名的 OpenSSL 数据?解决“无效填充”错误
2024-03-18 10:16:29
使用 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
错误,并确保数据的完整性和真实性。