Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 平台DES IV 加密解密隨筆

Android 平台DES IV 加密解密隨筆

編輯:關於Android編程

Android 平台DES IV 加密解密隨筆

好記性不如爛筆頭,所以開始寫博客了,一方面加深自己的印象,另一方面給後面初學者參考,幫助少走彎路,不論難易,有些東西可能理解的不深,歡迎各位高手指導賜教加吐槽!

DES加密接觸過好多次了,但總容易忘,和服務器交互時,加出來不一致後面能解密成功但是頭部是亂碼導致小坑了一會,在次記錄下來~

根據網上資料和自己的理解,DES是一個基於56位密鑰的對稱的加密算法,就是兩邊的密鑰需要一致,在此就不考慮為什麼不用安全性更高的AES或者采用非對稱加密方法,比如RSA等等;關於密鑰空間小,可以使用DES的派生算法3DES來進行加密。DES算法是把64位的明文輸入塊變成64位的密文輸出塊,所以這裡需要BASE64編解碼工具類,加密需要3個參數(Key、Data、Mode) Mode是加密還是解密,其它就不解釋了,注釋寫的比較清楚。

下面是加密解密方法:

public class EncryptUtils {
	public static String encryptDES(String encryptString, String encryptKey)
			throws Exception {
		//返回實現指定轉換的 Cipher 對象	“算法/模式/填充”
		Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
		//創建一個 DESKeySpec 對象,使用 8 個字節的key作為 DES 密鑰的密鑰內容。
		DESKeySpec desKeySpec = new DESKeySpec(encryptKey.getBytes("UTF-8"));
		//返回轉換指定算法的秘密密鑰的 SecretKeyFactory 對象。 
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		//根據提供的密鑰生成 SecretKey 對象。
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		//使用 iv 中的字節作為 IV 來構造一個 IvParameterSpec 對象。復制該緩沖區的內容來防止後續修改。
		IvParameterSpec iv = new IvParameterSpec(encryptKey.getBytes());
		//用密鑰和一組算法參數初始化此 Cipher;Cipher:加密、解密、密鑰包裝或密鑰解包,具體取決於 opmode 的值。
		cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
		//加密同時解碼成字符串返回
		return new String(BASE64.encode(cipher.doFinal(encryptString
				.getBytes("UTF-8"))));
	}

	public static String decryptDES(String decodeString, String decodeKey) throws Exception {
			//使用指定密鑰構造IV
			IvParameterSpec iv = new IvParameterSpec(decodeKey.getBytes());
			//根據給定的字節數組和指定算法構造一個密鑰。 
			SecretKeySpec skeySpec = new SecretKeySpec(decodeKey.getBytes(), "DES");
			//返回實現指定轉換的 Cipher 對象
			Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
			//解密初始化
			cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
			//解碼返回
			byte[] byteMi = BASE64.decode(decodeString.toCharArray());
			byte decryptedData[] = cipher.doFinal(byteMi);
			return new String(decryptedData);
	}
}


幾個錯誤需要解釋下:

java.security.InvalidAlgorithmParameterException: IV must be 8 bytes long.
java.security.InvalidKeyException: key too short

這兩種錯誤都是key的長度造成的,但官方說密鑰是56位長度,這個有點不太明白,但你只要記住key的長度必須是8位!這個地方還請高手賜教!

IV向量:主要作用就是防止篡改的,這個地方如果不一致會導致數據的頭部解出來是亂碼,而後面正常。


BASE64 編解碼工具類

public class BASE64 {
	static public char[] encode(byte[] data) {
		char[] out = new char[((data.length + 2) / 3) * 4];
		for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
			boolean quad = false;
			boolean trip = false;
			int val = (0xFF & (int) data[i]);
			val <<= 8;
			if ((i + 1) < data.length) {
				val |= (0xFF & (int) data[i + 1]);
				trip = true;
			}
			val <<= 8;
			if ((i + 2) < data.length) {
				val |= (0xFF & (int) data[i + 2]);
				quad = true;
			}
			out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
			val >>= 6;
			out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
			val >>= 6;
			out[index + 1] = alphabet[val & 0x3F];
			val >>= 6;
			out[index + 0] = alphabet[val & 0x3F];
		}
		return out;
	}

	static public byte[] decode(char[] data) {
		int len = ((data.length + 3) / 4) * 3;
		if (data.length > 0 && data[data.length - 1] == '=')
			--len;
		if (data.length > 1 && data[data.length - 2] == '=')
			--len;
		byte[] out = new byte[len];
		int shift = 0;
		int accum = 0;
		int index = 0;
		for (int ix = 0; ix < data.length; ix++) {
			int value = codes[data[ix] & 0xFF];
			if (value >= 0) {
				accum <<= 6;
				shift += 6;
				accum |= value;
				if (shift >= 8) {
					shift -= 8;
					out[index++] = (byte) ((accum >> shift) & 0xff);
				}
			}
		}
		if (index != out.length)
			throw new Error("miscalculated data length!");
		return out;
	}

	static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
			.toCharArray();
	static private byte[] codes = new byte[256];
	static {
		for (int i = 0; i < 256; i++)
			codes[i] = -1;
		for (int i = 'A'; i <= 'Z'; i++)
			codes[i] = (byte) (i - 'A');
		for (int i = 'a'; i <= 'z'; i++)
			codes[i] = (byte) (26 + i - 'a');
		for (int i = '0'; i <= '9'; i++)
			codes[i] = (byte) (52 + i - '0');
		codes['+'] = 62;
		codes['/'] = 63;
	}
}

加密解密使用

\

\

	try {
		String en_Str = EncryptUtils.encryptDES("data20141117", "key12345");
		String de_Str = EncryptUtils.decryptDES(en_Str, "key12345");
		Log.i("MainActivity", "en_Str:"+en_Str);
		Log.i("MainActivity", "de_Str:"+de_Str);
	} catch (Exception e) {
		e.printStackTrace();
	}


  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved