使用RSA加密字符串并将Java中的密钥包装到文件中

时间:2018-03-16 15:21:53

标签: java encryption

我试图加密两个不同文件中的某些信息,第一个用AES加密的字符串,第二个用RSA加密密钥,但我在使用它时遇到了一些麻烦。< / p>

这是我的方法:

public synchronized static void encrypToFile(KeyPair clauPublicaPrivada, SecretKey clauSecretaSimetrica) {
        String dades = null;
        byte[][] encWrappedData = new byte[2][];
        byte[] dadesAEncriptarEnByte;
        dades = extreureRutesDB();

        dadesAEncriptarEnByte = dades.getBytes();

        try {

            try {
                File file = new File(FITXER_DADES_TRIPULANTS_XIFRADES_AES128);
                File file2 = new File(FITXER_DADES_TRIPULANTS_XIFRADES_AES128_CLAUS);
                boolean fvar = file.createNewFile();
                boolean fvar2 = file2.createNewFile();
                if (fvar2) {
                    System.out.println("File2 has been created successfully");
                } else {
                    System.out.println("File2 already present at the specified location");
                }

                if (fvar) {
                    System.out.println("File1 has been created successfully");
                } else {
                    System.out.println("File1 already present at the specified location");
                }
            } catch (IOException e) {
                System.out.println("Exception Occurred:");
                e.printStackTrace();
            }


            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec(IV_PARAM);
            cipher.init(Cipher.ENCRYPT_MODE, clauSecretaSimetrica, iv);
            encWrappedData[0] = cipher.doFinal(dadesAEncriptarEnByte);

            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            PublicKey clauPublica = clauPublicaPrivada.getPublic();
            cipher.init(Cipher.WRAP_MODE, clauPublica);
            encWrappedData[1] = cipher.wrap(clauSecretaSimetrica);



            CipherOutputStream cos = new CipherOutputStream(new FileOutputStream(FITXER_DADES_TRIPULANTS_XIFRADES_AES128), cipher);
            cos.write(encWrappedData[0]);
            cos.close();

            cos = new CipherOutputStream(new FileOutputStream(FITXER_DADES_TRIPULANTS_XIFRADES_AES128_CLAUS), cipher);
            cos.write(encWrappedData[1]);
            cos.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            System.out.println("menu 21(): FINAL");
        }

    }

问题在于,当我运行它时,我收到此错误:

java.lang.IllegalStateException:未对加密/解密初始化密码

知道我做错了什么以及如何解决它?

2 个答案:

答案 0 :(得分:3)

为不同目的重用相同的Cipher变量是糟糕的编程习惯和混乱,并导致您遇到这些错误。您在致电cipher之前离开了WRAP_MODE中的doWrap()个实例。然后,您向CipherOutputStream构造函数提供相同的实例。这些要求cipher对象位于ENCRYPT_MODEDECRYPT_MODE

只需为Cipher对象的每个不同用途调用Cipher.getInstance()即可。除非你确实做了一些非常奇怪的事情(并且可能是错误的),否则这个电话的开销在你的节目中是微不足道的。

答案 1 :(得分:1)

您未正确使用CipherOutputStream值。确切地说,您的代码设置方式根本不需要使用 。这些输出流用于加密解密数据。

但是,在调用encWrappedData[0] = cipher.doFinal(dadesAEncriptarEnByte);encWrappedData[1] = cipher.wrap(clauSecretaSimetrica);时,数据已经加密。

因此,您只需使用FileOutputStream即可直接将这些调用的结果写入文件。

RSA包装的AES密钥的大小总是有限的,因此传输该信息没有意义。如果消息(dades)很大,您可能希望使用流式传输,并使用基于AES的密码实例来执行加密,而不将所有明文和密文都放在内存中的字节数组中。在这种情况下,CipherOutputStream可能有意义。