如何加密和解密应用存储中的文件

问题描述 投票:0回答:2

为了保护应用程序存储的安全,我使用

EncryptedStorage
加密了存储,如此处所述。也就是说,

EncryptedStorage.install("your-pass-encryption-key")

我创建了一个文本文件,供另一台设备中的同一应用程序共享和打开/使用。

问题是该文件无法在其他设备中打开/使用。它说这个文件已加密。

如何解密它以便能够在另一设备的同一应用程序中打开或使用它?

编辑

我执行了以下操作来创建要共享的文件作为 .txt 文件,以便能够使用

plain/text
mime 类型来共享它。

String databasePath = Display.getInstance().getDatabasePath("TestDB.db");
String mimeType = "application/vnd.sqlite3";
mimeType = "application/x-sqlite3";
mimeType = "plain/text";

try {
    FileSystemStorage fss = FileSystemStorage.getInstance();
    InputStream is = fss.openInputStream(databasePath);

    //Copy from FSS to Storage
    Util.copy(is, Storage.getInstance().createOutputStream("TestDB.txt"));
    String fileToSharePath = FileSystemStorage.getInstance().getAppHomePath() + "TestDB.txt";
    Log.p("FileToSharePath " + fileToSharePath);
    Display.getInstance().share(fileToSharePath, null, mimeType);
} catch (IOException e) {
    Log.p("Share error: " + e);
}

我执行了以下操作,在另一台设备中使用

FileChooser
浏览共享文件,并将其另存为应用程序数据库目录中的 .db 文件。

FileChooser.showOpenDialog("txt", ev -> {

    if (ev == null) {
        Log.p("no file selected");
    } else {
        String filePath = (String) ev.getSource();
        Log.p("FilePath " + filePath);
        try {
            FileSystemStorage fss = FileSystemStorage.getInstance();
            InputStream is = fss.openInputStream(filePath);

            String databasePath = Display.getInstance().getDatabasePath("TestDB.db");
            OutputStream os = FileSystemStorage.getInstance().openOutputStream(databasePath);
            Util.copy(is, os);
        } catch (IOException e) {
                Log.p("Create DB error: " + e);
        }
    }
});
codenameone
2个回答
1
投票

您在这一行中使用

Storage
而不是
FileSystemStorage

Util.copy(is, Storage.getInstance().createOutputStream("TestDB.txt"));

这会加密文件,请注意,这无论如何都不能在设备上一致地工作...但是然后您再次使用

FileSystemStorage
来读取数据(已加密)。

String fileToSharePath = FileSystemStorage.getInstance().getAppHomePath() + "TestDB.txt";

解决方案是使用

FileSystemStorage
来分享您想要分享的所有内容。用这种方式加密数据库文件无论如何是行不通的。


1
投票

以下内容将创建一个加密的

SampleText.txt
到应用程序存储,在文本编辑器中打开时无法读取。它只能由应用程序读取。

   EncryptedStorage.install("your-pass-encryption-key")
                
   private void writeAndReadCipherFile() {
    try {    
        //write encrypted file to the app storage
        try (Writer w = new OutputStreamWriter(Storage.getInstance().createOutputStream("SampleText.txt"))) {
            w.write("Hey there big brother");
        } catch (Exception e) {
            Log.p("Error " + e);
        }

        //read encrypted file from the app storage
        InputStream is = Storage.getInstance().createInputStream("SampleText.txt");
        int nextChar = is.read();
      
        StringBuilder sb = new StringBuilder();
        while (nextChar > -1) {
            sb.append((char) nextChar);
            nextChar = is.read();
        }
        
        Log.p("FileContent " + sb.toString());
    } catch (Exception e) {
        Log.p("Error " + e);
    }
}

以下使用

BouncyCastle
读取并加密数据库文件内容,并将加密后的数据库文件保存在应用程序主路径目录中
home/.cn1
它还读取加密的文件内容,解密并将解密的文件保存在
home/.cn1
中。

ISO-8859-1
中需要进行编码,以确保按预期读取文件字节中的所有字符。
OutputStreamWriter
编码也尝试,但一些十六进制被读为
Windows-1252
?

