Java RSA 解密javax.crypto.IllegalBlockSizeException: 数据不能超过 256 字节

Java RSA decryption javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes

RSA解密小题Java请

我想在一个秘密地点与我的朋友见面。 由于我们不希望任何人窃听秘密位置,因此我生成了一个 RSA 密钥对、一个私钥和一个 public 密钥。请注意,我将两者都生成为字符串。

        String privateKeyString = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6cXloNrocJ8s[...]LABviZm5AFCQWfke4LZo5mOS10";
        String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB[...]EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4iGwIDAQAB";

然后我 public 分享了我的 public 密钥给我的朋友,他写了这个:

private static String encryptSecretLocation(String secretLocation) {
        try {
            String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB[...]EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4iGwIDAQAB"; //public key same as above
            byte[]             buffer          = Base64.getDecoder().decode(publicKeyString);
            KeyFactory         keyFactory      = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec         = new X509EncodedKeySpec(buffer);
            PublicKey          publicKey       = keyFactory.generatePublic(keySpec);
            Cipher             encryptCipher   = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] secretMessageBytes    = secretLocation.getBytes(StandardCharsets.UTF_8);
            byte[] encryptedMessageBytes = encryptCipher.doFinal(secretMessageBytes);
            return Base64.getEncoder().encodeToString(encryptedMessageBytes);
        } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
            return "bad location";
        }
    }

事实上,他设法得到了一些乱码,他把它发回给我了

"OixtTJRXe2nDRWDBqSs9m4wN[...]17/MKpw=="

通过一封漂亮的信:

Hey, meet me at (decrypt this)

"OixtTJRXe2nDRWDBqSs9m4wN[...]17/MKpw=="

I will wait for you there tomorrow at noon! Please come alone!

我有私钥,但没有与任何人分享,希望通过这段代码计算出秘密位置,这是我尝试过的。

 public static void main(String[] args) throws Exception {
        String privateKeyString = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6cXloNrocJ8s[...]LABviZm5AFCQWfke4LZo5mOS10";
        String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB[...]EatUOuyQMt2Vwx4uV+d/A3DP6PtMGBKpF8St4iGwIDAQAB";

        byte[]              buffer1       = Base64.getDecoder().decode(privateKeyString);
        PKCS8EncodedKeySpec keySpec1      = new PKCS8EncodedKeySpec(buffer1);
        KeyFactory          keyFactory1   = KeyFactory.getInstance("RSA");
        PrivateKey          privateKey    = (RSAPrivateKey) keyFactory1.generatePrivate(keySpec1);

        Cipher decryptCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);

        byte[] decryptedMessageBytes = decryptCipher.doFinal("OixtTJRXe2nDRWDBqSs9m4wN[...]17/MKpw==".getBytes(StandardCharsets.UTF_8));
        String decryptedMessage      = new String(decryptedMessageBytes, StandardCharsets.UTF_8);
        
        System.out.println(decryptedMessage);
    }

不幸的是,我得到的只是:

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
    at java.base/com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:347)
    at java.base/com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:392)
    at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)

请问这是什么问题,请问如何计算我们见面的秘密地点?

谢谢

P.S。试图让问题变得有趣,希望你喜欢它!

正如 Topaco 在解密时提到的(所有功劳归功于他),密文必须是 Base64 解码而不是 UTF8 编码:

在我的例子中,它是 UTF8 编码的。

``` Base64.getDecoder().decode("OixtTJRXe2nDRWDBqSs9m4wN[...]17/MKpw==") `` 有效。