Android 文件加密解密(AES)

private static final String ALGORITHM = "AES";

=========================文件加密=================================

/**
 * 文件加密
 * @param secretKey 文件加密密钥
 * @param oldFiles 原始文件列表,需要加密的
 * @param newFiles 构造加密后的文件列表
 *(选择多个或者单个)多个文件加密
 */
@RequiresApi(api = Build.VERSION_CODES.O)
public  void newEncryptFiles(String secretKey, List<File> oldFiles, List<File> newFiles) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IOException {
    // 使用密钥字符串生成秘密密钥
    SecretKey secretKeySpec = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
    // 获取 AES 加密算法的实例
    Cipher cipher = Cipher.getInstance(ALGORITHM);
    // 使用秘密密钥初始化密码 cipher,设置为加密模式
    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
    //循环复制文件
    curr = 1;
    for (int i = 0; i < oldFiles.size(); i++) {
        File oldFile = oldFiles.get(i);
        File newFile = newFiles.get(i);
        long m = oldFiles.get(i).length();
        int n = (int)(m/100);
        int s = 0;//每一份的进度
        // 创建输入流,读取源文件
        try (InputStream inputStream = new FileInputStream(oldFile);
             // 创建输出流,写入加密文件
             OutputStream outputStream = new FileOutputStream(newFile);
             // 创建密码输出流,连接到输出流,并使用密码 cipher 进行加密
             CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher)
        ) {
            // 缓冲区大小
            byte[] buffer = new byte[4096];
            int bytesRead;
            // 读取源文件内容到缓冲区
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                // 将加密后的数据写入加密文件
                cipherOutputStream.write(buffer, 0, bytesRead);
                s += 1024;
                if(s >= n){//进度+1
                    handler.sendEmptyMessage(MSG_COPY_RUNNING);
                    prog ++;
                    s = 0;
                }
            }
        }
    }


}

=========================文件解密=========================

SecretKey secretKeySpec = new SecretKeySpec("sin-17214455-@@@".getBytes(), ALGORITHM);
Cipher cipher = null;
try {
    cipher = Cipher.getInstance(ALGORITHM + "/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
    //获取源加密文件或文件夹路径
    File  encryptFile= new File(item.getPath() + File.separator +     item.getEncrypted_name());
    //获取目标解密文件或文件夹路径,解密过后生成的名称original_name
    File newFile = new File(item.getNewPath(), "original_name");
    // 创建输入流,读取加密文件
    FileInputStream inputStream = new FileInputStream(encryptFile);
    // 创建输出流,写入解密文件
    FileOutputStream outputStream = new FileOutputStream(newFile);
    // 创建密码输出流,连接到输出流,并使用密码 cipher 进行加密
    CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
    // 缓冲区大小
    byte[] buffer = new byte[4096];
    int bytesRead;
    // 读取源文件内容到缓冲区
    while ((bytesRead = cipherInputStream.read(buffer)) != -1) {
        // 将加密后的数据写入解密文件
        outputStream.write(buffer, 0, bytesRead);

    }
    outputStream.close();
    inputStream.close();
    cipherInputStream.close();
    if (!newFile.exists()) {
        newFile.createNewFile();
    }
   
    if (!newFile.getParentFile().exists()) {
        newFile.getParentFile().mkdirs();
    }
  //解密到这里就结束了打开文件,这里就根据自己的需求而定。下面是我自己的一个需求。
 // 打开文件,调用系统的打开选择的图片,text文件或者其他
    FileUtil.openFile(view.getContext(), newFile, ext);
} catch (IOException e) {
    throw new RuntimeException(e);
} catch (NoSuchFileToOpenException e) {
    ToastUtil.errorToast(view.getContext(), e.getMessage());
    throw new RuntimeException(e);
} catch (NoSuchPaddingException e) {
    throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
    throw new RuntimeException(e);
} catch (InvalidKeyException e) {
    throw new RuntimeException(e);
}
/**
 * 调用系统应用打开文件
 * @param context context
 * @param file file对象
 * @param ext 扩展名()
 * @throws NoSuchFileToOpenException 没有文件异常
 */
public static void openFile(Context context, File file,String ext) throws NoSuchFileToOpenException {
    if(! file.exists()){
        throw new NoSuchFileToOpenException("文件不存在");
    }
    //根据扩展名,适配相应的type
    String type = getType(ext);
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        Uri contentUri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".fileprovider", file);
        intent.setDataAndType(contentUri,type);
    } else {
        Uri uri = Uri.fromFile(file);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(uri,type);
    }
    context.startActivity(intent);
}
/**
 * 根据扩展名适配打开类型
 * @param ext 文件扩展名
 * @return 打开类型
 */
