Java 实现图片的加密和解密的两种方式

今天我们将探讨一个有趣且实用的主题:如何在Java中实现图片的加密和解密?图片加密就像是给图片穿上一件隐身斗篷,让它们的内容只有授权的人能够看到。解密则是解开这层隐身斗篷,让图片恢复原貌。在这篇文章中,我们将介绍两种Java实现图片加密和解密的方法,帮助你了解如何保护和访问你的图片数据。

直接上图

当我们进行加密后本地访问显示

解密后图片恢复原貌

下面将介绍两种方式进行图片的加密解密,异或加密和AES对称加密

一:异或加密 

优点:

  1. 简单性

    异或运算是一种非常简单的位运算,实现起来非常直观和容易理解。这使得代码实现简单,并且不需要复杂的数学或密码学知识。
  2. 速度

    异或运算是计算机中的基本运算,执行速度非常快。对于大文件或大量数据的加密,异或运算通常比复杂的加密算法(如AES)更快。

缺点:

  1. 安全性

    异或加密的安全性较低。由于其简单性,异或加密容易受到已知明文攻击(Known-plaintext attack)和已知密文攻击(Chosen-plaintext attack)的影响。攻击者可以通过观察加密前后的数据来推断出密钥。
  2. 密钥长度

    异或加密的密钥长度通常与待加密数据的字节长度相同,或者为一个较短的常数值。这种密钥长度的限制可能会限制加密的安全性,因为密钥空间较小,容易受到穷举攻击。
  3. 数据模式依赖性

    异或加密对数据的变化敏感。如果待加密的数据有重复性或者特定的数据模式,可能导致加密后的结果也具有一定的模式性,这样会降低加密的效果和安全性。例一个数字异或本身为0(4947894947984 ^ 4947894947984 = 0)
  4. 不适合长期加密

    异或加密通常不适合长期加密需求,尤其是对于敏感数据和长期存储的数据。由于其安全性相对较低,推荐使用更为复杂和安全的加密算法(如AES)来保护长期存储的数据。
public class PictureCopy {
    public static void main(String[] args) {
        // 使用 try-with-resources 自动关闭资源
        try (FileInputStream fis = new FileInputStream("D:\\picture\\fengjing.jpg");
             FileOutputStream fos = new FileOutputStream("D:\\picture\\fengjing_copy.jpg")) {

            // 缓冲区大小
            byte[] buffer = new byte[8192];
            int bytesRead;

            // 读取和写入文件
            while ((bytesRead = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }

            System.out.println("图片复制完成。");

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

解密

public class PictureCopyEncryption {
    public static void main(String[] args) {
        // 定义输入输出流变量
        try (FileInputStream fis = new FileInputStream("D:\\picture\\fengjing_jiami.jpg");
             FileOutputStream fos = new FileOutputStream("D:\\picture\\fengjing_jiemi.jpg")) {

            // 缓冲区大小
            byte[] buffer = new byte[8192];
            int bytesRead;

            // 读取和解密文件
            while ((bytesRead = fis.read(buffer)) != -1) {
                // 解密操作,每个字节与5异或
                for (int i = 0; i < bytesRead; i++) {
                    buffer[i] = (byte) (buffer[i] ^ 5);
                }
                // 写入解密后的数据
                fos.write(buffer, 0, bytesRead);
            }

            System.out.println("图片解密完成。");

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

二:AES对称加密

优点:

  1. 安全性高

    AES被广泛认为是安全性很高的加密算法之一。它使用128位、192位或256位的密钥长度,这使得穷举攻击(Brute-force attack)变得非常困难。
  2. 效率高

    AES在各种计算机和设备上的加密和解密速度都很快,能够处理大量的数据。
  3. 广泛支持

    AES是一种公认的标准加密算法,得到了广泛的支持和实现。几乎所有的操作系统、编程语言和加密库都支持AES。
  4. 可扩展性

    AES支持多种密钥长度(128位、192位、256位),可以根据安全需求选择不同的密钥长度。
  5. 抗攻击能力强

    AES经过多次严格的密码学分析和公开审查,抵抗了各种已知的攻击方式,包括线性和差分密码分析。
  6. 适用于各种应用场景

    由于其高安全性和效率,AES广泛用于保护网络通信、存储数据、加密文件等多种应用场景。

缺点:

  1. 密钥管理

    AES作为对称加密算法,密钥的生成、分发和管理非常重要。长期使用相同的密钥可能会增加被破解的风险,因此密钥管理是使用AES时需要特别关注的问题
  2. 不适合公钥加密

    AES是一种对称加密算法,加密和解密使用相同的密钥。在某些场景下,特别是需要公钥加密的情况下,需要结合其他的公钥加密算法(如RSA)来进行密钥交换和加密操作。
  3. 不适用于流式加密

    AES是块加密算法,每次处理一块固定大小的数据(128位)。对于流式数据的加密,需要额外的处理以确保数据完整性和安全性。
  4. 硬件实现的安全隐患

    AES在硬件上的实现可能会存在侧信道攻击(side-channel attack)的风险,例如时钟信号分析或功耗分析等。
public class ImageEncryption {

    private static final String ALGORITHM = "AES";

    public static void main(String[] args) throws Exception {

        String inputFile = "D:\\picture\\fengjing.jpg";
        String encryptedFile = "D:\\picture\\encrypted_fengjing.jpg";

        // 生成固定密钥
        SecretKey key = generateKey();

        // 加密图片
        encryptImage(inputFile, encryptedFile, key);

        System.out.println("图片加密完成。");
    }

    // 生成AES密钥
    private static SecretKey generateKey() throws Exception {
        // 这里简单示例,实际应用中密钥管理应更加安全
        byte[] keyBytes = "MySecretKey12345".getBytes(); // 使用固定的字节数组作为密钥
        return new SecretKeySpec(keyBytes, ALGORITHM);
    }

    // 加密图片方法
    public static void encryptImage(String inputFile, String outputFile, Key key) throws Exception {
        // 创建 Cipher 实例并初始化为加密模式
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);

        // 输入输出流
        FileInputStream fis = new FileInputStream(inputFile);
        FileOutputStream fos = new FileOutputStream(outputFile);
        CipherOutputStream cos = new CipherOutputStream(fos, cipher);

        // 读取输入文件并加密后写入输出文件
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = fis.read(buffer)) != -1) {
            cos.write(buffer, 0, bytesRead);
        }

        // 关闭流
        cos.close();
        fis.close();
    }
}

解密

public class ImageDecryption {

    private static final String ALGORITHM = "AES";

    public static void main(String[] args) throws Exception {
        String encryptedFile = "D:\\picture\\encrypted_fengjing.jpg";
        String decryptedFile = "D:\\picture\\decrypted_fengjing.jpg";


        // 使用相同的固定密钥进行解密
        SecretKey key = generateKey();

        // 解密图片
        decryptImage(encryptedFile, decryptedFile, key);

        System.out.println("图片解密完成。");
    }

    // 生成AES密钥
    private static SecretKey generateKey() throws Exception {
        // 这里简单示例,实际应用中密钥管理应更加安全
        byte[] keyBytes = "MySecretKey12345".getBytes(); // 使用固定的字节数组作为密钥
        return new SecretKeySpec(keyBytes, ALGORITHM);
    }

    // 解密图片方法
    public static void decryptImage(String inputFile, String outputFile, Key key) throws Exception {
        // 创建 Cipher 实例并初始化为解密模式
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);

        // 输入输出流
        FileInputStream fis = new FileInputStream(inputFile);
        FileOutputStream fos = new FileOutputStream(outputFile);
        CipherOutputStream cos = new CipherOutputStream(fos, cipher);

        // 读取输入文件并解密后写入输出文件
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = fis.read(buffer)) != -1) {
            cos.write(buffer, 0, bytesRead);
        }

        // 关闭流
        cos.close();
        fis.close();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值