這段時間由於要對接一個外部接口,其參數的加密方式爲AES,就須要學下AES的加密寫法,但網上的資料不是很全,本身記錄下遇到的坑;java
String str = "hello"; String password = "1234567890123456"; //新建一個密碼編譯器的實例,由三部分構成,用"/"分隔,分別表明加密的類型(如AES,DES,RC2等),模式(AES中包含ECB,CBC,CFB,CTR,CTS等),補碼方式(包含nopadding/PKCS5Padding等等),依據這三個參數能夠建立不少種加密方式 Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", SymmetricAlgorithm.AES.name(), Mode.ECB.name(), Padding.PKCS5Padding.name())); //構建密鑰 SecretKeySpec key = new SecretKeySpec(password.getBytes(Charset.forName("utf-8")),"AES"); cipher.init(Cipher.ENCRYPT_MODE, key);//使用加密模式初始化 密鑰 byte[] encrypt = cipher.doFinal(str.getBytes()); //按單部分操做加密或解密數據,或者結束一個多部分操做。 System.out.println(Base64.encode(encrypt)); System.out.println("method2-加密:" + Arrays.toString(encrypt)); cipher.init(Cipher.DECRYPT_MODE, key);//使用解密模式初始化 密鑰 byte[] decrypt = cipher.doFinal(encrypt); System.out.println("method2-解密後:" + new String(decrypt));
這樣一個最簡單的AES加解密就完成了,但有一個缺點,密碼的長度必須爲128位,也就是16個字節,不然會報錯;
當使用AES/ECB/NoPadding模式時,加密的內容的字節長度也必須爲16的整倍數,不然也會提示錯誤;
可採用的方法是:若是key的長度小於16,則補全16位,不然截取16位
加密內容補全爲16的整倍數,如下爲示例代碼:數組
/** * 測試AES加密,使用ECB/Nopadding的方式,要求key的長度爲128位,內容的長度也爲128位的整數倍 * @param content * @param password * @return */ private String testAes(String content,String password) throws Exception { //原始字節數組 byte[] passwordBytes = password.getBytes(Charset.forName("utf-8")); //填充爲16位 byte[] keyBytes = new byte[16]; byte[] contentBytes = content.getBytes(Charset.forName("utf-8")); byte[] contentBytesTarget ; Cipher cipher = Cipher.getInstance(String.format("%s/%s/%s", SymmetricAlgorithm.AES.name(), Mode.ECB.name(), Padding.NoPadding.name())); if(passwordBytes.length < 16) System.arraycopy(passwordBytes,0,keyBytes,0,passwordBytes.length); else System.arraycopy(passwordBytes,0,keyBytes,0,16); if(contentBytes.length % 16 == 0) contentBytesTarget = contentBytes; else{ contentBytesTarget = new byte[contentBytes.length + 16 - contentBytes.length % 16 ]; System.arraycopy(contentBytes,0,contentBytesTarget,0,contentBytes.length); } SecretKeySpec key = new SecretKeySpec(keyBytes,"AES"); cipher.init(Cipher.ENCRYPT_MODE, key);//使用加密模式初始化 密鑰 byte[] encrypt = cipher.doFinal(contentBytesTarget); //按單部分操做加密或解密數據,或者結束一個多部分操做。 System.out.println(Base64.encode(encrypt)); System.out.println("method2-加密:" + Arrays.toString(encrypt)); cipher.init(Cipher.DECRYPT_MODE, key);//使用解密模式初始化 密鑰 byte[] decrypt = cipher.doFinal(encrypt); System.out.println("method2-解密後:" + new String(decrypt)); return Base64.encode(encrypt); }
能夠使用在線工具進行測試:http://tool.chacuo.net/cryptaes工具
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">測試