加密与安全_解密AES加密中的IV和Seed

news2024/11/27 22:32:20

文章目录

  • 概述
    • IV(Initialization Vector,初始化向量)
    • Seed(种子)
  • Code
    • seed
    • IV
  • 小结

在这里插入图片描述


概述

在AES加密中,**IV(Initialization Vector,初始化向量)Seed(种子)**是两个不同的概念,尽管它们都涉及到随机性和加密安全性,但用途和作用有所不同。

IV(Initialization Vector,初始化向量)

  • 用途:IV 是在加密块模式(如 CBC, CFB, OFB, 等)中使用的一个随机或伪随机的输入值。它确保相同的明文在加密时产生不同的密文,从而增强了加密的安全性。
  • 特点
    • IV 通常是一个固定长度的随机数,长度与加密算法的块大小相同(例如,对于AES,IV长度为128位,即16字节)。
    • 在加密过程中,IV 通常与明文的第一个块进行某种形式的操作(如异或)来产生第一个加密块。后续块则依赖于前一个加密块。
    • IV 不需要保密,但要确保每次加密都不相同,以防止模式分析攻击。

Seed(种子)

  • 用途:Seed 通常用于生成随机数或伪随机数。在加密算法中,随机数生成器需要一个初始值,Seed 用来设置这个初始状态,以便生成一系列的伪随机数。
  • 特点
    • Seed 可以是一个任意长度的数值,用于初始化随机数生成器(如在密钥生成、随机填充、生成IV等场景中使用)。
    • 使用相同的 Seed 初始化同一个随机数生成器,将生成相同的伪随机数序列。因此,Seed 的选取应尽量多样化和随机化,以避免生成可预测的随机数序列。

Code

seed


import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.UUID;

/**
 * AES 对称性加密
 * <p>
 * 需要依赖 Apache Commons Codec
 *
 * @author artisan
 */
public class AesUtil {

    /**
     * 加密算法类型
     */
    static final String ALGORITHM_KEY = "AES";

    /**
     * 算法长度
     */
    private static final int KEY_SIZE = 128;


    /**
     * 生成一个种子字符串
     * 该方法通过生成一个唯一标识符(UUID)来创建一个唯一的种子字符串
     * 使用UUID可以确保生成的种子在一定范围内具有唯一性
     *
     * @return 返回一个UUID作为种子字符串
     */
    public static String generateSeed() {
        return UUID.randomUUID().toString();
    }


