【问题标题】:Encrypt and decrypt large string in java using RSA [closed]使用RSA加密和解密java中的大字符串[关闭]
【发布时间】:2012-11-21 19:09:43
【问题描述】:

我正在尝试实施 PKI。我想在不使用充气城堡的情况下在 java 中使用 RSA 加密大字符串。我得到的问题是数据不能超过 117 个字节。我尝试寻找失败的解决方案。我是这个加密的新手。请以一个大字符串为例帮助我并解释一下。

【问题讨论】:

  • 安全性,尤其是密码学,是困难。您应该使用现有的高级软件包而不是原始加密 API,或者了解它们如何工作的详细信息。否则,您可能会编写不安全的代码。
  • 请发布您的代码。我们可以在那里工作。
  • 不要直接使用 RSA 加密数据。生成随机 AES 密钥,使用 AES 加密数据,使用 RSA 加密 AES 密钥。
  • RSA只是加密小数据,加密用于加密数据的密钥?

标签: java encryption rsa


【解决方案1】:

您一次不能对超过 128 个字节使用 RSA 加密解密。您必须拆分数据并在循环中执行它,几乎随时将字节写入字符串/数组。如果您唯一的问题是数据的大小,那么您可能没有更多工作要做。只是拆分数据。

一个很好的例子,对你来说可能更完整,处理大于 128 字节的字符串:http://www.stellarbuild.com/blog/article/encrypting-and-decrypting-large-data-using-java-and-rsa

如果您需要更多关于 RSA 加密的一般说明:

以下代码演示了如何使用 KeyPairGenerator 在 Java 中生成 RSA 密钥对:

// Get an instance of the RSA key generator
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
// Generate the keys — might take sometime on slow computers
KeyPair myPair = kpg.generateKeyPair();

这将为您提供一个 KeyPair 对象,其中包含两个密钥:一个私有密钥和一个公共密钥。为了使用这些密钥,您需要创建一个 Cipher 对象,该对象将与 SealedObject 结合使用来加密您将通过网络结束的数据。这样做的方法如下:

// Get an instance of the Cipher for RSA encryption/decryption
Cipher c = Cipher.getInstance("RSA");
// Initiate the Cipher, telling it that it is going to Encrypt, giving it the public key
c.init(Cipher.ENCRYPT_MODE, myPair.getPublic()); 

初始化密码后,我们就可以加密数据了。由于加密后的结果数据如果你看到它们“裸露”将没有多大意义,我们必须将它们封装在另一个对象中。 Java 通过 SealedObject 类提供了这一点。 SealedObjects 是加密对象的容器,它们在 Cipher 对象的帮助下对其内容进行加密和解密。

以下示例显示了如何创建和加密 SealedObject 的内容:

// Create a secret message
String myMessage = new String("Secret Message");
// Encrypt that message using a new SealedObject and the Cipher we created before
SealedObject myEncryptedMessage= new SealedObject( myMessage, c);

生成的对象可以通过网络发送而不必担心,因为它是加密的。唯一可以解密和获取数据的人是持有私钥的人。通常,这应该是服务器。为了解密消息,我们需要重新初始化 Cipher 对象,但这次使用不同的模式,解密并使用私钥而不是公钥。

这就是你在 Java 中的做法:

// Get an instance of the Cipher for RSA encryption/decryption
Cipher dec = Cipher.getInstance("RSA");
// Initiate the Cipher, telling it that it is going to Decrypt, giving it the private key
dec.init(Cipher.DECRYPT_MODE, myPair.getPrivate());

现在 Cipher 已准备好解密,我们必须告诉 SealedObject 解密保存的数据。

// Tell the SealedObject we created before to decrypt the data and return it
String message = (String) myEncryptedMessage.getObject(dec);
System.out.println("foo = "+message);

使用 getObject 方法时要小心,因为它返回一个 Object 的实例(即使它实际上是 String 的一个实例),而不是它在加密之前的 Class 的实例,所以你必须强制转换将其还原为以前的形式。

【讨论】:

  • 链接已失效。
  • 我选择将消息分成 100 个字节的部分,我做错了吗?
  • 在最好的情况下,将消息分成块并尝试像分组密码一样应用 RSA效率极低。在最坏的情况下,不安全:因为这是非常规的,没有人费心研究这种模式引入了哪些漏洞。例如,在某些模式中使用像 AES 这样的实际分组密码,为加密方案提供不同的属性。谁能说一下这个自制的 RSA 模式有什么属性。
  • @GML-VS 谢谢!将更新帖子。
【解决方案2】:

RSA 不适用于批量数据加密。相反,请使用对称密码(如 AES)来加密您的“大字符串”。然后,使用 RSA 密钥加密用于 AES 的对称密钥。

BouncyCastle 支持两种协议来执行此操作:S/MIME 和 PGP。所有明智的隐私协议都以这种方式使用非对称算法进行密钥传输或密钥交换。

可以使用 RSA 加密的消息大小取决于密钥的模数,减去安全填充消息所需的一些字节。

【讨论】:

  • 这样的混合加密是可行的方法。
  • 代码示例或相关 API 的链接不会受到影响。
  • 一个足够简单的 StackOverflow 答案示例将被盲目复制和使用,而无需了解获得真正安全所需的所有问题。公钥消息加密最好使用广泛使用且维护良好的库来实现。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2018-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多