public static String getType(String ext) {
    switch (ext){
        case "3gp":return "video/3gpp";
        case "apk":return "application/vnd.android.package-archive";
        case "asf":return "video/x-ms-asf";
        case "avi":return "video/x-msvideo";
        case "bin":return "application/octet-stream";
        case "bmp":return "image/bmp";
        case "c":return "text/plain";
        case "class":return "application/octet-stream";
        case "conf":return "text/plain";
        case "cpp":return "text/plain";
        case "doc":return "application/msword";
        case "docx":return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        case "xls":return "application/vnd.ms-excel";
        case "xlsx":return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        case "exe":return "application/octet-stream";
        case "gif":return "image/gif";
        case "gtar":return "application/x-gtar";
        case "gz":return "application/x-gzip";
        case "h":return "text/plain";
        case "htm":return "text/html";
        case "html":return "text/html";
        case "jar":return "application/java-archive";
        case "java":return "text/plain";
        case "jpeg":return "image/jpeg";
        case "jpg":return "image/jpeg";
        case "js":return "application/x-javascript";
        case "log":return "text/plain";
        case "m3u":return "audio/x-mpegurl";
        case "m4a":return "audio/mp4a-latm";
        case "m4b":return "audio/mp4a-latm";
        case "m4p":return "audio/mp4a-latm";
        case "m4u":return "video/vnd.mpegurl";
        case "m4v":return "video/x-m4v";
        case "mov":return "video/quicktime";
        case "mp2":return "audio/x-mpeg";
        case "mp3":return "audio/x-mpeg";
        case "mp4":return "video/mp4";
        case "mpc":return "application/vnd.mpohun.certificate";
        case "mpe":return "video/mpeg";
        case "mpeg":return "video/mpeg";
        case "mpg":return "video/mpeg";
        case "mpg4":return "video/mp4";
        case "mpga":return "audio/mpeg";
        case "msg":return "application/vnd.ms-outlook";
        case "ogg":return "audio/ogg";
        case "pdf":return "application/pdf";
        case "png":return "image/png";
        case "pps":return "application/vnd.ms-powerpoint";
        case "ppt":return "application/vnd.ms-powerpoint";
        case "pptx":return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        case "prop":return "text/plain";
        case "rc":return "text/plain";
        case "rmvb":return "audio/x-pn-realaudio";
        case "rtf":return "application/rtf";
        case "sh":return "text/plain";
        case "tar":return "application/x-tar";
        case "tgz":return "application/x-compressed";
        case "txt":return "text/plain";
        case "wav":return "audio/x-wav";
        case "wma":return "audio/x-ms-wma";
        case "wmv":return "audio/x-ms-wmv";
        case "wps":return "application/vnd.ms-works";
        case "xml":return "text/plain";
        case "z":return "application/x-compress";
        case "zip":return "application/x-zip-compressed";
        case "":
        default:return "*/*";
    }
}

在AndroidManiFest注册fileprovider

<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

在res目录下的xml里面创建files-path

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="files"
        path="." />
    <cache-path
        name="cache"
        path="." />
<!--    <external-path-->
<!--        name="external_storage"-->
<!--        path="." />-->
    <external-path
        name="file_safe_root_path"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <external-media-path
        name="external_media"
        path="." />
    <root-path
        name="root"
        path="." />
 
</paths>

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一个简单的示例,展示了如何在 Android 中使用 AES 加密和解密文件: ```java import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.MessageDigest; import java.util.Arrays; public class AesUtil { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String SECRET_KEY = "my_secret_key"; private static final String IV = "my_initialization_vector"; public static void encrypt(String inputFile, String outputFile) throws Exception { SecretKeySpec secretKeySpec = generateKey(SECRET_KEY); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); FileInputStream inputStream = new FileInputStream(inputFile); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { byte[] output = cipher.update(buffer, 0, bytesRead); if (output != null) { outputStream.write(output); } } byte[] output = cipher.doFinal(); if (output != null) { outputStream.write(output); } inputStream.close(); outputStream.close(); } public static void decrypt(String inputFile, String outputFile) throws Exception { SecretKeySpec secretKeySpec = generateKey(SECRET_KEY); IvParameterSpec ivParameterSpec = new IvParameterSpec(IV.getBytes("UTF-8")); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); FileInputStream inputStream = new FileInputStream(inputFile); FileOutputStream outputStream = new FileOutputStream(outputFile); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { byte[] output = cipher.update(buffer, 0, bytesRead); if (output != null) { outputStream.write(output); } } byte[] output = cipher.doFinal(); if (output != null) { outputStream.write(output); } inputStream.close(); outputStream.close(); } private static SecretKeySpec generateKey(String key) throws Exception { byte[] keyBytes = key.getBytes("UTF-8"); MessageDigest sha = MessageDigest.getInstance("SHA-256"); keyBytes = sha.digest(keyBytes); keyBytes = Arrays.copyOf(keyBytes, 16); return new SecretKeySpec(keyBytes, "AES"); } } ``` 在此示例中,我们使用 AES/CBC/PKCS5Padding 加密模式和 SHA-256 哈希算法生成密钥。我们将密钥和初始向量 IV 保存为常量,但您可以根据需要进行更改。 要使用此示例,请在您的代码中调用 `AesUtil.encrypt(inputFile, outputFile)` 或 `AesUtil.decrypt(inputFile, outputFile)` 方法,其中 `inputFile` 是要加密或解密的文件路径,而 `outputFile` 是加密或解密后的文件路径。 请注意,此示例中的加密和解密操作是阻塞的,并且使用了相对较小的缓冲区。对于大文件和需要异步处理的情况,您需要进行适当的优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值