    /**
     * 使用 种子(密码)、模式 创建密码加密
     *
     * @param seed 种子(密码)
     * @param mode 模式,加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}
     * @return 返回 密码加密
     * @throws NoSuchAlgorithmException 算法类型异常
     * @throws NoSuchPaddingException   算法填充异常
     * @throws InvalidKeyException      无效的密钥异常
     */
    public static Cipher cipher(String seed, int mode) throws NoSuchAlgorithmException,
            NoSuchPaddingException, InvalidKeyException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM_KEY);
        byte[] seedBytes = seed.getBytes();
        keyGenerator.init(KEY_SIZE, new SecureRandom(seedBytes));
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] encodedBytes = secretKey.getEncoded();
        SecretKeySpec secretKeySpec = new SecretKeySpec(encodedBytes, ALGORITHM_KEY);
        Cipher cipher = Cipher.getInstance(ALGORITHM_KEY);
        cipher.init(mode, secretKeySpec);
        return cipher;
    }

    /**
     * 使用 种子(密码)将内容 加密
     *
     * @param originalText 原文
     * @param seed         种子(密码)
     * @return 返回 加密结果
     * @throws NoSuchAlgorithmException  算法类型异常
     * @throws NoSuchPaddingException    算法填充异常
     * @throws InvalidKeyException       无效的密钥异常
     * @throws BadPaddingException       错误填充异常
     * @throws IllegalBlockSizeException 非法的块大小异常
     */
    public static byte[] encrypt(byte[] originalText, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher = cipher(seed, Cipher.ENCRYPT_MODE);
        return cipher.doFinal(originalText);
    }

    /**
     * 使用 种子(密码)将内容 加密
     *
     * @param originalText 原文
     * @param seed         种子(密码)
     * @return 返回 加密结果
     * @throws NoSuchAlgorithmException  算法类型异常
     * @throws NoSuchPaddingException    算法填充异常
     * @throws InvalidKeyException       无效的密钥异常
     * @throws BadPaddingException       错误填充异常
     * @throws IllegalBlockSizeException 非法的块大小异常
     */
    public static byte[] encrypt(String originalText, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        return encrypt(originalText.getBytes(), seed);
    }

    /**
     * 使用 种子(密码)将内容 加密
     *
     * @param originalText 原文
     * @param seed         种子(密码)
     * @return 返回 加密结果
     * @throws NoSuchAlgorithmException  算法类型异常
     * @throws NoSuchPaddingException    算法填充异常
     * @throws InvalidKeyException       无效的密钥异常
     * @throws BadPaddingException       错误填充异常
     * @throws IllegalBlockSizeException 非法的块大小异常
     */
    public static String encryptStr(String originalText, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] encryptBytes = encrypt(originalText.getBytes(), seed);
        return Hex.encodeHexString(encryptBytes);
    }

    /**
     * 使用 种子(密码)将内容 解密
     *
     * @param cipherText 密文
     * @param seed       种子(密码)
     * @return 返回 解密原文
     * @throws NoSuchAlgorithmException  算法类型异常
     * @throws NoSuchPaddingException    算法填充异常
     * @throws InvalidKeyException       无效的密钥异常
     * @throws BadPaddingException       错误填充异常
     * @throws IllegalBlockSizeException 非法的块大小异常
     */
    public static byte[] decrypt(byte[] cipherText, String seed) throws NoSuchAlgorithmException, BadPaddingException,
            IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException {
        Cipher cipher = cipher(seed, Cipher.DECRYPT_MODE);
        return cipher.doFinal(cipherText);
    }

    /**
     * 使用 种子(密码)将内容 解密
     *
     * @param cipherText 密文
     * @param seed       种子(密码)
     * @return 返回 解密原文
     * @throws NoSuchAlgorithmException  算法类型异常
     * @throws NoSuchPaddingException    算法填充异常
     * @throws InvalidKeyException       无效的密钥异常
     * @throws BadPaddingException       错误填充异常
     * @throws IllegalBlockSizeException 非法的块大小异常
     * @throws DecoderException          解码器异常
     */
    public static byte[] decrypt(String cipherText, String seed) throws NoSuchAlgorithmException, BadPaddingException,
            IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, DecoderException {
        byte[] contentBytes = Hex.decodeHex(cipherText);
        return decrypt(contentBytes, seed);
    }

    /**
     * 使用 种子(密码)将内容 解密
     *
     * @param cipherText 密文
     * @param seed       种子(密码)
     * @return 返回 解密原文
     * @throws NoSuchAlgorithmException  算法类型异常
     * @throws NoSuchPaddingException    算法填充异常
     * @throws InvalidKeyException       无效的密钥异常
     * @throws BadPaddingException       错误填充异常
     * @throws IllegalBlockSizeException 非法的块大小异常
     * @throws DecoderException          解码器异常
     */
    public static String decryptStr(String cipherText, String seed) throws NoSuchAlgorithmException, BadPaddingException,
            IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, DecoderException {
        byte[] decryptFrom = Hex.decodeHex(cipherText);
        byte[] decryptBytes = decrypt(decryptFrom, seed);
        return new String(decryptBytes);
    }

}

测试代码


import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.junit.jupiter.api.Test;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * AES 对称加密 测试类
 *
 * @author artisan 
 */
public class AesUtils {

    /**
     * 生成一个种子字符串
     * 该方法通过生成一个唯一标识符(UUID)来创建一个唯一的种子字符串
     * 使用UUID可以确保生成的种子在一定范围内具有唯一性
     *
     * @return 返回一个UUID作为种子字符串
     */
    public static String generateSeed() {
        return UUID.randomUUID().toString();
    }

    /**
     * 字符串加密与解密
     */
    @Test
    public void string() throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
            NoSuchAlgorithmException, NoSuchPaddingException, DecoderException {

        String content = "21dsikhjihiuseiu23isdjahjsfhuahfuiashufsdajiafjihaseuihfwauisdloa'aops][sogjier";
        String seed =  generateSeed();
        System.out.println(seed.length());
        System.out.println("原文:" + content);
        System.out.println("种子(密码):" + seed);

        String encryptStr = Aes.encryptStr(content, seed);
        System.out.println("加密结果:" + encryptStr);

        String decryptStr = Aes.decryptStr(encryptStr, seed);
        System.out.println("解密结果:" + decryptStr);
    }

