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

打印 上一主题 下一主题

主题 979|帖子 979|积分 2937



概述

在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

  1. import org.apache.commons.codec.DecoderException;
  2. import org.apache.commons.codec.binary.Hex;
  3. import javax.crypto.BadPaddingException;
  4. import javax.crypto.Cipher;
  5. import javax.crypto.IllegalBlockSizeException;
  6. import javax.crypto.KeyGenerator;
  7. import javax.crypto.NoSuchPaddingException;
  8. import javax.crypto.SecretKey;
  9. import javax.crypto.spec.SecretKeySpec;
  10. import java.security.InvalidKeyException;
  11. import java.security.NoSuchAlgorithmException;
  12. import java.security.SecureRandom;
  13. import java.util.UUID;
  14. /**
  15. * AES 对称性加密
  16. * <p>
  17. * 需要依赖 Apache Commons Codec
  18. *
  19. * @author artisan
  20. */
  21. public class AesUtil {
  22.     /**
  23.      * 加密算法类型
  24.      */
  25.     static final String ALGORITHM_KEY = "AES";
  26.     /**
  27.      * 算法长度
  28.      */
  29.     private static final int KEY_SIZE = 128;
  30.     /**
  31.      * 生成一个种子字符串
  32.      * 该方法通过生成一个唯一标识符(UUID)来创建一个唯一的种子字符串
  33.      * 使用UUID可以确保生成的种子在一定范围内具有唯一性
  34.      *
  35.      * @return 返回一个UUID作为种子字符串
  36.      */
  37.     public static String generateSeed() {
  38.         return UUID.randomUUID().toString();
  39.     }
  40.     /**
  41.      * 使用 种子(密码)、模式 创建密码加密
  42.      *
  43.      * @param seed 种子(密码)
  44.      * @param mode 模式,加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}
  45.      * @return 返回 密码加密
  46.      * @throws NoSuchAlgorithmException 算法类型异常
  47.      * @throws NoSuchPaddingException   算法填充异常
  48.      * @throws InvalidKeyException      无效的密钥异常
  49.      */
  50.     public static Cipher cipher(String seed, int mode) throws NoSuchAlgorithmException,
  51.             NoSuchPaddingException, InvalidKeyException {
  52.         KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM_KEY);
  53.         byte[] seedBytes = seed.getBytes();
  54.         keyGenerator.init(KEY_SIZE, new SecureRandom(seedBytes));
  55.         SecretKey secretKey = keyGenerator.generateKey();
  56.         byte[] encodedBytes = secretKey.getEncoded();
  57.         SecretKeySpec secretKeySpec = new SecretKeySpec(encodedBytes, ALGORITHM_KEY);
  58.         Cipher cipher = Cipher.getInstance(ALGORITHM_KEY);
  59.         cipher.init(mode, secretKeySpec);
  60.         return cipher;
  61.     }
  62.     /**
  63.      * 使用 种子(密码)将内容 加密
  64.      *
  65.      * @param originalText 原文
  66.      * @param seed         种子(密码)
  67.      * @return 返回 加密结果
  68.      * @throws NoSuchAlgorithmException  算法类型异常
  69.      * @throws NoSuchPaddingException    算法填充异常
  70.      * @throws InvalidKeyException       无效的密钥异常
  71.      * @throws BadPaddingException       错误填充异常
  72.      * @throws IllegalBlockSizeException 非法的块大小异常
  73.      */
  74.     public static byte[] encrypt(byte[] originalText, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException,
  75.             InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
  76.         Cipher cipher = cipher(seed, Cipher.ENCRYPT_MODE);
  77.         return cipher.doFinal(originalText);
  78.     }
  79.     /**
  80.      * 使用 种子(密码)将内容 加密
  81.      *
  82.      * @param originalText 原文
  83.      * @param seed         种子(密码)
  84.      * @return 返回 加密结果
  85.      * @throws NoSuchAlgorithmException  算法类型异常
  86.      * @throws NoSuchPaddingException    算法填充异常
  87.      * @throws InvalidKeyException       无效的密钥异常
  88.      * @throws BadPaddingException       错误填充异常
  89.      * @throws IllegalBlockSizeException 非法的块大小异常
  90.      */
  91.     public static byte[] encrypt(String originalText, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException,
  92.             InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
  93.         return encrypt(originalText.getBytes(), seed);
  94.     }
  95.     /**
  96.      * 使用 种子(密码)将内容 加密
  97.      *
  98.      * @param originalText 原文
  99.      * @param seed         种子(密码)
  100.      * @return 返回 加密结果
  101.      * @throws NoSuchAlgorithmException  算法类型异常
  102.      * @throws NoSuchPaddingException    算法填充异常
  103.      * @throws InvalidKeyException       无效的密钥异常
  104.      * @throws BadPaddingException       错误填充异常
  105.      * @throws IllegalBlockSizeException 非法的块大小异常
  106.      */
  107.     public static String encryptStr(String originalText, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException,
  108.             InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
  109.         byte[] encryptBytes = encrypt(originalText.getBytes(), seed);
  110.         return Hex.encodeHexString(encryptBytes);
  111.     }
  112.     /**
  113.      * 使用 种子(密码)将内容 解密
  114.      *
  115.      * @param cipherText 密文
  116.      * @param seed       种子(密码)
  117.      * @return 返回 解密原文
  118.      * @throws NoSuchAlgorithmException  算法类型异常
  119.      * @throws NoSuchPaddingException    算法填充异常
  120.      * @throws InvalidKeyException       无效的密钥异常
  121.      * @throws BadPaddingException       错误填充异常
  122.      * @throws IllegalBlockSizeException 非法的块大小异常
  123.      */
  124.     public static byte[] decrypt(byte[] cipherText, String seed) throws NoSuchAlgorithmException, BadPaddingException,
  125.             IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException {
  126.         Cipher cipher = cipher(seed, Cipher.DECRYPT_MODE);
  127.         return cipher.doFinal(cipherText);
  128.     }
  129.     /**
  130.      * 使用 种子(密码)将内容 解密
  131.      *
  132.      * @param cipherText 密文
  133.      * @param seed       种子(密码)
  134.      * @return 返回 解密原文
  135.      * @throws NoSuchAlgorithmException  算法类型异常
  136.      * @throws NoSuchPaddingException    算法填充异常
  137.      * @throws InvalidKeyException       无效的密钥异常
  138.      * @throws BadPaddingException       错误填充异常
  139.      * @throws IllegalBlockSizeException 非法的块大小异常
  140.      * @throws DecoderException          解码器异常
  141.      */
  142.     public static byte[] decrypt(String cipherText, String seed) throws NoSuchAlgorithmException, BadPaddingException,
  143.             IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, DecoderException {
  144.         byte[] contentBytes = Hex.decodeHex(cipherText);
  145.         return decrypt(contentBytes, seed);
  146.     }
  147.     /**
  148.      * 使用 种子(密码)将内容 解密
  149.      *
  150.      * @param cipherText 密文
  151.      * @param seed       种子(密码)
  152.      * @return 返回 解密原文
  153.      * @throws NoSuchAlgorithmException  算法类型异常
  154.      * @throws NoSuchPaddingException    算法填充异常
  155.      * @throws InvalidKeyException       无效的密钥异常
  156.      * @throws BadPaddingException       错误填充异常
  157.      * @throws IllegalBlockSizeException 非法的块大小异常
  158.      * @throws DecoderException          解码器异常
  159.      */
  160.     public static String decryptStr(String cipherText, String seed) throws NoSuchAlgorithmException, BadPaddingException,
  161.             IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, DecoderException {
  162.         byte[] decryptFrom = Hex.decodeHex(cipherText);
  163.         byte[] decryptBytes = decrypt(decryptFrom, seed);
  164.         return new String(decryptBytes);
  165.     }
  166. }
