密鑰是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
