AES加解密
密钥是AES
算法实现加密和解密的根本。对称加密算法之所以对称,是因为这类算法对明文的加密和解密需要使用同一个密钥。
AES
支持三种长度的密钥: 128位,192位,256位
平时大家所说的AES128
,AES192
,AES256
,实际上就是指AES
算法对不同长度密钥的使用。
三种密钥的区别:
从安全性来看,AES256
安全性最高。从性能看,AES128
性能最高。本质原因是它们的加密处理轮数不同。
AES原理:AES是对数据按128位,也就是16个字节进行分组进行加密的,每次对一组数据加密需要运行多轮,而输入密钥的长度可以为128、192和256位,也就是16个字节、24个字节和32个字节,如果用户输入的密钥长度不是这几种长度,也会补成这几种长度。
无论输入密钥是多少字节,加密还是以16字节的数据一组来进行的,密钥长度的不同仅仅影响加密运行的轮数。
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; public class TestController { public static void main(String[] args) { try { //根据指定字符串生成秘钥 KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(128,new SecureRandom("ceshi".getBytes())); SecretKey sk = kg.generateKey(); String keyStr = Base64.getEncoder().encodeToString(sk.getEncoded()); byte[] iv = Base64.getDecoder().decode(keyStr); byte[] key = Base64.getDecoder().decode(keyStr); String content = "测试"; String encrypted = Base64.getEncoder().encodeToString(encrypt(iv, key, content.getBytes())); System.out.println("加密后: " + encrypted); String raw = new String(decrypt(iv, key, Base64.getDecoder().decode(encrypted))); System.out.println("解密后: " + raw); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } public static byte[] encrypt(byte[] iv, byte[] key, byte[] raw) { try { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式" IvParameterSpec ips = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ips); return cipher.doFinal(raw); } catch (Exception e) { throw new RuntimeException(e); } } public static byte[] decrypt(byte[] iv, byte[] key, byte[] encryptContent) { try { SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ips = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, skeySpec, ips); return cipher.doFinal(encryptContent); } catch (Exception e) { throw new RuntimeException(e); } } }
填充模式:
PKCS1Padding:PKCS#1(v1.5)中规定当RSA的密钥长度是1024b,如果使用PKCS1Padding填充,则原文数据最多117B。如果原文不满足长度要求,则在加密前需要进行填充。
PKCS5Padding:PKCS#5填充是将数据填充到8的倍数,填充后数据长度的计算公式是 定于元数据长度为x, 填充后的长度是 x + (8 - (x % 8)), 填充的数据是 8 - (x % 8),块大小固定为8字节
PKCS7Padding:假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小;PKCS5只填充到8字节,而PKCS7可以在1-255之间任意填充。
ZeroPadding:数据长度不对齐时使用0填充,否则不填充。
NoPadding:待补充
参考连接:https://blog.csdn.net/qq_36838191/article/details/80494043