复制代码
测试代码
  1. import org.apache.commons.codec.DecoderException;
  2. import org.apache.commons.codec.binary.Hex;
  3. import org.junit.jupiter.api.Test;
  4. import javax.crypto.BadPaddingException;
  5. import javax.crypto.IllegalBlockSizeException;
  6. import javax.crypto.NoSuchPaddingException;
  7. import java.security.InvalidKeyException;
  8. import java.security.NoSuchAlgorithmException;
  9. import java.util.UUID;
  10. /**
  11. * AES 对称加密 测试类
  12. *
  13. * @author artisan
  14. */
  15. public class AesUtils {
  16.     /**
  17.      * 生成一个种子字符串
  18.      * 该方法通过生成一个唯一标识符(UUID)来创建一个唯一的种子字符串
  19.      * 使用UUID可以确保生成的种子在一定范围内具有唯一性
  20.      *
  21.      * @return 返回一个UUID作为种子字符串
  22.      */
  23.     public static String generateSeed() {
  24.         return UUID.randomUUID().toString();
  25.     }
  26.     /**
  27.      * 字符串加密与解密
  28.      */
  29.     @Test
  30.     public void string() throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
  31.             NoSuchAlgorithmException, NoSuchPaddingException, DecoderException {
  32.         String content = "21dsikhjihiuseiu23isdjahjsfhuahfuiashufsdajiafjihaseuihfwauisdloa'aops][sogjier";
  33.         String seed =  generateSeed();
  34.         System.out.println(seed.length());
  35.         System.out.println("原文:" + content);
  36.         System.out.println("种子(密码):" + seed);
  37.         String encryptStr = Aes.encryptStr(content, seed);
  38.         System.out.println("加密结果:" + encryptStr);
  39.         String decryptStr = Aes.decryptStr(encryptStr, seed);
  40.         System.out.println("解密结果:" + decryptStr);
  41.     }
  42.     /**
  43.      * 字节与字符串
  44.      */
  45.     @Test
  46.     public void byteAndString() throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
  47.             NoSuchAlgorithmException, NoSuchPaddingException, DecoderException {
  48.         String content = "artisan go go go";
  49.         String seed =  generateSeed();
  50.         System.out.println("原文:" + content);
  51.         System.out.println("种子(密码):" + seed);
  52.         byte[] encryptBytes = Aes.encrypt(content, seed);
  53.         String encryptStr = Hex.encodeHexString(encryptBytes);
  54.         System.out.println("加密结果:" + encryptStr);
  55.         byte[] decryptBytes = Aes.decrypt(encryptStr, seed);
  56.         System.out.println("解密结果:" + new String(decryptBytes));
  57.     }
  58.     /**
  59.      * 字节
  60.      */
  61.     @Test
  62.     public void bytes() throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException,
  63.             NoSuchAlgorithmException, NoSuchPaddingException, DecoderException {
  64.         String content = "aedksej sdksfdkhoweio (*&*^&^^^";
  65.         String seed = generateSeed();
  66.         System.out.println("原文:" + content);
  67.         System.out.println("种子(密码):" + seed);
  68.         byte[] encryptBytes = Aes.encrypt(content, seed);
  69.         String encryptStr = Hex.encodeHexString(encryptBytes);
  70.         System.out.println("加密结果:" + encryptStr);
  71.         byte[] contentBytes = Hex.decodeHex(encryptStr);
  72.         byte[] decryptBytes = Aes.decrypt(contentBytes, seed);
  73.         System.out.println("解密结果:" + new String(decryptBytes));
  74.     }
  75. }
