編輯:關於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(); }
我們寫程序的時候都希望能寫出一個沒有任何Bug的程序,期望在任何情況下都不會發生程序崩潰。不過理想是豐滿的,現實是骨感的。沒有一個程序員能保證自己寫的程序絕對不會出現異常
今天去面試,一面還可以,到了第二面的時候也差不多吧,最後來了一題,說那個360被卸載之後會跳轉到指定的反饋頁面,是怎麼弄的?這個之前沒有研究過,但是這個效果是見過的。當時
只是簡單的實現了效果,界面沒怎麼做優化,不過那都是次要的啦!!相信大家都迫不及待的想看效果圖了吧,其中主要的彩票視圖類和橡皮擦類都是通過代碼的方式構建視圖,布
在前面的Linux文件系統Inotify機制 中介紹了Linux對文件變更監控過程。Android系統在此基礎上封裝了一個FileObserver類來方便使用Inotif