以下
private void encryptDatabaseFile() { try { String filePath = Display.getInstance().getDatabasePath("TestDB.db"); FileSystemStorage fss = FileSystemStorage.getInstance(); InputStream is = fss.openInputStream(filePath); byte[] plainBytes = Util.readInputStream(is); //encrypt database file content byte[] cipherByteArray = FilesCipher.encryptFile(plainBytes); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(cipherByteArray); String encryptedFilePath = fss.getAppHomePath() + "EncryptedDB.db"; try (Writer w = new OutputStreamWriter(fss.openOutputStream(encryptedFilePath), "ISO-8859-1")) {//ISO-8859-1 Windows-1252 UTF-8 int nextChar = byteArrayInputStream.read(); while (nextChar > -1) { char[] charArray = {(char) nextChar}; w.write(charArray); nextChar = byteArrayInputStream.read(); } } catch (Exception e) { Log.p("Error " + e); } //decrypt database file content InputStream decryptInputStream = fss.openInputStream(encryptedFilePath); byte[] cipherBytes = Util.readInputStream(decryptInputStream); byte[] plainByteArray = FilesCipher.decryptFile(cipherBytes); ByteArrayInputStream decryptedInputStream = new ByteArrayInputStream(plainByteArray); String decryptedFilePath = fss.getAppHomePath() + "DecryptedDB.db"; try (Writer w = new OutputStreamWriter(fss.openOutputStream(decryptedFilePath), "ISO-8859-1")) {//ISO-8859-1 Windows-1252 UTF-8 int nextChar = decryptedInputStream.read(); while (nextChar > -1) { char[] charArray = {(char) nextChar}; w.write(charArray); nextChar = decryptedInputStream.read(); } } catch (Exception e) { Log.p("Error " + e); } } catch (Exception e) { Log.p("Error " + e); } }

类处理加密和解密

FilesCipher

这也使得数据库加密成为可能。也就是说,创建数据库后,可以使用
import com.codename1.io.Log; import java.io.UnsupportedEncodingException; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.CryptoException; import org.bouncycastle.crypto.engines.AESEngine; import org.bouncycastle.crypto.modes.CBCBlockCipher; import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.encoders.Base64; public class FilesCipher { private static PaddedBufferedBlockCipher cipher; private static final String SECRET_KEY = "Your 16 Character Secret Key"; private static final String I_VECTOR = "Your 16 Character initialization vector"; public static byte[] encryptFile(byte[] plainBytes) { byte[] byteArray = null; try { cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); byte sKey[] = SECRET_KEY.getBytes("UTF-8"); byte[] iv = I_VECTOR.getBytes("UTF-8"); KeyParameter keyParam = new KeyParameter(sKey); CipherParameters ivAndKey = new ParametersWithIV(keyParam, iv); cipher.init(true, ivAndKey); byte[] cipherBytes = cipherData(plainBytes); byteArray = Base64.encode(cipherBytes); } catch (UnsupportedEncodingException | IllegalArgumentException | CryptoException e) { Log.p("Error " + e); } return byteArray; } public static byte[] decryptFile(byte[] cipherBytes) { byte[] byteArray = null; try { cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); byte sKey[] = SECRET_KEY.getBytes("UTF-8"); byte[] iv = I_VECTOR.getBytes("UTF-8"); KeyParameter keyParam = new KeyParameter(sKey); byte[] cipherData = Base64.decode(cipherBytes); CipherParameters ivAndKey = new ParametersWithIV(keyParam, iv); cipher.init(false, ivAndKey); byteArray = cipherData(cipherData); } catch (UnsupportedEncodingException | IllegalArgumentException | CryptoException e) { Log.p("Error " + e); } return byteArray; } private static byte[] cipherData(byte[] data) throws CryptoException { int minSize = cipher.getOutputSize(data.length); byte[] outBuf = new byte[minSize]; int len1 = cipher.processBytes(data, 0, data.length, outBuf, 0); int len2 = cipher.doFinal(outBuf, len1); int actualLen = len1 + len2; byte[] result = new byte[actualLen]; System.arraycopy(outBuf, 0, result, 0, result.length); return result; } }

加密该数据库文件,然后将其另存为数据库。

在执行 

FilesCipher.encryptFile()

查询之前,使用

Create, Read, Update & Delete
解密数据库文件。
执行查询后,使用 

FilesCipher.decryptFile()

 再次加密数据库
    

© www.soinside.com 2019 - 2024. All rights reserved.