首页 > 解决方案 > php和ruby中连续RSA加密和base64编码的输出差异

问题描述

我的目标是集成一个API 服务,它希望我按照这些步骤生成签名。

  1. 检索您的客户 ID。
  2. 用句点 (.) 分隔的 CURRENT UNIX 时间戳附加它
  3. 使用您收到的公钥使用 RSA 加密来加密这些数据——这就是签名。
  4. 通过标头 X-Cf-Signature 传递此签名。

第 3 步是签名生成步骤。在我的 ruby​​ 应用程序中,这就是我实现这些步骤的方式。

def dynamic_signature
 raw_data = "#{client_id}.#{Time.now.to_i}"
 filepath = "public_key.pem"
 public_key = OpenSSL::PKey::RSA.new File.read(filepath)
 Base64.strict_encode64(public_key.public_encrypt(raw_data)).encode("UTF-8")
end

但 API 服务拒绝此签名。他们在 php 中有代码片段示例,因此使用以下代码在 php 中尝试了此过程。我已经使用上面的 ruby​​ 代码中的变量来表示。

<?php

$plainData = <raw_data>;
$publicKey = <public_key.to_s>;
openssl_public_encrypt($plainData, $encrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
echo base64_encode($encrypted);

?>

该签名被 API 服务接受。我做了一些手动检查,两个 base64 输出明显不同。在 ruby​​ 中,我尝试过使用和不强制执行encode("UTF-8").

有趣的是,以下语句返回 true,无论我在末尾执行strict_encode64orencode64还是 append encode("UTF-8")

base64_generated_in_ruby.bytes == base64_generated_in_php.bytes

我通过在 ruby​​ 控制台中复制粘贴 base64 编码的字符串来进行此相等性检查。

我怀疑 base64 编码对于这两种语言的转义字符的工作方式不同。任何帮助表示赞赏。

编辑 1:添加示例。

  1. 我在 base64 中编码的 RSA 加密字符串。
"g\xF3\f%\xA2\xC0(\xCBYAw\x80\xA5 c\x9DR\xC7r\xFE\xAF \xADJ\xCBy\x8D\xC8kd#\xD3\x04L(\x9B\xC0V\n\xCD\xFF\xD4\rj\xF0\x12\x86\xEC5\xC6ev\xCEUD\x9B\xA2\xAD\x9F{\xC8\xF5\x8A\x00->\xB5\xA4f\x05\x9F\xE1\x81u\xB5\x87\xD4\xD7\xA7\xCC\xE0:\xC9\xF3,\x8D(\x10\xEC\\\xE8'\r\xFA\x14\x82\x8A\xCF_^\xAA\x94\x17\x15\xD0Qw\x18\xDB\xE7\t\xEEy\x9E04\x94\xDE\xFB\xF6\xEB:\xDF\x90\xDER\xEB\xF1c\xF2\x98\x00\x9CM\x16\xA6{\x12\xA8\xA2\xE7\x00\x89\xDE\xB4\x9C\xB1\xE9\x81\x9D\xB4\xC8~q\x8A\xBDu#\xD2\xD2\x19T\xE4H\x7F\x0E\xDF\xECV\x8E\rF\xF7\x12m\x1C\xFE-\xC2gO\x90\xEDp\x88\x1A\x1D\t4\xC2\r!\xD5Y\xC3\xBB\xB8*B%\x00\xDF\xE2s\x8A\x19j\xFB\xEBy\xD7\xD6\xF5\x06\x99\xEE\xEA\xE4\xA3\x83\x97\xDB\x95\xA2o\x86\x97c\xA8w\xAAb\xEF\x00e\xC4\b\xD3\xEB\xFB\x86\xF4\xE2!\xF1{\xA5\x80\xD7\xC4\xC4\x01,\xBFj-"
  1. 使用红宝石作为Base64.strict_encode64(rsa_string)
"Z/MMJaLAKMtZQXeApSBjnVLHcv6vIK1Ky3mNyGtkI9METCibwFYKzf/UDWrwEobsNcZlds5VRJuirZ97yPWKAC0+taRmBZ/hgXW1h9TXp8zgOsnzLI0oEOxc6CcN+hSCis9fXqqUFxXQUXcY2+cJ7nmeMDSU3vv26zrfkN5S6/Fj8pgAnE0WpnsSqKLnAInetJyx6YGdtMh+cYq9dSPS0hlU5Eh/Dt/sVo4NRvcSbRz+LcJnT5DtcIgaHQk0wg0h1VnDu7gqQiUA3+Jzihlq++t519b1Bpnu6uSjg5fblaJvhpdjqHeqYu8AZcQI0+v7hvTiIfF7pYDXxMQBLL9qLQ=="
  1. 使用 php 作为base64_encode($rsa_string)
"Z/MMJaLAKMtZQXeApSBjnVLHcv6vIK1Ky3mNyGtkI9METCibwFYKzf/UDWrwEobsNcZlds5VRJuirZ97yPWKAC0+taRmBZ/hgXW1h9TXp8zgOsnzLI0oEOxc6CcN+hSCis9fXqqUFxXQUXcY2+cJ7nmeMDSU3vv26zrfkN5S6/Fj8pgAnE0WpnsSqKLnAInetJyx6YGdtMh+cYq9dSPS0hlU5Eh/Dt/sVo4NRvcSbRz+LcJnT5DtcIgaHQk0wg0h1VnDu7gqQiUA3+Jzihlq++t519b1Bpnu6uSjg5fblaJvhpdjqHeqYu8AZcRcYtPr+4b04iHxe6WA18TEASy/ai0="

标签: phprubybase64escapingrsa

解决方案


默认情况下,rubypublic_encrypt方法不包含填充参数。用于public_encrypt(raw_data, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)添加相关的填充参数。在提供的 php 代码中明确提到了提交的填充。


推荐阅读