我需要向银行发送查询,其中包含指定字符串格式的验证码$ 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
使用公钥算法RSA计算MAC008函数的值。空字段的值也被考虑在内 - “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)计算。
答案 0 :(得分:3)
如果您尝试使用$ rsa-> sign()怎么办? PKCS#1不会通过简单地加密哈希进行签名,如果您的银行正在使用可互操作的RSA解决方案,他们可能也不会这样做。
答案 1 :(得分:2)
代码几乎是正确的 - 我不需要再次哈希(感谢@Accipitridae)。
解决方案是商家的ID必须是大写的,而不是提供的小写。规范中的任何地方都没有说它必须是大写的。好的。
答案 2 :(得分:0)
如上所述,您可以使用openssl轻松完成此操作。以下是我将如何做到这一点。
$hashed = sha1($vk_mac);
openssl_public_encrypt($vk_mac, $encrypted, ($pubkey));
$vk_mac = base6$_encode($encrypted);