![]() 概述在AES加密中,**IV(Initialization Vector,初始化向量)和Seed(种子)**是两个不同的概念,尽管它们都涉及到随机性和加密安全性,但用途和作用有所不同。 IV(Initialization Vector,初始化向量)
Seed(种子)
Codeseed[code] 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); } } [/code]测试代码 [code] 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)); } } [/code]![]() IV[code]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); } } [/code]测试代码 [code]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); } } [/code]![]() 小结
虽然IV有时可以通过随机数生成器来生成,这个随机数生成器可能使用Seed作为其输入,但它们的概念和用途是不同的。 ![]() 免责声明:本内容来源于网络,如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |