java - 使用 DES 算法对 Java 中的文件进行加密和解密

标签 java security encryption cryptography

我正在尝试做一个练习,用 DES 算法加密 file.txt。我必须将生成的 key 保存在不带扩展名的文件中。我觉得这部分已经很好解决了。但我在使用相同的 key 解密加密文件时遇到了麻烦。我收到错误:“鉴于最终 block 未正确填充”。

练习: 1.加密程序:读取一个文本文件,使用DES算法对其进行加密,并将结果写入一个新文件,另一个文件中存储用于加密的 key 。 2.解密程序:读取加密 key 保存的程序,将加密程序保存的文本解密并显示在屏幕上。

注意:使用FileInputStream和FileOutputStream,以8字节为单位进行加密,以16字节为单位进行解密。

加密

import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class Encrypt {

    public static void main(String[] args) {

        try {
            SecretKey key = KeyGenerator.getInstance("DES").generateKey();

            FileOutputStream fosKey = new FileOutputStream("..\\KEY");
            SecretKeyFactory keyfac = SecretKeyFactory.getInstance("DES");
            DESKeySpec keyspec = (DESKeySpec) keyfac.getKeySpec(key, DESKeySpec.class);
            fosKey.write(keyspec.getKey());
            fosKey.close();

            Cipher crypt = Cipher.getInstance("DES");
            crypt.init(Cipher.ENCRYPT_MODE, key);

            FileInputStream fis = new FileInputStream("..\\File.txt");
            FileOutputStream fos = new FileOutputStream("..\\FileCrypted.txt");
            byte[] arrayBytes = new byte[8];
            int bytesReads;
            while ((bytesReads = fis.read(arrayBytes)) != -1) {
                fos.write(crypt.doFinal(arrayBytes), 0, bytesReads);
            }
            fis.close();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

解密

import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class Decrypt {

    public static void main(String[] args) {

        try {
            FileInputStream fisKey = new FileInputStream("..\\KEY");
            byte[] arrayKey = new byte[fisKey.available()];
            fisKey.read(arrayKey);
            SecretKey key = new SecretKeySpec(arrayKey, "DES");

            Cipher decrypt = Cipher.getInstance("DES");
            decrypt.init(Cipher.DECRYPT_MODE, key);

            FileInputStream fis = new FileInputStream("..\\FileCrypted.txt");
            byte[] encText = new byte[16];
            int bytesReads;
            while ((bytesReads = fis.read(encText)) != -1) {
                fis.read(decrypt.doFinal(encText), 0, bytesReads);
            }
            fis.close();
            System.out.println(new String(encText));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

最佳答案

您应该对中间加密调用使用 update() 方法,并且仅在最后一次调用时使用 doFinal() 。这适用于加密和解密。

DES - 在 ECB 或 CBC 模式下 - 始终使用 8 字节 的 block 大小(加密和解密)。如果填充处于 Activity 状态,则在执行doFinal()时,将附加附加数据(1-8字节)以确保 block 大小为8 >。如果密码上的填充未激活,则需要确保在执行 doFinal() 时提供的数据为 8 字节的倍数。

update() 允许您在不与 8 字节 block 大小对齐的情况下处理加密数据,因为它只是进行缓冲,直到拥有完整 block 的数据为止。 doFinal() 刷新缓冲区中可能存在的任何多余字节以进行加密,并应用任何可能有效的填充。

<小时/>

请注意,DES 不再被认为是安全的,因此不应将其用于任何严重的安全性。

关于java - 使用 DES 算法对 Java 中的文件进行加密和解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35182131/

相关文章:

java - 哈希表和ArrayList的时间复杂度

java - JBoss - 同一应用程序中的不同类加载系统 - 可能吗?

api - 如何安全地让我的用户使用刷新 token 登录?

java - 数据截断 : Data to long for column

video - 播放加密的视频

python - 密码保护 Python

java - Java 8 中删除了 JDBC-ODBC 桥,最好的替代方案是什么?

Java编码: why the output is always the same?

javascript - 在 Vuex 中存储敏感数据

asp.net - 隐藏密码输入字段的最简洁方法?