用Ruby加密的字符串,在Java中解密时出现“BadPaddingException”的错误。

4
我正在使用以下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

现在,我已经在Stackoverflow上看了很多问题,但是针对我的Ruby代码,我在API端无法解密加密文本的问题出错了。显然,API端正在使用Java。
当涉及到加密时,我完全是一个新手,但通过在Ruby中进行加密和解密,我确保实现在Ruby中是正确的。问题在于,当通过Ruby语言加密的文本在API端通过Java解密时就会出现问题。

在Ruby和Java中以BigInteger的形式输出模数,并检查它们是否相同。这应该有助于确定您是否在Java中正确加载了私钥。还要检查每个程序使用的填充方式。您的Ruby代码并没有明示您是使用PKCS#1Padding还是OAEP填充。 - Luke Joshua Park
好的,我的代码正在使用PKCS1填充。 - Arslan Ali
那么Java端期望什么填充方式? - Ebbe M. Pedersen
@EbbeM.Pedersen 它期望 PKCS1。 - Arslan Ali
请务必在您的问题中包含API的Java代码,包括解密部分、加载私钥和解码客户端发送的数据。 - pedrofb
@pedrofb 不可能的。 - Arslan Ali
3个回答

3
我写了一个非常简单的Java程序来解密那个非常简单的Ruby程序的输出,它运行得很好。因此,毫不意外,Ruby的openssl模块和标准的Java加密之间没有固有的不兼容性。如果没有更多关于Java方面的信息,我们只能列出一些可能性:
1. 键不匹配
您使用的公钥必须对应于Java端使用的私钥。如果不是,则可能会收到BadPadding异常。
2. 格式问题
显然,您传输的内容是带有嵌入换行符的base64编码字符串,在Java端必须正确解析和解码。一个字节出错可能会导致您看到的错误。大多数base64解码器要么无法处理换行并抛出异常,要么忽略它们。这两种解释都不会导致BadPaddingException。也许Java端期望的是Base64URL而不是Base64?如果Java端期望的是base64url编码,并且忽略无效字符,则可能存在问题。值得尝试从base64输出中删除空格,包括换行符,如果这样不起作用,那么请尝试使用base64url编码器进行编码(同样,从输出中删除任何空格)。

2
根据openJdk源代码,BadPaddingException的意思是“如果此密码器处于解密模式,并请求(反)填充,但解密数据未受到适当填充字节的限制”。这意味着出现此异常有两个可能的原因 - 其名称可能会误导,但在最低级别上是技术上正确的 - 要么填充错误,要么解密与加密不匹配。在后一种情况下,解密的结果将是无意义的,因此 - 要解释源代码的技术语言 - 无法适应填充方案。

1

来自密码学书籍

'PKCS1填充会将原始数据增加11个字节。'

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接