复制代码


IV

  1. package com.artisan.shuangxiang_aesrsa;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.SecretKey;
  4. import javax.crypto.spec.IvParameterSpec;
  5. import java.util.Base64;
  6. /**
  7. * AES工具类,提供AES加密和解密功能
  8. * 使用AES/CBC/PKCS5Padding算法进行加密和解密
  9. *
  10. * @author artisan
  11. */
  12. public class AESUtil {
  13.     /**
  14.      * 定义加密算法类型为AES/CBC/PKCS5Padding
  15.      */
  16.     private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
  17.     /**
  18.      * 使用AES算法加密数据
  19.      *
  20.      * @param data 待加密的字符串
  21.      * @param key  加密使用的SecretKey
  22.      * @param iv   加密使用的初始化向量(IvParameterSpec)
  23.      * @return 加密后的字符串,以Base64编码
  24.      * @throws Exception 如果加密过程中发生错误,抛出异常
  25.      */
  26.     public static String encryptAES(String data, SecretKey key, IvParameterSpec iv) throws Exception {
  27.         // 创建Cipher实例,指定使用AES/CBC/PKCS5Padding算法
  28.         Cipher cipher = Cipher.getInstance(ALGORITHM);
  29.         // 初始化Cipher为加密模式,传入密钥和初始化向量
  30.         cipher.init(Cipher.ENCRYPT_MODE, key, iv);
  31.         // 将待加密数据转换为字节数组,并执行加密操作
  32.         byte[] encryptedData = cipher.doFinal(data.getBytes());
  33.         // 将加密后的数据使用Base64编码,并返回
  34.         return Base64.getEncoder().encodeToString(encryptedData);
  35.     }
  36.     /**
  37.      * 使用AES算法解密数据
  38.      *
  39.      * @param encryptedData 待解密的字符串,以Base64编码
  40.      * @param key           解密使用的SecretKey
  41.      * @param iv            解密使用的初始化向量(IvParameterSpec)
  42.      * @return 解密后的字符串
  43.      * @throws Exception 如果解密过程中发生错误,抛出异常
  44.      */
  45.     public static String decryptAES(String encryptedData, SecretKey key, IvParameterSpec iv) throws Exception {
  46.         // 创建Cipher实例,指定使用AES/CBC/PKCS5Padding算法
  47.         Cipher cipher = Cipher.getInstance(ALGORITHM);
  48.         // 初始化Cipher为解密模式,传入密钥和初始化向量
  49.         cipher.init(Cipher.DECRYPT_MODE, key, iv);
  50.         // 将待解密数据从Base64解码为字节数组
  51.         byte[] decodedData = Base64.getDecoder().decode(encryptedData);
  52.         // 执行解密操作
  53.         byte[] decryptedData = cipher.doFinal(decodedData);
  54.         // 将解密后的数据转换为字符串,并返回
  55.         return new String(decryptedData);
  56.     }
  57. }
