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>
相关推荐
天空中的野鸟33 分钟前
Android音频采集
android·音视频
小白也想学C2 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程2 小时前
初级数据结构——树
android·java·数据结构
闲暇部落4 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX6 小时前
Android 分区相关介绍
android
大白要努力!7 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee7 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood7 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-10 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen12 小时前
MTK Android12 user版本MtkLogger
android·framework