如何让 PHP 签署与 C# 完全相同的输入?
How can I get PHP to sign an input exactly the same as C#?
我正在使用需要对 XML 进行签名的较旧的 API。没有适当的文档,唯一的代码示例是用 C# 给出的。我需要将此示例移植到 PHP。但是,即使提供相同的输入,我在 PHP 中编写的代码也会得到不同的输出,从而导致 API 调用失败。
我在 C# 中将它缩小到这个函数:
public byte[] CreateSignature(byte[] hash)
{
RSAPKCS1SignatureFormatter signatureFormatter = new RSAPKCS1SignatureFormatter(pfxCert.PrivateKey);
signatureFormatter.SetHashAlgorithm("SHA1");
return signatureFormatter.CreateSignature(hash);
}
下面是 PHP 中的相同操作:
public function createSignature($hashByteArray, $certArray) {
$hash = implode(array_map("chr", $hashByteArray));
$hashEncoded = base64_encode($hash);
openssl_sign($hashEncoded,$signature, $certArray);
return unpack("C*", $signature);
}
请注意,openssl_sign 中的输入不能采用字节数组,因此这是一个可能的差异点。我已经尝试了 openssl_get_md_methods() 和 phpseclib 提供的所有算法,都没有匹配输出。
我在 C# and PHP 中创建了相同示例输入和证书的 GitHub 要点,以更好地说明问题。
如何在 PHP 中获得与 C# 相同的签名输出,给定相同的输入?
它们之间有根本的区别。
RSAPKCS1SignatureFormatter.CreateSignature 方法需要 数据散列。另一方面,openssl_sign
需要 数据本身。
From PHP: openssl_sign - Manual
openssl_sign() computes a signature for the specified data by
generating a cryptographic digital signature using the private key
associated with priv_key_id. Note that the data itself is not
encrypted.
显然,您生成了一些数据的散列值以用于用 C# 编写的 API。不要用 openssl_sign
做,而是用原始数据调用。 openssl_sign
将在签名前对其进行哈希处理,这是设计使然。
我正在使用需要对 XML 进行签名的较旧的 API。没有适当的文档,唯一的代码示例是用 C# 给出的。我需要将此示例移植到 PHP。但是,即使提供相同的输入,我在 PHP 中编写的代码也会得到不同的输出,从而导致 API 调用失败。
我在 C# 中将它缩小到这个函数:
public byte[] CreateSignature(byte[] hash)
{
RSAPKCS1SignatureFormatter signatureFormatter = new RSAPKCS1SignatureFormatter(pfxCert.PrivateKey);
signatureFormatter.SetHashAlgorithm("SHA1");
return signatureFormatter.CreateSignature(hash);
}
下面是 PHP 中的相同操作:
public function createSignature($hashByteArray, $certArray) {
$hash = implode(array_map("chr", $hashByteArray));
$hashEncoded = base64_encode($hash);
openssl_sign($hashEncoded,$signature, $certArray);
return unpack("C*", $signature);
}
请注意,openssl_sign 中的输入不能采用字节数组,因此这是一个可能的差异点。我已经尝试了 openssl_get_md_methods() 和 phpseclib 提供的所有算法,都没有匹配输出。
我在 C# and PHP 中创建了相同示例输入和证书的 GitHub 要点,以更好地说明问题。
如何在 PHP 中获得与 C# 相同的签名输出,给定相同的输入?
它们之间有根本的区别。
RSAPKCS1SignatureFormatter.CreateSignature 方法需要 数据散列。另一方面,openssl_sign
需要 数据本身。
From PHP: openssl_sign - Manual
openssl_sign() computes a signature for the specified data by generating a cryptographic digital signature using the private key associated with priv_key_id. Note that the data itself is not encrypted.
显然,您生成了一些数据的散列值以用于用 C# 编写的 API。不要用 openssl_sign
做,而是用原始数据调用。 openssl_sign
将在签名前对其进行哈希处理,这是设计使然。