Java jce對aes算法有很好的支持,但是默認安裝的JDK或者JRE是不能支持aes192bit密鑰和aes256bit密鑰兩種算法的,需要到sun官方下載Java(TM) Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files,以下是jce unilimited strength jurisdiction policy files 6的官方下載地址:
https://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/ViewProductDetail-Start?ProductRef=jce_policy-6-oth-JPR@CDS-CDS_Developer
下載後解壓文件,將裡面的文件拷貝到
<java-home>/lib/security [Unix]
<java-home>/lib/security [Win32]
覆蓋原先的jar文件,請先備份原先的jar文件,以防你需要恢復密鑰長度的限制,這裡需要注意的是如果是安裝的jdk,jdk目錄中的jre下面的lib/security下的文件也需要覆蓋。完成這個步驟之後就可以使用不限制密鑰長度的aes算法了,簡單的實現代碼如下:
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(192); // 192 and 256 bits also available,這一步是否有安裝jce unlimited strength jurisdiction policy files 都不會出現異常
Generate the secret key specs.
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);//這一步如果沒有安裝jce unlimited strength jurisdiction policy files,並且使用了192bits和256bits的密鑰的話就會拋出java.security.InvalidKeyException:Invalid AES key length
byte[] output = cipher.doFinal(seed);//seed是一個byte[];
最後講下aes算法是塊加密運算的,單位塊大小為16bytes,所以輸入的byte[]如果不是16的倍數就填充至16的倍數,然後aes算法的密文結構就是aes對每一個塊(16bytes)的明文加密的密文的拼串。比如aes128加密16bytes的byte[]a得到16bytes的密文a,加密16bytes的byte[]b得到16bytes的密文b,這樣我們構建一個32bytes的byte[]c,前16bytes數據來自copy至a,後16bytes數據copy至b,這樣將c輸入aes128加密將得到一個32bytes的密文,並且就是之前的密文a和密文b的順序拼串,以上都是nopadding模式下的情況。