在以前咱們在openssl上和ios上分別測試了 AES256位cbc模式的加密和解密html
今天用java提供的api來測試一下;進而肯定一下在PC,iOS,安卓上三個平臺下的加密解密數據;java
1. 首先經過查詢資料瞭解到:ios
2. 關於安裝 支持AES 256位密鑰的擴展包api
下載http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.htmloracle
下載以後獲得 local_policy.jar ,US_export_policy.jar 兩個jar包,把這兩個jar包放到 jdk/lib/security 目錄下ide
替換原來的兩個jar包便可測試
3. 使用java api 進行 AES_cbc_256位密鑰 PKCS5 填充方式的加密解密加密
以下封裝spa
private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; //加密 public static byte[] AES_cbc_encrypt(byte[] srcData,byte[] key,byte[] iv) { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] encData = cipher.doFinal(srcData); return encData; } //解密 public static byte[] AES_cbc_decrypt(byte[] encData,byte[] key,byte[] iv) { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] decbbdt = cipher.doFinal(encData); return decbbdt; }
測試調用3d
public static void main(String[] args) { byte[] key= new byte[32]; byte[] iv = new byte[16]; String srcStr = "This is java default pkcs5padding PKCS5 TEST"; System.out.println(srcStr); //設置key 全8,iv,全1,這裏測試用 for (int i = 0; i <32; i++) { key[i] = 8; if (i < 16) {iv[i] = 1;} } byte[] encbt = AES_cbc_encrypt(srcStr.getBytes(),key,iv); byte[] decbt = AES_cbc_decrypt(encbt,key,iv); String decStr = new String(decbt); System.out.println(decStr); if(srcStr.equals(decStr)) { System.out.println("TEST PASS"); }else { System.out.println("TEST NO PASS"); } }
輸出:
This is java default pkcs5padding PKCS5 TEST This is java default pkcs5padding PKCS5 TEST TEST PASS
總結:此處使用的是java提供的PKCS5填充方式,其實和PKCS7是同樣的,因此在ios上使用pkcs7,安卓上使用pkcs5,只要key和iv保持一致,相互加解密是沒有問題的
完整的代碼以下
import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.util.Base64; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class TestPKCS5 { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; //加密 public static byte[] AES_cbc_encrypt(byte[] srcData,byte[] key,byte[] iv) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] encData = cipher.doFinal(srcData); return encData; } //解密 public static byte[] AES_cbc_decrypt(byte[] encData,byte[] key,byte[] iv) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] decbbdt = cipher.doFinal(encData); return decbbdt; } public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { byte[] key= new byte[32]; byte[] iv = new byte[16]; String srcStr = "This is java default pkcs5padding PKCS5 TEST"; System.out.println(srcStr); //設置key 全8,iv,全1,這裏測試用 for (int i = 0; i <32; i++) { key[i] = 8; if (i < 16) {iv[i] = 1;} } byte[] encbt = AES_cbc_encrypt(srcStr.getBytes(),key,iv); byte[] decbt = AES_cbc_decrypt(encbt,key,iv); String decStr = new String(decbt); System.out.println(decStr); if(srcStr.equals(decStr)) { System.out.println("TEST PASS"); }else { System.out.println("TEST NO PASS"); } } }
4. 使用 BouncyCastle庫 進行 AES_cbc_256 指定PKCS7方式加密解密
須要先去 http://www.bouncycastle.org/latest_releases.html 下載 庫,而且導入到工程中
以下封裝
//AES_256_cbc pkcs7 private static final String ALGORITHM = "AES/CBC/PKCS7Padding"; //加密 public static byte[] AES_cbc_encrypt(byte[] srcData,byte[] key,byte[] iv) { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(ALGORITHM,"BC"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] encData = cipher.doFinal(srcData); return encData; } //解密 public static byte[] AES_cbc_decrypt(byte[] encData,byte[] key,byte[] iv) { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(ALGORITHM,"BC"); cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] decbbdt = cipher.doFinal(encData); return decbbdt; }
調用測試代碼
public static void main(String[] args) { // TODO Auto-generated method stub byte[] key= new byte[32]; byte[] iv = new byte[16]; String srcStr = "This is java bcprovlib pkcs7padding PKCS7 TEST"; System.out.println(srcStr); //設置key 全8,iv,全1,這裏測試用 for (int i = 0; i <32; i++) { key[i] = 8; if (i < 16) {iv[i] = 1;} } byte[] encbt = AES_cbc_encrypt(srcStr.getBytes(),key,iv); byte[] decbt = AES_cbc_decrypt(encbt,key,iv); String decStr = new String(decbt); System.out.println(decStr); if(srcStr.equals(decStr)) { System.out.println("TEST PASS"); }else { System.out.println("TEST NO PASS"); } }
輸出結果:
This is java bcprovlib pkcs7padding PKCS7 TEST
This is java bcprovlib pkcs7padding PKCS7 TEST
TEST PASS
總結:此處使用BC庫的方式指定PKCS7方式,這樣就和ios pc保持一致了;不過使用上面第一種方式也是可行的
完整的代碼以下
import java.util.Base64; import java.io.UnsupportedEncodingException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.util.Arrays; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; public class TestAES { //AES_256_cbc pkcs7 private static final String ALGORITHM = "AES/CBC/PKCS7Padding"; //加密 public static byte[] AES_cbc_encrypt(byte[] srcData,byte[] key,byte[] iv) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(ALGORITHM,"BC"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] encData = cipher.doFinal(srcData); return encData; } //解密 public static byte[] AES_cbc_decrypt(byte[] encData,byte[] key,byte[] iv) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); Security.addProvider(new BouncyCastleProvider()); Cipher cipher = Cipher.getInstance(ALGORITHM,"BC"); cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv)); byte[] decbbdt = cipher.doFinal(encData); return decbbdt; } public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException { // TODO Auto-generated method stub byte[] key= new byte[32]; byte[] iv = new byte[16]; String srcStr = "This is java bcprovlib pkcs7padding PKCS7 TEST"; System.out.println(srcStr); //設置key 全8,iv,全1,這裏測試用 for (int i = 0; i <32; i++) { key[i] = 8; if (i < 16) {iv[i] = 1;} } byte[] encbt = AES_cbc_encrypt(srcStr.getBytes(),key,iv); byte[] decbt = AES_cbc_decrypt(encbt,key,iv); String decStr = new String(decbt); System.out.println(decStr); if(srcStr.equals(decStr)) { System.out.println("TEST PASS"); }else { System.out.println("TEST NO PASS"); } } }
測試使用 jdk1.8