在 Ruby 中加密的字符串给出: 'BadPaddingException' 在 Java 中解密时

String encrypted in Ruby gives: 'BadPaddingException' when decrypted in Java

我正在使用以下 Ruby 代码来加密字符串

require 'openssl'
require 'base64'

public_key = OpenSSL::PKey::RSA.new(File.read('public_key'))

Base64.encode64(public_key.public_encrypt('Some random string that I want to encrypt.'))

我需要将请求中的加密文本传递给 API,在 API 端,我收到以下错误(阅读 API 日志):

javax.crypto.BadPaddingException: Decryption error

现在,我已经在 Whosebug 上解决了很多问题,但是考虑到我的 Ruby 代码,我做错了什么,无法在 API 端解密加密文本.显然,API端使用的是Java.

我对加密完全是菜鸟,但通过Ruby中的加密和解密,我确定Ruby中的实现是正确的。当通过 Ruby 语言加密的文本在 API 端通过 Java 解密时,问题就出现了。

根据the openJdk source code,BadPaddingException 表示"if this cipher is in decryption mode, and (un)padding has been requested, but the decrypted data is not bounded by the appropriate padding bytes"。这意味着此异常有两个不同的可能原因 - 其名称可能具有误导性,但在最低级别上技术上是正确的 - 要么填充错误,要么解密与加密不匹配。在后一种情况下,解密的结果将是乱码,因此 - 解释源代码的技术语言 - 不适合填充方案。

来自Cryptography book

'PKCS1 padding adds 11 bytes to your original data.'

因此您应使用大小为 public 密钥长度 - 11 的缓冲区进行加密,并使用实际的 public 密钥大小进行解密

对于 1024 位 RSA 密钥,加密大小通常为 117,解密缓冲区大小为 128。

我写了一个非常简单的 Java 程序来解密那个非常简单的 Ruby 程序的输出,它运行良好。因此,毫不奇怪,在 ruby openssl 模块和标准 Java 密码学之间没有 固有的 不兼容。没有关于 Java 方面的更多信息,我们所能做的就是列出一些可能性:

  1. 键不匹配

您使用的 public 密钥必须与 Java 方使用的私钥相对应。否则,您可能会收到 BadPadding 异常。

  1. 格式问题

很明显,您传输的内容是带有嵌入换行符的 base64 编码字符串,必须在 Java 端正确解析和解码。获取单个字节错误可能会导致您看到的错误。大多数 base64 解码器要么在换行符处阻塞并抛出异常,要么忽略它们。这两种解释都不会导致 BadPaddingException。也许 Java 一方期待 If Java 端期望 base64url 编码并且 if 它忽略无效字符,那么这可能是问题所在。值得尝试从 base64 输出中删除包括换行符在内的空格,如果这不起作用,请尝试使用 base64url 编码器进行编码(同样,从输出中删除任何空格)。