Java中使用私钥进行加密和解密

11

在我阅读了关于加密(对称和非对称)方法的文章后,很多文章都说私钥用于加密和解密数据,公钥用于加密数据。但当我尝试在Java中实现时,我无法使用私钥来加密和解密数据(我正在使用RSA算法)。如果可能,请提供一个链接。如果不支持,请回答为什么不支持?

//加密

Cipher encrypt=Cipher.getInstance("RSA");
encrypt.init(Cipher.ENCRYPT_MODE, privatekey);
byte[] encryptedMessage=encrypt.doFinal(msg.getBytes());

//解密

Cipher decrypt=Cipher.getInstance("RSA");
decrypt.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedMessage=decrypt.doFinal(encryptedMessage);
3个回答

19

要执行RSA加密,需要使用公钥进行加密,并使用私钥进行解密。此外,您应该使用明确定义的填充方法,例如PKCS#1 v1.5兼容填充或(如果有)OAEP填充。

使用RSA私钥进行加密没有任何意义,因为任何拥有公钥的人都可以解密。有一种称为"原始RSA"的方法,它基本上是模指数运算,但那应该只与另一种填充方案一起使用以生成签名。在这种情况下,您希望每个拥有公钥的人“解密”以验证签名。

更多信息在这里在这里

因此加密是:

// specify mode and padding instead of relying on defaults (use OAEP if available!)
Cipher encrypt=Cipher.getInstance("RSA/ECB/PKCS1Padding");
// init with the *public key*!
encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
// encrypt with known character encoding, you should probably use hybrid cryptography instead 
byte[] encryptedMessage = encrypt.doFinal(msg.getBytes(StandardCharsets.UTF_8));

解密是:

Cipher decrypt=Cipher.getInstance("RSA/ECB/PKCS1Padding");
decrypt.init(Cipher.DECRYPT_MODE, privateKey);
String decryptedMessage = new String(decrypt.doFinal(encryptedMessage), StandardCharsets.UTF_8);

1
加密签名不就是使用私钥进行加密吗? - Peter Becker
3
最好不要那样想。请查看RFC 3447第5.2部分:“……每个基元中的主要数学操作是指数运算,就像第5.1节的加密和解密基元中一样。 RSASP1和RSAVP1与RSADP和RSAEP相同,除了它们的输入和输出参数名称不同;它们之间有所区别,因为它们用于不同的目的。” 这仅适用于“教科书”或“原始”的RSA,这种方法不适合普通的加密目的。填充是方案的组成部分,不同于“教科书”或“原始”RSA。 - Maarten Bodewes
明白了。我曾经发现过一个破解的加密方案,其中使用了纯RSA(第一个问题),而且两个密钥被错误地使用了。Bouncy Castle允许你这样做,然后悄悄地改变填充方式,在这种情况下意味着加密没有随机化。 - Peter Becker

7

公钥私钥加密的工作原理:

  1. 如果您使用私钥加密某些内容,任何拥有您的公钥的人都可以解密它。
  2. 如果您使用公钥加密某些内容,只有您的私钥才能解密它。

您需要生成公私钥对。私钥只属于您,而公钥可以提供给您信任的人。

如何生成密钥对?

$ openssl genrsa -out private_key.pem 1024
$ openssl rsa -pubout -in private_key.pem -out public_key.pem

或者在这里使用Java完成 -> JAVA RSA 当你完成后回来继续问问题。


1
当你使用私钥进行加密时,称之为证书。您的公钥分发给客户端,以便他们可以打开并验证证书的发行者。同样,客户端可以通过使用公钥创建自己的签名。同样,服务器/发行者可以通过使用私钥解密它来验证它。
S:私钥 P:公钥
S + 数据 = 证书 => 客户端(使用公钥打开/验证) P + 数据 = 签名 => 服务器/发行者(使用私钥打开/验证)

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