移動應用安全開發指南(Android)--數據存儲

一、數據存儲

概述java

移動應用常常須要在某些場景下(好比用戶登陸)處理和用戶或業務相關的敏感數據,有時候爲知足某些業務需求,須要把這些敏感數據存儲在本地,若是不對這些數據進行適當處理,就有可能存在敏感信息泄漏的風險。android

安全準則算法

A.      敏感數據老是優先考慮存儲在內部空間。chrome

B.      敏感數據不管是存儲在內部仍是外部空間均應通過加密後再存儲,應避免直接明文存儲。瀏覽器

C.      避免將敏感數據存儲在全局可訪問的緩存裏(如log、剪切板等)。緩存

D.      敏感數據避免硬編碼在代碼裏面,常見的有用戶帳戶口令和加密密鑰等。安全

詳細描述session

A.      可使用JDK提供的javax.crypto包進行加/解密,注意加密算法的選擇以及密鑰複雜度策略(參考第6條以及附錄1)。app

B.      使用System.out.print系列以及android.util.Log類的方法(好比Log.d())會將日誌存儲在系統緩衝區,任意應用均可以經過logcat指令查看緩存裏面的敏感信息(好比密碼和sessionID等),所以Release版本應移除這些主要用於debug的方法。dom

備註

A.      常見的敏感數據有用戶口令、用戶我的信息和sessionID等等,但也有一些是和業務強相關的,當不太容易判斷時,能夠和安全工程師一塊兒確認。

B.      Android使用沙箱技術對不一樣應用之間的內部存儲空間進行了隔離,但考慮到應用自身的漏洞(好比SQL注入)和ROOT的場景,對內部存儲數據進行加密仍是很是必要的。

提示:若是IE顯示不正常,請使用chrome瀏覽器

附錄1:

1、安全的加/解密方案:

1.1AES128對稱加密方案:

 public class AES128Enc {

         public static String encrypt(byte[] rawKey, String cleartext) throws Exception {     

        SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");     

        Cipher cipher = Cipher.getInstance("AES");     

        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);     

        byte[] encrypted = cipher.doFinal(cleartext.getBytes());

        return toHex(encrypted);     

    }     

         

    public static String decrypt(byte[] rawKey, String encrypted) throws Exception {       

        byte[] enc = toByte(encrypted);     

        SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");     

        Cipher cipher = Cipher.getInstance("AES");     

        cipher.init(Cipher.DECRYPT_MODE, skeySpec);     

        byte[] decrypted = cipher.doFinal(enc);

        return new String(decrypted);     

    }     

    

    /* 產生隨機的128bit AES密鑰 */

    public static byte[] getRawKey(byte[] seed) throws Exception {     

        KeyGenerator kgen = KeyGenerator.getInstance("AES");     

        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");     

        sr.setSeed(seed);     

        kgen.init(128, sr);      

        SecretKey skey = kgen.generateKey();     

        byte[] raw = skey.getEncoded();     

        return raw;     

    }                   

         

    public static byte[] toByte(String hexString) {     

        int len = hexString.length()/2;     

        byte[] result = new byte[len];     

        for (int i = 0; i < len; i++)     

            result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();     

        return result;     

    }     

    

    public static String toHex(byte[] buf) {     

        if (buf == null)     

            return "";     

        StringBuffer result = new StringBuffer(2*buf.length);     

        for (int i = 0; i < buf.length; i++) {     

            appendHex(result, buf[i]);     

        }     

        return result.toString();     

    } 

   

    private final static String HEX = "0123456789ABCDEF";     

    private static void appendHex(StringBuffer sb, byte b) {     

        sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));

    }

}

1.2SHA256哈希算法:

public class Sha256Hash {

    private static byte [] getHash(String strForHash) {

        MessageDigest digest = null ;

        try {

            digest = MessageDigest. getInstance( "SHA-256");

        } catch (NoSuchAlgorithmException e1) {

            e1.printStackTrace();

        }

        digest.reset();

        return digest.digest(strForHash.getBytes());

    }

 

    public static String bin2hex(String strForHash) {

        byte [] data = getHash(strForHash);

        return String.format( "%0" + (data.length * 2) + "X", new BigInteger(1, data));

    }

}

相關文章
相關標籤/搜索