用公钥解密?



我在用Java写程序时犯了一个错误。

package cf.huzpsb.jnip.security;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class Cipher {
private static final byte[] pub = Base64.getDecoder().decode("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUjb+/Ea3i9W53tASAu5OJ8vxf7+7oGberM5B6GIfu2uBMD0YfaQuGqInREop6kho7AHYd4oCq68fhQ4DbAtE+RSy9Us4sCMpvvE4luLWoR3iZQtii7hyIoDSeXGaNVu6L3xbjFji7kSDPpWubdCuD6dCVYD5kS2N07m74d5grOwIDAQAB");
private static final byte[] pri = Base64.getDecoder().decode("MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJSNv78RreL1bne0BIC7k4ny/F/v7ugZt6szkHoYh+7a4EwPRh9pC4aoidESinqSGjsAdh3igKrrx+FDgNsC0T5FLL1SziwIym+8TiW4tahHeJlC2KLuHIigNJ5cZo1W7ovfFuMWOLuRIM+la5t0K4Pp0JVgPmRLY3Tubvh3mCs7AgMBAAECgYAPimSs0GSogZR04Vg3P2hH3iuYvbj4fvg/6L0MiNRvoGYmjtJ/JrYV+Duyq4XhHLexxHKW3cMoHlJitnUcdEb/W5L0iOSXRN4W1WGBkGLv+FE3TbFT0ruxbLTdcK+cmiE6hWh2sO9xVXjIPxixuTrDvd7qyO0XyX0aNUU0/42FQQJBANwpKF6ZJRIHvF32RIfPjAxkTEY6Mq8IbxeuxsbN3IJ1aywK3bQdSxz0rd+b/gR/3CJhjp9OUGt0KqYm6emVJrcCQQCsvHu30wrK8qfjQmlVxYlwgVitb3u+pgRPO64neuucsbXPUEYnB/Ae9Y1QrdRUBWInhWfXpRK7m4LzK0udJvudAkEArWU9BkRXjfvJv7dWAiDUjG3yJN1xTam21VAx/iHkqlsQLX/hXRo1LnkG+DZDugd5uRpc2ds0O20iqfm8ANwXwQJBAIVagdy5lfR1/zzIkY+BEAkGIpLKpWrauir9NQcPs4PmAilJnM8XJr6P7YgimvA+s7c1G6T0sJCbjy3x988cQFUCQBnPIMFNyfz+t9Cg+gA42ivbKQC9OnIpTD0Jsm8gyvh1C15Pkb4I0WYOQuh66AWHwrlqlkF6IdUVyM8JlNArI/M=");
public static String encrypt(String text) {
try {
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(pri);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, privateKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(text.getBytes()));
} catch (Exception e) {
return "Failed";
}
}
public static String decrypt(String text) {
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pub);
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, pubKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(text)));
} catch (Exception e) {
return "Failed";
}
}
}

正如您所看到的,我在试图加密/解密数据时使用了错误的密钥。然而,代码没有产生任何异常。

如果我编译并运行:

String str = Cipher.encrypt("uwu");
System.out.println(str);
System.out.println(Cipher.decrypt(str));

控制台将显示:

GrKyCCML73yuJN/fsdevN00eOvWUDl7MTpW50iWhhnhqhMxelWPEQ4I2A7PPd0G8flVaZrabAIsYNNUBpEg96x+8zj3ZTh5u9rXbhJKbzHXSMbsuPCY39WqUOf6qqqWRxGL44E3ltIdE/wQr7XeRvqJa4Z089mSxl6VYB468BnA=
uwu

虽然我已经修正了错误,但我仍然有一个问题:

这是怎么回事?为什么它看起来运行"正常"?

编辑:

我见过一些人可能会说这是一种"符号"。但如果是这样的话,有没有一种方法可以让我不需要任何密钥就能读取数据,如果我不在乎数据是否被篡改?为什么或者为什么不呢?谢谢!

尝试使用带有私钥的RSA加密数据是没有意义的。然而,当尝试这样做时,Cipher类并没有抛出异常,而是做了一些不同的事情。它假设您想要执行签名操作,并且您只提供签名的有效负载部分。然后,它将PKCS1填充字符串直接应用于您的数据,在这种情况下,填充是0x00 0x01,然后是尽可能多的0xff 0xff…0xff 0x00字节根据需要填充RSA块的长度(在本例中为128字节),应用带有私有指数的求幂原语。因此,填充的内容在十六进制中看起来像这样:

0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00757775

正确的PKCS1签名需要对数据进行散列,然后封装到DigestInfo ASN.1结构中,但Cipher不这样做。但是Signature类会这样做。

只能使用正确的公钥验证(或"解密")结果。除非你有公钥,否则你无法获得明文。

最新更新