有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

加密Java RSA解密

我解密一些文本时遇到问题

public class mainClass {

    private static Cipher cipher;

    private static KeyPairGenerator keyGen;
    private static KeyPair pair;
    private static PrivateKey privateKey;
    private static PublicKey publicKey;

    public static void createKeys() {
        pair = keyGen.generateKeyPair();
        privateKey = pair.getPrivate();
        publicKey = pair.getPublic();
    }

    public static String encryptText(String msg)
            throws NoSuchAlgorithmException, NoSuchPaddingException,
            UnsupportedEncodingException, IllegalBlockSizeException,
            BadPaddingException, InvalidKeyException {
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return Base64.getEncoder().encodeToString((cipher.doFinal(msg.getBytes("UTF-8"))));
    }

    public static String decryptText(String msg)
            throws InvalidKeyException, UnsupportedEncodingException,
            IllegalBlockSizeException, BadPaddingException {

        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return new String(cipher.doFinal(Base64.getDecoder().decode(msg)), "UTF-8");
    }

    public static void main(String args[]) throws Exception {
        int keylength = 1024;

        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

        keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(keylength, random);
        cipher = Cipher.getInstance("RSA");
        createKeys();

        FileInputStream f = new FileInputStream("C:\\Users\\caleb.baker\\Downloads\\test100k.db");
        byte[] b = new byte[f.available()];
        int offset = 0;
        String asf = "";
        f.read(b);
        String test = new String(b);
        for (int x = 0; x < b.length; x += 117) {
            try {
                asf += encryptText(test.substring(x, x + 117));
            } catch (StringIndexOutOfBoundsException e) {
                asf += encryptText(test.substring(x));
            }
        }
        String t = asf;
        asf = "";
        for (int x = 0; x < t.length(); x += 117) {
            System.out.println("run");
            try {
                asf += decryptText(test.substring(x, x + 117));
            } catch (StringIndexOutOfBoundsException e) {
                asf += decryptText(test.substring(x));
            }
        }
    }
}

我得到的错误是 线程“main”中出现异常

java.lang.IllegalArgumentException: Last unit does not have enough valid bits

at java.util.Base64$Decoder.decode0(Unknown Source)

at java.util.Base64$Decoder.decode(Unknown Source)

at java.util.Base64$Decoder.decode(Unknown Source)

at mainClass.decryptText(mainClass.java:60)

at mainClass.main(mainClass.java:162)

我对加密相当陌生。对称AES工作得很好,我知道它速度更快,但出于我自己的好奇心,我想给RSA计时。我将得到的另一个错误是错误的填充异常。我已经做了一些工作,但我认为这可能在我的代码中的某个地方等待着我

此外,加密工作正常。我没有检查它是否正确,但我确实打印了长度,以确保字符串足够长。用于解密的循环从未通过第一个循环


共 (1) 个答案

  1. # 1 楼答案

    您的程序存在多个问题

    • 如前所述,使用了错误的密钥(私钥用于解密,公钥用于加密)

    • RSA仅用于加密有限数量的数据,而不是任何长度的文本。可以这样使用,但在某些情况下可能不安全

    • Last unit does not have enough valid bits表示base64编码的值无效。解码base64意味着将4字节的6位编码转换为3字节的8位编码。因此,解码部分的长度必须是4的乘法器(1177不是),这与加密循环的长度相同,只是连接多个base64字符串并不一定会产生有效的b64值

    • 我不明白程序中循环的目的。,不管它有多复杂,你都应该保持简单。你想达到什么目的

    • Another error I will get is a bad padding exception.RSA(默认密码RSA/ECB/pkcs1padding)向要加密的值添加填充。因此,您不能只获取任何值并对其进行解密,否则填充将无效(这发生在具有某些子字符串的循环中)

    不久前我写了一篇blog about encryption in Java你可能会从中得到一些启发