【Java】全网最详细的对称加密AES详解

【Java】全网最详细的对称加密AES详解AES AdvancedEncr 高级加密标准 是一种对称加密算法 用于加密电子数据

大家好,欢迎来到IT知识分享网。

前言

  AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,用于加密电子数据。它是由比利时密码学家Joan Daemen和Vincent Rijmen设计的,并于2001年由美国国家标准与技术研究院(NIST)采纳为官方标准。

一、AES加密原理

2、如何选择密钥长度

3、加密模式
  AES加密支持多种工作模式,每种模式都有其特定的应用场景和优势。以下是AES加密的一些常见模式

  • 选择合适的模式
    选择哪种模式取决于你的具体需求:
    如果你关心的是加密速度并且数据块之间没有相关性,可以选择 ECB。
    如果你需要更高的安全性,并且数据块之间存在相关性,可以选择 CBC。
    如果你需要并行处理数据,可以选择 CTR。
    如果你需要处理连续的数据流,并且希望减少错误传播的影响,可以选择 OFB 或 CFB。
    在大多数情况下,CBC 和 CTR 是最常用的模式。如果你需要在性能和安全性之间取得平衡,CTR 模式通常是一个不错的选择,因为它既可以并行处理又提供了良好的安全性。





4、填充模式
  填充(Padding)模式用于处理不足一个完整分组大小的数据块。填充模式确保所有的数据块都是固定长度的,这样就可以正确地进行加密和解密。以下是几种常见的填充模式

  • 选择合适的填充模式
    选择填充模式时,通常会考虑以下几个因素:
    安全性:PKCS5Padding 和 PKCS7Padding提供了更好的安全性,因为它们确保了填充字节的值是唯一的,并且可以通过检查填充字节来验证数据的完整性。
    兼容性:PKCS5Padding 和 PKCS7Padding 是最常用的标准,因此与其他系统或库的兼容性最好。
    性能:ZeroPadding 可能更快,因为它只需要填充零字节,但这可能会降低安全性。



  • 注意:jdk自带的加密模块不支持PKCS7Padding 填充,如果需要PKCS7Padding 需要引入第三方支持*

二、使用案例

  下面例子将使用CBC模式和PKCS5Padding填充进行AES加密和解密,大家有需要可以直接复制到自己的项目当中使用

import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; / * AES加密解密工具类(目前AES比DES和DES3更安全,速度更快,对称加密一般采用AES) */ public class AESUtil { 
    private static final String KEY_ALGORITHM="AES"; / * * 参数按"加密算法/模式/填充模式" 。 * * (1)加密算法有:AES * * (2) 模式有CBC(有向量模式)和ECB(无向量模式)等,使用CBC模式需要定义一个IvParameterSpec对象,使用CBC模式更加安全,一般建议使用CBC模式 * * (3) 填充模式:NoPadding、PKCS5Padding、PKCS7Padding等 */ private static final String CIPHER_ALGORITHM="AES/CBC/PKCS5Padding"; / * 生成AES密钥 * @param keySize * @return * @throws NoSuchAlgorithmException * @throws UnsupportedEncodingException */ public static String generateKey(int keySize) throws NoSuchAlgorithmException, UnsupportedEncodingException { 
    KeyGenerator keyGenerator=KeyGenerator.getInstance(KEY_ALGORITHM); keyGenerator.init(keySize,new SecureRandom()); SecretKey secretKey=keyGenerator.generateKey(); return new String(Base64.getEncoder().encode(secretKey.getEncoded()),"UTF-8"); } / * 使用AES加密数据 * @param data 加密数据 * @param key 密钥 * @param iv 初始化随机向量 * @return * @throws Exception */ public static String encrypt(String data, String key,String iv)throws Exception{ 
    //密钥base64解码 byte[] decode = Base64.getDecoder().decode(key); SecretKeySpec secretKeySpec=new SecretKeySpec(decode,KEY_ALGORITHM); byte[] ivBytes = Base64.getDecoder().decode(iv); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); //根据参数获取加密实例 Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM); //初始化对象为加密模式 cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivSpec); //加密后的密文进行base64编码 return Base64.getEncoder().encodeToString(cipher.doFinal(data.getBytes())); } / * 使用AES解密密文 * @param encrypt 加密后的密文 * @param key 密钥 * @param iv 初始化随机向量 * @return * @throws Exception */ public static String decrypt(String encrypt,String key,String iv)throws Exception{ 
    //密钥base64解码 byte[] decode = Base64.getDecoder().decode(key); SecretKeySpec secretKeySpec=new SecretKeySpec(decode,KEY_ALGORITHM); Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM); byte[] ivBytes = Base64.getDecoder().decode(iv); IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); //初始化对象为解密模式 cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,ivSpec); byte[] dateBytes = Base64.getDecoder().decode(encrypt); //解密并转换为字符串 return new String(cipher.doFinal(dateBytes)); } public static void main(String[] args) throws Exception { 
    // 生成一个 16 字节的随机 IV byte[] ivBytes = new byte[16]; SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(ivBytes); String iv = new String(Base64.getEncoder().encode(ivBytes), "UTF-8"); System.out.println("iv:"+iv); String key = AESUtil.generateKey(128); String plainText ="Hello,world!"; System.out.println("加密前的数据:" + plainText); String encrypt = AESUtil.encrypt(plainText,key,iv); System.out.println("加密后的密文:" + new String(encrypt)); String decryptedText = AESUtil.decrypt(encrypt,key,iv); System.out.println("解密后的数据:" + decryptedText); } } 
  • 如果您需要使用PKCS7Padding填充进行加密,可以在pom中引入如下依赖
<!-- 包含了基础的密码学功能,比如对称加密(如 AES)、非对称加密(如 RSA)、散列算法(如 SHA-256)以及数字签名等。它是实现加密、数字签名等基本密码学应用的基础 --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70</version> <!-- 检查最新的版本 --> </dependency> <!-- 包含了与 PKIXPublic Key Infrastructure X.509)相关的一系列功能,主要包括证书管理、证书验证、证书撤销列表(CRL)等功能。它提供了更高级的密码学服务,比如证书链验证、证书签发等--> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.70</version> <!-- 检查最新的版本 --> </dependency> 
  • 并且增加以下类启动后执行Security.addProvider(new BouncyCastleProvider());来添加安全提供者,然后只需要将上例中的PKCS5Padding改成PKCS7Padding即可
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class SecurityProviderInitializer implements CommandLineRunner { 
    @Override public void run(String... args) throws Exception { 
    // 添加 Bouncy Castle 为首选的安全提供者 Security.addProvider(new BouncyCastleProvider()); } } 

有关非对称加密RSA大家可以看我另一篇: 全网最详细的非对称加密RSA详解

为了帮助更多像你一样的读者,我将持续在专栏中分享技术干货和实用技巧。如果你觉得这篇文章对你有帮助,可以考虑关注我的专栏,谢谢。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/109814.html

(0)
上一篇 2026-02-04 15:15
下一篇 2026-02-04 15:27

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信