簡體   English   中英

如何在Android中加密和解密文件?

[英]How to encrypt and decrypt file in Android?

我想加密文件並將其存儲在 SD 卡中。 我想解密那個加密文件並再次將其存儲在 SD 卡中。 我試圖通過將文件作為文件流打開並加密來加密文件,但它不起作用。 我想知道如何做到這一點。

使用CipherOutputStreamCipherInputStreamCipher和您的FileInputStream / FileOutputStream

我會建議像Cipher.getInstance("AES/CBC/PKCS5Padding")來創建Cipher類。 CBC 模式是安全的,沒有ECB 模式對非隨機明文漏洞 它應該存在於任何通用加密庫中,以確保高兼容性。

如果您想使用相同的密鑰加密多個文件,請不要忘記使用由安全隨機生成器生成的初始化向量(IV)。 您可以在密文開頭添加普通 IV 的前綴。 它的大小總是正好是一個塊(16 字節)。

如果您想使用密碼,請確保您確實使用了良好的密鑰派生機制(查找基於密碼的加密或基於密碼的密鑰派生)。 PBKDF2 是最常用的基於密碼的密鑰派生方案,它存在於大多數 Java 運行時中,包括 Android。 請注意,SHA-1 是一個有點過時的哈希函數,但它在 PBKDF2 中應該沒問題,並且目前確實提供了最兼容的選項。

在編碼/解碼字符串時總是指定字符編碼,否則當平台編碼與之前的編碼不同時你會遇到麻煩。 換句話說,不要使用String.getBytes()而是使用String.getBytes(StandardCharsets.UTF_8)

為了使其更安全,請通過在密文和 IV 上添加安全校驗和(MAC 或 HMAC)來添加加密完整性和真實性,最好使用不同的密鑰。 如果沒有身份驗證標簽,密文可能會以無法檢測到的方式更改。

請注意, CipherInputStream可能不會報告BadPaddingException ,這包括為經過身份驗證的密碼(例如 GCM)生成的BadPaddingException 這將使這些類型的經過身份驗證的密碼的流不兼容和不安全。

我有一個類似的問題,對於加密/解密,我想出了這個解決方案:

public static byte[] generateKey(String password) throws Exception
{
    byte[] keyStart = password.getBytes("UTF-8");

    KeyGenerator kgen = KeyGenerator.getInstance("AES");
    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
    sr.setSeed(keyStart);
    kgen.init(128, sr);
    SecretKey skey = kgen.generateKey();
    return skey.getEncoded();
}

public static byte[] encodeFile(byte[] key, byte[] fileData) throws Exception
{

    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(fileData);

    return encrypted;
}

public static byte[] decodeFile(byte[] key, byte[] fileData) throws Exception
{
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);

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

    return decrypted;
}

要將加密文件保存到 sd,請執行以下操作:

File file = new File(Environment.getExternalStorageDirectory() + File.separator + "your_folder_on_sd", "file_name");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
byte[] yourKey = generateKey("password");
byte[] filesBytes = encodeFile(yourKey, yourByteArrayContainigDataToEncrypt);
bos.write(fileBytes);
bos.flush();
bos.close();

要解碼文件,請使用:

byte[] yourKey = generateKey("password");
byte[] decodedData = decodeFile(yourKey, bytesOfYourFile);

為了將文件讀入字節數組,有一種不同的方式。 一個例子: http : //examples.javacodegeeks.com/core-java/io/fileinputstream/read-file-in-byte-array-with-fileinputstream/

您可以使用java-aes-cryptoFacebook 的 Conceal

java-aes-crypto

從回購報價

一個用於加密和解密字符串的簡單 Android 類,旨在避免大多數此類類所遭受的經典錯誤。

臉書的隱藏

從回購報價

Conceal 提供簡單的 Android API 來執行數據的快速加密和身份驗證

將CipherOutputStream或CipherInputStream與Cipher和FileOutputStream / FileInputStream一起使用。

我們有一個相同的問題,它由我的問題線程中的某個人解決。 您應該看看:CipherInputStream和CipherOutputStream。 它們用於加密和解密字節流。 有關詳細的源代碼,請查看此鏈接中的Kiril答案: 如何在Android中使用AES從SD卡加密文件?

我有同樣的問題,我從這段代碼中得到了解決方案。

private static final String ALGO = "AES";
private static final byte[] keyValue = new byte[] { 'o', 'n', 'e', 'n','e', 't', 'e','d', 'o', 'c', 'e', 'i', 'r', 's', 'r', 'p' };
    public static String decrypt(String encryptedData){
        String decryptedValue = null;
        try{
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        decryptedValue = new String(decValue);
    }catch(Exception e){
        //LOGGER.error("In TD:" + e);
        //Teneno_StartupService.loadForConnectionFailed();
    }
    return decryptedValue;
}
private static Key generateKey(){
    Key key = new SecretKeySpec(keyValue, ALGO);
    return key;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM