如何在Android中使用AES从SD卡加密文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10782187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:56:57  来源:igfitidea点击:

How to encrypt file from SD card using AES in Android?

androidfileencryptionaes

提问by user1421273

I want to encrypt image from the sd card and store it again in SD card again using AES. The main idea is the application browse an image, then encrypt it when I push a button, then store it in sd card. so my image would be secure.

我想从 sd 卡加密图像并使用 AES 再次将其存储在 SD 卡中。主要思想是应用程序浏览图像,然后在我按下按钮时对其进行加密,然后将其存储在 SD 卡中。所以我的形象是安全的。

I already succeed do string encryption using AES from this tutorial http://www.androidsnippets.com/encryptdecrypt-strings, but I don't have idea how to do this with an image, not string.

我已经成功地使用本教程http://www.androidsnippets.com/encryptdecrypt-strings 中的AES 进行字符串加密,但我不知道如何使用图像而不是字符串来执行此操作。

This is how I do it with a string:

这就是我使用字符串的方式:

public static String encrypt(String seed, String cleartext) throws Exception  
{
    byte[] rawKey = getRawKey(seed.getBytes());
    byte[] result = encrypt(rawKey, cleartext.getBytes()); 
    return toHex(result);
}

private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception 
{
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

Can anyone help me give example code how to encrypt an imagewith AES?

谁能帮我提供示例代码,如何使用 AES加密图像

maybe it must using I/O file stream but I don't have an idea how to implement with this code.

也许它必须使用 I/O 文件流,但我不知道如何使用此代码实现。

回答by Kiril

If you take user input for the password make sure to read this answer.

如果您让用户输入密码,请务必阅读此答案

You should take a look at: CipherInputStreamand CipherOutputStream. They are used to encrypt and decrypt byte streams.

你应该看看: CipherInputStreamCipherOutputStream。它们用于加密和解密字节流。

I have a file named cleartext. The file contains:

我有一个名为cleartext. 该文件包含:

Hi, I'm a clear text.
How are you?
That's awesome!
Hi, I'm a clear text.
How are you?
That's awesome!

Now, you have an encrypt()function:

现在,你有一个encrypt()函数:

static void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    // Here you read the cleartext.
    FileInputStream fis = new FileInputStream("data/cleartext");
    // This stream write the encrypted text. This stream will be wrapped by another stream.
    FileOutputStream fos = new FileOutputStream("data/encrypted");

    // Length is 16 byte
    // Careful when taking user input!!! https://stackoverflow.com/a/3452620/1188357
    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
    // Create cipher
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, sks);
    // Wrap the output stream
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    // Write bytes
    int b;
    byte[] d = new byte[8];
    while((b = fis.read(d)) != -1) {
        cos.write(d, 0, b);
    }
    // Flush and close streams.
    cos.flush();
    cos.close();
    fis.close();
}

After you execute this function, there should be a file names encrypted. The file contains the encrypted characters.

执行此函数后,应该有一个文件名encrypted。该文件包含加密字符。

For decryption you have the decryptfunction:

对于解密,您具有以下decrypt功能:

static void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
    FileInputStream fis = new FileInputStream("data/encrypted");

    FileOutputStream fos = new FileOutputStream("data/decrypted");
    SecretKeySpec sks = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.DECRYPT_MODE, sks);
    CipherInputStream cis = new CipherInputStream(fis, cipher);
    int b;
    byte[] d = new byte[8];
    while((b = cis.read(d)) != -1) {
        fos.write(d, 0, b);
    }
    fos.flush();
    fos.close();
    cis.close();
}

After the execution of decrypt, there should be a file named decrypted. This file contains the free text.

执行解密后,应该有一个名为decrypted. 该文件包含自由文本。

You write you're a "noob" but depending on the use-case of encryption you could do a lot of harm if you're not doing it the right way. Know your tools!

你写你是一个“菜鸟”,但根据加密的用例,如果你没有以正确的方式进行加密,你可能会造成很多伤害。了解你的工具!

Usage of CipherOutputStream Oracle documentation:

CipherOutputStream Oracle 文档的使用

SecretKeySpec skeySpec = new SecretKeySpec(y.getBytes(), "AES");

FileInputStream fis;
FileOutputStream fos;
CipherOutputStream cos;
// File you are reading from
fis = new FileInputStream("/tmp/a.txt");
// File output
fos = new FileOutputStream("/tmp/b.txt");

// Here the file is encrypted. The cipher1 has to be created.
// Key Length should be 128, 192 or 256 bit => i.e. 16 byte
SecretKeySpec skeySpec = new SecretKeySpec("MyDifficultPassw".getBytes(), "AES"); 
Cipher cipher1 = Cipher.getInstance("AES");  
cipher1.init(Cipher.ENCRYPT_MODE, skeySpec);
cos = new CipherOutputStream(fos, cipher1);
// Here you read from the file in fis and write to cos.
byte[] b = new byte[8];
int i = fis.read(b);
while (i != -1) {
    cos.write(b, 0, i);
    i = fis.read(b);
}
cos.flush();

Thus, the encryption should work. When you reverse the process, you should be able to read the decrypted bytes.

因此,加密应该有效。当您反转该过程时,您应该能够读取解密的字节。