复制代码
测试代码
  1. package com.artisan.shuangxiang_aesrsa;
  2. import javax.crypto.SecretKey;
  3. import javax.crypto.spec.IvParameterSpec;
  4. import java.security.KeyPair;
  5. import java.security.PrivateKey;
  6. import java.security.PublicKey;
  7. import java.util.Base64;
  8. /**
  9. * @author artisan
  10. */
  11. public class Main_OnlyAES {
  12.     /**
  13.      * 使用RSA公钥加密AES密钥,以及使用RSA私钥解密AES密钥的全过程
  14.      * 同时展示了使用AES密钥加密和解密数据的应用
  15.      *
  16.      * @param args 命令行参数
  17.      * @throws Exception 可能抛出的异常
  18.      */
  19.     public static void main(String[] args) throws Exception {
  20.         // 生成AES和RSA密钥
  21.         SecretKey aesKey = KeyGeneration.generateAESKey();
  22.         String aesKeyString = Base64.getEncoder().encodeToString(aesKey.getEncoded());
  23.         System.out.println("AES密钥: " + aesKeyString);
  24.         // 初始化IV(通常需要确保IV的安全传输)  16字节的IV向量
  25.         IvParameterSpec iv = new IvParameterSpec(new byte[16]);
  26.         // 使用AES加密和解密数据
  27.         String originalData = "我是需要加密的数据artisan GO GO GO !!!";
  28.         String encryptedData = AESUtil.encryptAES(originalData, aesKey, iv);
  29.         System.out.println("加密的数据: " + encryptedData);
  30.         String decryptedData = AESUtil.decryptAES(encryptedData, aesKey, iv);
  31.         System.out.println("解密的数据: " + decryptedData);
  32.     }
  33. }
复制代码

小结



  • IV 是加密过程的一部分,用于确保相同的明文在加密时能产生差异的密文,从而进步安全性。
  • Seed 则是用于初始化随机数天生器,以天生伪随机数,这些伪随机数可以用于天生IV、密钥等。
固然IV有时可以通过随机数天生器来天生,这个随机数天生器可能使用Seed作为其输入,但它们的概念和用途是差异的。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

石小疯

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表