0

作为一个学校项目,我试图实现以下目标: - 列出文件夹中的所有文件(图片)。一张一张地浏览每张图片,并使用 AES 对它们进行密码加密。

这是一个安全加密图片的应用程序,只有您才能解密和查看它们 - 只要您有正确的密码。

到目前为止,我能够获取文件夹/目录中的所有文件名,并且只加密一个指定的文件。问题是,我不知道如何浏览列表,并将所有文件加密到最后。

这是我目前正在使用的代码:

package com.example.secretpictures;
import java.io.File; 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;


import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.spec.SecretKeySpec;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;

public class EncryptService extends Service {
private static final String TAG = EncryptService.class.getSimpleName();
@Override
public IBinder onBind(Intent intent) {
    return null;



}
@Override
public void onCreate() {
    // TODO Auto-generated method stub
    super.onCreate();

Log.d(TAG, "OnCreate");
}


@SuppressLint("SdCardPath")
@Override
public void onStart(Intent intent, int startId) {
    // TODO Auto-generated method stub
    super.onStart(intent, startId);

Log.d(TAG, "OnStart");

File file[] = Environment.getExternalStorageDirectory().listFiles();
recursiveFileFind(file);


try {

FileInputStream fis = new FileInputStream("/mnt/sdcard/secretpictures/yolo.png");
// This stream write the encrypted text. This stream will be wrapped by another stream.
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/secretpictures/yolo2.enc");

// Length is 16 byte
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();


} catch (IOException  e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

Log.d(TAG, "OnDestroy");
}



public void recursiveFileFind(File[] file1){
int i = 0;
String filePath="";
 if(file1!=null){
while(i!=file1.length){
    filePath = file1[i].getAbsolutePath();
        if(file1[i].isDirectory()){
                File file[] = file1[i].listFiles();
            recursiveFileFind(file);
            }
        i++;
        Log.d(i+"", filePath);

}
}
}   
}

如您所见,它的编码非常难看,但现在可以完成工作了。创建 mainactivity 时调用此服务。

此行指定要加密的文件: FileInputStream fis = new FileInputStream("/mnt/sdcard/secretpictures/yolo.png");

一种方法是如何让输入流通过File file[] = file1[i].listFiles();加密所有文件?

4

1 回答 1

0

一旦你有一个File在你的代码中显示的可以找到文件的对象,你就可以FileInputStream使用构造函数获取该文件的一个对象FileInputStream(File)

关于您的加密系统的一些说明。它不是很安全。没有特别的顺序

  • 您直接使用 UTF-8 字节,而无需为您的密钥材料添加盐。使用像PBKDF2这样的密钥扩展算法,并用盐将密码字节提供给它。您可以将盐存储为带有加密图像的明文。

  • 您正在使用AES. 这扩展为AES/ECB/PKCS5PaddingECB不是加密超过 1 个纯文本块(AES 为 16 个字节)的安全模式。由于相同的输入明文导致相同的输出密文,ECB 未能隐藏明文中的模式。由于重复模式,图像特别容易受到这种影响。有关 ECB 的更多信息,请参阅此Wikipedia 文章,它还提供了一个加密图像作为示例。您可以使用的大多数其他模式(CBC、CTR 等)都需要 IV,IV 应该是随机生成的,您可以将其与加密图像一起明文存储。

于 2013-11-03T13:30:56.430 回答