標籤:android base64 解密 加密 des
Android 平台DES IV 加密解密隨筆
好記性不如爛筆頭,所以開始寫部落格了。一方面加深自己的理解,二方面給後面初學者少走彎路,不論難易,有些東西可能理解的不深,歡迎各位高手指導賜教加吐槽!
DES加密接觸過好多次了,但總容易忘,和伺服器互動時,加出來不一致後面能解密成功但是頭部是亂碼導致小坑了一會,在此記錄下來~
根據百度百科和自己的理解,DES是一個基於56位密鑰的對稱的密碼編譯演算法,就是兩邊的密鑰需要一致,在此就不考慮為什麼不用安全性更高的AES或者採用非對稱式加密方法,比如RSA等等;關於密鑰空間小,可以使用DES的派生演算法3DES來進行加密。DES演算法是把64位的明文輸入塊變成64位的密文輸出塊,所以這裡需要BASE64編解碼工具類,加密需要3個參數(Key、Data、Mode) Mode是加密還是解密,其它就不解釋了,注釋寫的比較清楚。
下面是加密解密方法:
<span style="font-size:18px;">public class EncryptUtils {<span style="white-space:pre"></span>public static String encryptDES(String encryptString, String encryptKey)<span style="white-space:pre"></span>throws Exception {<span style="white-space:pre"></span>//返回實現指定轉換的 Cipher 對象<span style="white-space:pre"></span>“演算法/模式/填充”<span style="white-space:pre"></span>Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");<span style="white-space:pre"></span>//建立一個 DESKeySpec 對象,使用 8 個位元組的key作為 DES 密鑰的金鑰產製原料。<span style="white-space:pre"></span>DESKeySpec desKeySpec = new DESKeySpec(encryptKey.getBytes("UTF-8"));<span style="white-space:pre"></span>//返迴轉換指定演算法的秘密密鑰的 SecretKeyFactory 對象。 <span style="white-space:pre"></span>SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");<span style="white-space:pre"></span>//根據提供的密鑰產生 SecretKey 對象。<span style="white-space:pre"></span>SecretKey secretKey = keyFactory.generateSecret(desKeySpec);<span style="white-space:pre"></span>//使用 iv 中的位元組作為 IV 來構造一個 IvParameterSpec 對象。複製該緩衝區的內容來防止後續修改。<span style="white-space:pre"></span>IvParameterSpec iv = new IvParameterSpec(encryptKey.getBytes());<span style="white-space:pre"></span>//用密鑰和一組演算法參數初始化此 Cipher;Cipher:加密、解密、密鑰封裝或密鑰解包,具體取決於 opmode 的值。<span style="white-space:pre"></span>cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);<span style="white-space:pre"></span>//加密同時解碼成字串返回<span style="white-space:pre"></span>return new String(BASE64.encode(cipher.doFinal(encryptString<span style="white-space:pre"></span>.getBytes("UTF-8"))));<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public static String decryptDES(String decodeString, String decodeKey) throws Exception {<span style="white-space:pre"></span>//使用指定密鑰構造IV<span style="white-space:pre"></span>IvParameterSpec iv = new IvParameterSpec(decodeKey.getBytes());<span style="white-space:pre"></span>//根據給定的位元組數組和指定演算法構造一個密鑰。 <span style="white-space:pre"></span>SecretKeySpec skeySpec = new SecretKeySpec(decodeKey.getBytes(), "DES");<span style="white-space:pre"></span>//返回實現指定轉換的 Cipher 對象<span style="white-space:pre"></span>Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");<span style="white-space:pre"></span>//解密初始化<span style="white-space:pre"></span>cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);<span style="white-space:pre"></span>//解碼返回<span style="white-space:pre"></span>byte[] byteMi = BASE64.decode(decodeString.toCharArray());<span style="white-space:pre"></span>byte decryptedData[] = cipher.doFinal(byteMi);<span style="white-space:pre"></span>return new String(decryptedData);<span style="white-space:pre"></span>}}</span>
幾個錯誤需要解釋下:
java.security.InvalidAlgorithmParameterException: IV must be 8 bytes long.
java.security.InvalidKeyException: key too short
這兩種錯誤都是key的長度造成的,但官方說密鑰是56位長度,這個有點不太明白,但你只要記住key的長度必須是8位!這個地方還請高手賜教!
IV向量:主要作用就是防止篡改的,這個地方如果不一致會導致資料的頭部解出來是亂碼,而後面正常。
BASE64 編解碼工具類
<span style="font-size:18px;">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;}}</span>
加密解密使用
Android 平台DES IV 加密解密隨筆