    /**
     * 字节与字符串
     */
    @Test
    public void byteAndString() throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
            NoSuchAlgorithmException, NoSuchPaddingException, DecoderException {
        String content = "artisan go go go";
        String seed =  generateSeed();

        System.out.println("原文:" + content);
        System.out.println("种子(密码):" + seed);

        byte[] encryptBytes = Aes.encrypt(content, seed);
        String encryptStr = Hex.encodeHexString(encryptBytes);
        System.out.println("加密结果:" + encryptStr);

        byte[] decryptBytes = Aes.decrypt(encryptStr, seed);
        System.out.println("解密结果:" + new String(decryptBytes));
    }

    /**
     * 字节
     */
    @Test
    public void bytes() throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
            NoSuchAlgorithmException, NoSuchPaddingException, DecoderException {
        String content = "aedksej sdksfdkhoweio (*&*^&^^^";
        String seed = generateSeed();

        System.out.println("原文:" + content);
        System.out.println("种子(密码):" + seed);

        byte[] encryptBytes = Aes.encrypt(content, seed);
        String encryptStr = Hex.encodeHexString(encryptBytes);
        System.out.println("加密结果:" + encryptStr);

        byte[] contentBytes = Hex.decodeHex(encryptStr);
        byte[] decryptBytes = Aes.decrypt(contentBytes, seed);
        System.out.println("解密结果:" + new String(decryptBytes));
    }

}

在这里插入图片描述


IV

package com.artisan.shuangxiang_aesrsa;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;

/**
 * AES工具类,提供AES加密和解密功能
 * 使用AES/CBC/PKCS5Padding算法进行加密和解密
 *
 * @author artisan
 */
public class AESUtil {
    /**
     * 定义加密算法类型为AES/CBC/PKCS5Padding
     */
    private static final String ALGORITHM = "AES/CBC/PKCS5Padding";

    /**
     * 使用AES算法加密数据
     *
     * @param data 待加密的字符串
     * @param key  加密使用的SecretKey
     * @param iv   加密使用的初始化向量(IvParameterSpec)
     * @return 加密后的字符串,以Base64编码
     * @throws Exception 如果加密过程中发生错误,抛出异常
     */
    public static String encryptAES(String data, SecretKey key, IvParameterSpec iv) throws Exception {
        // 创建Cipher实例,指定使用AES/CBC/PKCS5Padding算法
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 初始化Cipher为加密模式,传入密钥和初始化向量
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
        // 将待加密数据转换为字节数组,并执行加密操作
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        // 将加密后的数据使用Base64编码,并返回
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * 使用AES算法解密数据
     *
     * @param encryptedData 待解密的字符串,以Base64编码
     * @param key           解密使用的SecretKey
     * @param iv            解密使用的初始化向量(IvParameterSpec)
     * @return 解密后的字符串
     * @throws Exception 如果解密过程中发生错误,抛出异常
     */
    public static String decryptAES(String encryptedData, SecretKey key, IvParameterSpec iv) throws Exception {
        // 创建Cipher实例,指定使用AES/CBC/PKCS5Padding算法
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        // 初始化Cipher为解密模式,传入密钥和初始化向量
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        // 将待解密数据从Base64解码为字节数组
        byte[] decodedData = Base64.getDecoder().decode(encryptedData);
        // 执行解密操作
        byte[] decryptedData = cipher.doFinal(decodedData);
        // 将解密后的数据转换为字符串,并返回
        return new String(decryptedData);
    }
}

测试代码

package com.artisan.shuangxiang_aesrsa;

import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

/**
 * @author artisan
 */
public class Main_OnlyAES {


