java | 使用Cipher类实现AES所有常用加密模式

1.先看下介绍

AES 密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。

AES 是对称加密算法,优点:加密速度快;缺点:如果秘钥丢失,就容易解密密文,安全性相对比较差
对称加密 : 也就是加密秘钥和解密秘钥是一样的。
非对称加密 : 也就是加密秘钥和解密秘钥是不一样的。

2.废话不多说,直接上代码

2.1 自己定义的一个类,参数是AES加密模式,方便调用
    public static final String AESCBCNoPadding = "AES/CBC/NoPadding";
    public static final String AESCBCPKCS5Padding = "AES/CBC/PKCS5Padding(";
    public static final String AESECBNoPadding = "AES/ECB/NoPadding";
    public static final String AESECBPKCS5Padding = "AES/ECB/PKCS5Padding";
    public static final String DESCBCNoPadding = "DES/CBC/NoPadding";
    public static final String DESCBCPKCS5Padding = "DES/CBC/PKCS5Padding";
    public static final String DESECBNoPadding = "DES/ECB/NoPadding";
    public static final String DESECBPKCS5Padding = "DES/ECB/PKCS5Padding";
    public static final String DESedeCBCNoPadding = "DESede/CBC/NoPadding";
    public static final String DESedeCBCPKCS5Padding = "DESede/CBC/PKCS5Padding";
    public static final String DESedeECBNoPadding = "DESede/ECB/NoPadding";
    public static final String DESedeECBPKCS5Padding = "DESede/ECB/PKCS5Padding";
    public static final String RSAECBPKCS1Padding = "RSA/ECB/PKCS1Padding";
    public static final String RSAECBOAEPWithSHA_1AndMGF1Padding = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
    public static final String RSAECBOAEPWithSHA_256AndMGF1Padding = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";

2.2 由于aes加密后的字节数组,直接转String返回参数有可能存在乱码,所以对返回值做一下处理,将加密的结果转换为base64的字符串。同理,解密时候,需要把字符串先base64处理,再把解密后的内容进行aes解密操作。
也就是说流程为:
加密(从前往后):明文 -> 加密 -> base64处理 -> 密文
解密(从后往前):明文 <- 解密 <- base64处理 <- 密文

/**
     * @param data 明文
     * @param key  密钥,长度16
     * @param iv   偏移量,长度16
     * @return 密文
     * @Description AES算法加密明文
     */
    public static String AesEncrypt(String data, String key, String iv) {
        try {
        	//AES/CBC/NoPadding
            Cipher cipher = Cipher.getInstance(AESEnum.AESCBCNoPadding);
            int blockSize = cipher.getBlockSize();
            byte[] dataBytes = data.getBytes();
            int plaintextLength = dataBytes.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
            // CBC模式,需要一个向量iv,可增加加密算法的强度
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());  
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);
            // 加密后直接转string可能乱码,用BASE64做转码。
            return encode(encrypted).trim(); 
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * @param data 密文
     * @param key  密钥,长度16
     * @param iv   偏移量,长度16
     * @return 明文
     * @Description AES算法解密
     */
    public static String AesDecrypt(String data, String key, String iv) {
        try {
        	//先用base64解密
            byte[] encrypted1 = decode(data);
            //AES/CBC/NoPadding 
            Cipher cipher = Cipher.getInstance(AESEnum.AESCBCNoPadding);
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original);
            return originalString.trim();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 编码
     *
     * @param byteArray
     * @return
     */
    public static String encode(byte[] byteArray) {
        return new String(new org.apache.commons.codec.binary.Base64().encode(byteArray));
    }

    /**
     * 解码
     *
     * @param base64EncodedString
     * @return
     */
    public static byte[] decode(String base64EncodedString) {
        return new org.apache.commons.codec.binary.Base64().decode(base64EncodedString);
    }

用到的依赖

		<!--常用的加密解密方法-->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.15</version>
        </dependency>

测试结果:
没一点问题滴
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的加密Cipher是一个非常重要的,用于加密和解密数据。它是Java Cryptography Architecture (JCA)的一部分,提供了许多加密算法的实现,如DES、AES、RSA等。下面是Cipher使用方法: 1. 创建Cipher对象:Cipher对象是通过调用Cipher.getInstance()方法创建的。需要传入一个加密算法的名称,如AES、DES等。 ```java Cipher cipher = Cipher.getInstance("AES"); ``` 2. 初始化Cipher对象:Cipher对象需要被初始化为加密模式或解密模式。可以通过调用init()方法实现。需要传入一个密钥和一个模式参数,如加密模式Cipher.ENCRYPT_MODE)或解密模式Cipher.DECRYPT_MODE)。 ```java Key key = new SecretKeySpec(keyBytes, "AES"); cipher.init(Cipher.ENCRYPT_MODE, key); ``` 3. 加密或解密数据:使用已经初始化的Cipher对象,可以使用doFinal()方法来加密或解密数据。需要传入要加密或解密的数据。 ```java byte[] encryptedData = cipher.doFinal(plainText.getBytes()); ``` 完整的加密和解密示例代码如下: ```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.security.Key; public class CipherExample { public static void main(String[] args) throws Exception { String plainText = "hello world"; byte[] keyBytes = "0123456789abcdef".getBytes(); // Create cipher object Cipher cipher = Cipher.getInstance("AES"); // Initialize cipher object Key key = new SecretKeySpec(keyBytes, "AES"); cipher.init(Cipher.ENCRYPT_MODE, key); // Encrypt data byte[] encryptedData = cipher.doFinal(plainText.getBytes()); System.out.println("Encrypted data: " + new String(encryptedData)); // Initialize cipher object for decryption cipher.init(Cipher.DECRYPT_MODE, key); // Decrypt data byte[] decryptedData = cipher.doFinal(encryptedData); System.out.println("Decrypted data: " + new String(decryptedData)); } } ``` 上述代码使用AES算法加密和解密数据。注意,密钥的长度必须是16个字节。如果需要使用其他算法或长度的密钥,需要进行相应的修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值