使用phpseclib的Crypt_RSA加密银行的验证码

时间:2011-05-20 19:39:23

标签: php security encryption rsa phpseclib

我需要向银行发送查询,其中包含指定字符串格式的验证码$ 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)计算。

3 个答案:

答案 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);

阅读documentation on openssl_public_encrypt了解更多信息。