2

我需要向银行发送查询,其中包含指定字符串格式的验证码 $vk_mac。代码必须是 SHA1 哈希和 RSA,使用我的公钥加密并以 base64 格式显示。不幸的是,到目前为止,我一直没有成功——银行给了我“错误的签名”以及我得到的所有信息。

我所拥有的是:

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents("private_key.pem"));
$rsa->loadKey($rsa->getPublicKey());
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1);
$encrypted = $rsa->encrypt(sha1($vk_mac));
$vk_mac = base64_encode($encrypted);

private_key.pem 这里是我的纯文本私钥。我尝试将加密模式设置为 CRYPT_RSA_ENCRYPTION_OAEP 没有运气。我有 99.9% 的把握,起始 $vk_mac 字符串的格式正确并包含所有必需的详细信息。

有人知道我做错了什么吗?谢谢你。


编辑:

我已将代码更改为此(其中 vk_mac 是需要签名的起始格式化字符串,而 private_key.pem 是我解码的私钥):

$rsa = new Crypt_RSA();
$rsa->loadKey(file_get_contents("private_key.pem"));
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
$hashed = $rsa->hash->hash($vk_mac);
$encrypted = $rsa->sign($hashed);
$signature = base64_encode($encrypted);

我可以告诉生成的签名是正确的,因为当我这样做时:

$rsa->loadKey($rsa->getPublicKey());
$verified = $rsa->verify($hashed, base64_decode($signature));

$verified 返回 TRUE。

但是,银行回应“签名不正确”。还有什么想法吗?

编辑:

规格

VK_MAC 控制码计算

VK_MAC,用于电子签名,在请求中使用,用于检查和确认使用的算法版本,在参数VK_VERSION中指示。这次使用的是 008 版本。VK_MAC 在 BASE64 编码中作为请求参数呈现。

版本 008

MAC008 函数的值是使用公钥算法 RSA 计算的。空字段的值也被考虑在内——“000”。

MAC008(x1,x2,…,xn) := RSA(SHA-1(p(x1)|| x1|| p(x2)|| x2 || … ||p(xn)||xn),d, n)

地点:|| 是添加字符串的操作 x1, x2, ..., xn 是查询参数 p 是参数长度的函数。长度是三位数字符串形式的数字 d 是 RSA 秘密指数 n 是 RSA 模数 签名根据 PKCS1 标准 (RFC 2437) 计算。

4

3 回答 3

3

如果你尝试 $rsa->sign() 会怎样?PKCS#1 不会通过简单地加密哈希来进行签名,如果您的银行使用可互操作的 RSA 解决方案,他们可能也不会这样做。

于 2011-05-21T10:22:17.153 回答
2

代码几乎是正确的——不过我不需要再次对其进行哈希处理(感谢@Accipitridae)。

解决方案是商家的 ID 必须是大写的,而不是提供的小写。它没有在规范中的任何地方说它也必须是大写的。好的。

于 2011-05-23T11:36:19.477 回答
0

As mentioned above you can do this easily with openssl. Below is how I would do so.

$hashed = sha1($vk_mac);
openssl_public_encrypt($vk_mac, $encrypted, ($pubkey));
$vk_mac = base6$_encode($encrypted);

Read the documentation on openssl_public_encrypt for more.

于 2011-05-20T23:43:23.750 回答