    /**
     * 使用RSA公钥加密AES密钥,以及使用RSA私钥解密AES密钥的全过程
     * 同时展示了使用AES密钥加密和解密数据的应用
     *
     * @param args 命令行参数
     * @throws Exception 可能抛出的异常
     */
    public static void main(String[] args) throws Exception {
        // 生成AES和RSA密钥
        SecretKey aesKey = KeyGeneration.generateAESKey();


        String aesKeyString = Base64.getEncoder().encodeToString(aesKey.getEncoded());
        System.out.println("AES密钥: " + aesKeyString);
        // 初始化IV(通常需要确保IV的安全传输)  16字节的IV向量
        IvParameterSpec iv = new IvParameterSpec(new byte[16]);


        // 使用AES加密和解密数据
        String originalData = "我是需要加密的数据artisan GO GO GO !!!";
        String encryptedData = AESUtil.encryptAES(originalData, aesKey, iv);
        System.out.println("加密的数据: " + encryptedData);

        String decryptedData = AESUtil.decryptAES(encryptedData, aesKey, iv);
        System.out.println("解密的数据: " + decryptedData);
    }
}


在这里插入图片描述

小结

  • IV 是加密过程的一部分,用于确保相同的明文在加密时能产生不同的密文,从而提高安全性。
  • Seed 则是用于初始化随机数生成器,以生成伪随机数,这些伪随机数可以用于生成IV、密钥等。

虽然IV有时可以通过随机数生成器来生成,这个随机数生成器可能使用Seed作为其输入,但它们的概念和用途是不同的。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2060522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HoloLens 坐标系统 Coordinate systems

Hololens 和 Unity 空间坐标系统-CSDN博客文章浏览阅读79次。这意味着&#xff0c;在 X、Y 或 Z 轴上相距 2 个单位的物体&#xff0c;在混合现实中的渲染效果是相距 2 米。虽然左手坐标和右手坐标是最常见的系统&#xff0c;但 3D 软件中也会使用其他坐标系。例如&#xff0c;…

【杂乱算法】前缀和与差分

前缀和 文章目录 前缀和一维应用 二维差分一维 二维扩展1、前缀和与哈希表 一维 一个数组prefix中&#xff0c;第i个元素表示nums[0]至nums[i-1]的总和&#xff0c;那么我们就称这个prefix数组是nums数组的前缀和。 prefix [ i ] ∑ j 0 i nums [ j ] \text{prefix}[i] \s…

显示弹出式窗口的方法

文章目录 1. 概念介绍2. 使用方法3. 示例代码 我们在上一章回中介绍了Sliver综合示例相关的内容&#xff0c;本章回中将介绍PopupMenuButton组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在本章回中介绍的PopupMenuButton组件位于AppBar右侧&#xf…

x-cmd pkg | dua - 一个可以方便地了解给定目录的磁盘空间使用情况的工具

目录 简介用户首次快速实验指南技术特点竞品和相关项目进一步阅读 简介 dua 是 Disk Usage Analyzer 的简写&#xff0c;该工具可以快速查看给定目录的磁盘空间使用情况。 对于想要深入了解磁盘空间使用情况并有效管理存储的用户来说&#xff0c;Dua 是一个很有价值的工具。通…

项目1 物流仓库管理系统

一、项目概述 本项目旨在开发一个功能全面的物流仓库管理系统&#xff0c;以数字化手段优化仓库作业流程&#xff0c;提高管理效率。系统集成了前端用户交互界面与后端数据处理逻辑&#xff0c;涵盖了从用户注册登录、订单管理、货单跟踪到用户信息维护等多个核心业务模块。通…

heic格式转化jpg用什么方法?这8个教程很实用

随着iOS设备的普及&#xff0c;HEIC&#xff08;High Efficiency Image Coding&#xff09;格式成为了默认的图片格式&#xff0c;因其相较于传统的JPEG格式&#xff0c;能更有效地压缩图片文件&#xff0c;保存更多细节&#xff0c;同时占用更少的存储空间。然而&#xff0c;H…

【UE5】Groom毛发系统的基本使用——给小白人添加头发

目录 效果 步骤 一、准备 二、使用3DsMax制作毛发 三、在UE中给小白人安装毛发 四、修改毛发材质 效果 步骤 一、准备 1. 新建一个第三人称模板工程 2. 在项目设置中&#xff0c;勾选“支持计算蒙皮缓存” 3. 在插件面板中&#xff0c;启用“Groom”和“Alembic Gro…

kubernetes的pod基础

kubernetes的pod基础 pod概念 pod&#xff08;豆荚&#xff09;&#xff0c;是k8s的最小管理单元。是一个或多个容器的组合&#xff0c;这些容器共享存储&#xff0c;网络和命名空间&#xff0c;以及运行规范&#xff0c;pod内的容器统一的进行安排和调度。pod是一组具有共享命…

智慧党建系统设计与实现_1i659

TOC springboot629智慧党建系统设计与实现_1i659--论文 研究背景 近年来&#xff0c;由于计算机技术和互联网技术的快速发展&#xff0c;使得所有企事业单位内部都是数字化、信息化、无纸化的发展趋势&#xff0c;随着趋势的发展&#xff0c;各种决策系统、辅助系统也应运而…

Java | Leetcode Java题解之第350题两个数组的交集II

题目&#xff1a; 题解&#xff1a; class Solution {public int[] intersect(int[] nums1, int[] nums2) {Arrays.sort(nums1);Arrays.sort(nums2);int length1 nums1.length, length2 nums2.length;int[] intersection new int[Math.min(length1, length2)];int index1 …

27.移除元素---力扣

题目链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/remove-element/description/ 问题描述&#xf…

Maven的简单使用

Maven使用 Maven的作用1. 自动构建标准化的java项目结构(1) 项目结构① 约定目录结构的意义② 约定大于配置 (2)项目创建坐标坐标的命名方法&#xff08;约定&#xff09; 2. 帮助管理java中jar包的依赖(1) 配置使用依赖引入属性配置 (2) maven指令(3) 依赖的范围(4) 依赖传递(…

Vitis AI 进阶认知(Torch量化基础+映射+量化参数+对称性+每通道+PTQ+QAT+敏感性)

目录 1. 介绍 2. 基本概念 2.1 映射函数 2.2 量化参数 2.3 校准 2.4 对称与非对称量化 2.5 Per-Tensor and Per-Channel 2.6 PTQ 2.7 QAT 2.8 敏感性分析 2.6 退火学习率 3. 几点建议 4. 总结 1. 介绍 Practical Quantization in PyTorch | PyTorchQuantization i…

OpenCV几何图像变换(4)亚像素图像截取函数getRectSubPix()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 从图像中以亚像素精度检索像素矩形。 getRectSubPix 函数从 src 中提取像素&#xff1a; p a t c h ( x , y ) s r c ( x center.x − ( dst.…

怎么为pdf文件加密设置密码?8个实用pdf文件加密方法

随着数字化信息的普及&#xff0c;保护PDF文件免受未授权访问和篡改的需求日益增强。为了确保您的重要文档安全无虞&#xff0c;加密PDF文件并设置密码成为了一个至关重要的步骤。以下是详细指导&#xff0c;帮助您为PDF文档加密并设置密码&#xff0c;确保其内容的安全。怎么为…

深入理解Java虚拟机(类加载器)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 类加载器 类加载器有什么作用呢&#xff1f; 对于任意的一个类&a…

基于一阶高斯低通滤波器的软件设计

前言 一阶RC低通滤波器&#xff08;巴特沃斯滤波&#xff09;-CSDN博客 一阶高斯低通滤波器不是一个直接的概念&#xff08;因为一阶滤波器通常不产生高斯型频率响应&#xff09;&#xff0c;这里我用软件的方式来模拟高斯低通滤波器的效果。 有纰漏请指出&#xff0c;转载…

C++竞赛初阶L1-13-第五单元-循环嵌套(29~30课)538: T456457 第 n 小的质数

题目内容 输入一个正整数 n&#xff0c;求正整数范围中第 n 小的质数。 输入格式 一个不超过 30000 的正整数 n。 输出格式 第 n 小的质数。 样例 1 输入 10 全部程序代码&#xff1a; #include<bits/stdc.h> using namespace std; int main() {long long n,i;ci…

【数据分享】《中国社会统计年鉴》(2006-2023)

而今天要限时免费分享的数据就是2006-2023年间出版的《中国社会统计年鉴》并以多格式提供免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 一、《中国社会统计年鉴》是一部反映我国社会发展相关领域基本情况的综合性统计资料年刊。书中收录了年全国和…

Leetcode每日刷题之1004.最大连续1的个数|||(C++)

1.题目解析 本题的目的是找出能最多翻转k个0的情况下最长连续的1的个数&#xff0c;并且这是一个二进制数组&#xff0c;只存在0和1&#xff0c;翻转0就是将0变为1 2.算法原理 首先我们想到的一定是暴力枚举&#xff0c;即依次列举出在最多翻转k个0的情况下所有连续1的子数组的…