【问题标题】:Java File EncryptionJava 文件加密
【发布时间】:2013-06-04 07:01:25
【问题描述】:

我正在尝试编写一个简单的程序来使用 AES 算法加密和解密文件。我对加密没有问题,但解密..

public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {

    // Инициализация секретных ключей
    KeyGenerator keyGenS = KeyGenerator.getInstance("AES");
    keyGenS.init(128);
    SecretKey sKey1 = keyGenS.generateKey();
    SecretKey sKey2 = keyGenS.generateKey();
    // Перевод секретных ключей в строку и запись в файл
    String key1 = SecretKeyToString(sKey1);
    String key2 = SecretKeyToString(sKey2);

    spreader.write(fileName1, key1);
    spreader.write(fileName2, key2);
    spreader.write(fileNameS1, key1);
    spreader.write(fileNameS2, key2);


    // Чтение секретных ключей из файла и перевод обратно в тип SecretKey
    key1 = spreader.read(fileName1);
    System.out.println("Секретный ключ 1го пользователя: " +key1);


    SecretKey seansKey1=getKeyInstance(key1);

    key2 = spreader.read(fileName2);
    System.out.println("Секретный ключ 2го пользователя: " +key2);

    SecretKey seansKey2=getKeyInstance(key2);


    //инициализация и зашифрование сеансового ключа с помощью секретных
    Cipher aesCipher = Cipher.getInstance("AES");
    aesCipher.init(Cipher.ENCRYPT_MODE,seansKey1);

    KeyGenerator keyGen = KeyGenerator.getInstance("AES");
    keyGen.init(128);
    SecretKey secretKey = keyGen.generateKey();

    String stringsecretKey = SecretKeyToString(secretKey);
    byte[] byteKey = stringsecretKey.getBytes();
    byte[] byteCipherKey1 = aesCipher.doFinal(byteKey); 
    String encryptedKey = new BASE64Encoder().encode(byteCipherKey1);
    System.out.println("Зашифрованный сеансовый ключ с помощью секретного ключа 1: " +encryptedKey);





    aesCipher = Cipher.getInstance("AES");
    aesCipher.init(Cipher.ENCRYPT_MODE,SeansKey2);


     byteKey = etringsecretKey.getBytes();
     byte[] byteCipherKey2 = aesCipher.doFinal(byteKey); 
     encryptedKey = new BASE64Encoder().encode(byteCipherKey2);
    System.out.println("Зашифрованный сеансовый ключ с помощью секретного ключа 2: " +encryptedKey);
    spreader.write(fileNameEK2, encryptedKey);

    //Чтение данных из файла
    String text =spreader.read(fileName);
    System.out.println(text);

    // Зашифрование данных


            aesCipher.init(Cipher.ENCRYPT_MODE,secretKey); // константная переменная

            byte[] byteText = text.getBytes();
            byte[] byteCipherText = aesCipher.doFinal(byteText); 
            encryptedText = new BASE64Encoder().encode(byteCipherText);
            System.out.println("Зашифрованный текст: " +encryptedText);

            spreader.write(fileNameOK, encryptedText);





}

下面是解密部分:

public static void main(String[] args) throws NoSuchAlgorithmException, FileNotFoundException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException {

    String encryptedText = user.read(fileNameOK);
    String key1 = user.read(fileName1);
    String key2 = user.read(fileName2);
    String encryptedSeanceKey1 = user.read(fileNameEK1);
    String encryptedSeanceKey2 = user.read(fileNameEK2);




    SecretKey secretKey1=getKeyInstance(key1);
    SecretKey secretKey2=getKeyInstance(key2);



    Cipher aesCipher = Cipher.getInstance("AES");
    aesCipher.init(Cipher.DECRYPT_MODE,secretKey1,aesCipher.getParameters());




    //byte[] byteKey = encryptedSeanceKey1.getBytes();

       byte[] byteDecryptedKey = aesCipher.doFinal(encryptedSeanceKey1.getBytes());
       String decryptedKey1 = new String(byteDecryptedKey);
       System.out.println("Расшифрованный сеансовый ключ с помощью секретного ключа 1: " +decryptedKey1);

    aesCipher.init(Cipher.DECRYPT_MODE,secretKey2,aesCipher.getParameters());




    byte[] byteKey2 = encryptedSeanceKey2.getBytes();
        byteDecryptedKey = aesCipher.doFinal(byteKey2); 
        String decryptedKey2 = new String(byteDecryptedKey);
       System.out.println("Расшифрованный сеансовый ключ с помощью секретного ключа 2: " +decryptedKey2);





        // Расшифрование данных
        aesCipher.init(Cipher.DECRYPT_MODE,getKeyInstance(decryptedKey1),aesCipher.getParameters());

         byte[] byteText = encryptedText.getBytes();

        byte[] byteDecryptedText = aesCipher.doFinal(byteText);
        decryptedText = new String(byteDecryptedText);
        System.out.println(" Расшифрованный текст " +decryptedText);



}

}

现在的问题是解密部分是:使用填充密码解密时,输入长度必须是 16 的倍数

我知道我错误地保留了会话密钥和字节丢失。但是我该如何正确地做到这一点呢?

【问题讨论】:

  • 您能遵守 Java 命名约定吗?也就是说,变量名和方法名应该以小写字母开头(SKey1 应该是sKey1,仅引用第一个示例)。这将使 SO 更容易突出显示文本,最终让 SO 经验丰富的 Java 开发人员更容易提供帮助 ;)
  • 谢谢。我是 Java 初学者,因此我要求不要严格评判我。

标签: java encryption cryptoapi


【解决方案1】:

您的代码中有一点混乱,可能是因为您调用的某些方法丢失了,或者可能是因为您正在使用您的密钥来加密...您的密钥(!!!)
让我们尝试加密和解密简单的方法,删除代码中不需要的所有内容(例如对密钥进行编码并将其保存到文件中,然后在不解码的情况下恢复密钥等)。

让我们根据你的来看看下面的简化代码:

    KeyGenerator keyGenS = KeyGenerator.getInstance("AES");
    keyGenS.init(128);
    SecretKey sKey1 = keyGenS.generateKey();

    Cipher aesCipher = Cipher.getInstance("AES");
    aesCipher.init(Cipher.ENCRYPT_MODE,sKey1);

    byte[] byteText = "Insert here whatever you want to crypt".getBytes();

    byte[] byteCipherText = aesCipher.doFinal(byteText);

我们已经使用 KeyGenerator 生成了我们的密钥,然后我们使用该密钥初始化了我们的 Cipher 实例。此时我们只需调用doFinal() 传递我们要加密的纯文本。
这就是加密部分的全部内容。当然,如果您愿意,您可以将您的密钥和byteCipherText 保存到一个文件中,但所有其他员工(至少)都是无用的。

解密部分和加密一样简单。逻辑是一样的。 如果您将密钥保存在文件中,只需将其读入byte[],然后使用它来初始化您的密码实例。像这样的:

    aesCipher.init(Cipher.DECRYPT_MODE, sKey1);
    byte[] plainText = aesCipher.doFinal(byteCipherText);

如果您将上述所有代码放入main() 并运行它,您应该在plainText 中输入与byteText 中相同的文本。
您可以使用

进行验证
    System.out.println(new String(plainText));

尝试从这里开始,然后添加您可能需要的所有其他内容。
希望这会有所帮助。
问候

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    • 2012-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2020-01-20
    相关资源
    最近更新 更多