java aes_cbc_256 加密解密


在之前我們在openssl上和ios上分別測試了 AES256位cbc模式的加密和解密

今天用java提供的api來測試一下;進而確定一下在PC,iOS,安卓上三個平台下的加密解密數據;

1. 首先通過查詢資料了解到:

  • java的jdk 不支持256位AES密鑰,需要安裝擴展包,以下會提到
  • java 中默認不支持PKCS7 填充方式,支持PKCS5,經測試PKCS5和pkcs7沒多大區別(在多平台數據互測上)
  • java中如果非要指定PKCS7 需要借助 BouncyCastle(java用的密碼學類庫)

2. 關於安裝 支持AES 256位密鑰的擴展包

   下載http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

   下載之后得到 local_policy.jar ,US_export_policy.jar 兩個jar包,把這兩個jar包放到 jdk/lib/security 目錄下

   替換原來的兩個jar包即可

 

3.  使用java api 進行 AES_cbc_256位密鑰 PKCS5 填充方式的加密解密

   如下封裝

    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;
    }

測試調用

    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
View Code

總結:此處使用的是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
View Code

總結:此處使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM