美文网首页androidAndroid开发Android技术知识
Android Studio NDK开发(七):文件的加密与解密

Android Studio NDK开发(七):文件的加密与解密

作者: zhang_pan | 来源:发表于2017-11-30 12:28 被阅读101次

    前言

    基于C++学习和JNI流程学习,相信大家对NDK开发充满了期待,本篇博客将从一个简单的例子入手,带着大家熟悉NDK开发。

    文件的加密与解密

    创建Java文件Encryptor

    public class Encryptor {
        static {
            System.loadLibrary("file_encryption");
        }
    
        //加密
        public native static void cryption(String normalPath, String cryptPath);
        //解密
        public native static void decryption(String cryptPath, String decryptPath);
    }
    

    创建cpp文件file_encryption.c加密核心实现:

    #include "jni.h"
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <android/log.h>
    
    #define LOGD(FORMAT,...) __android_log_print(ANDROID_LOG_DEBUG,"zp",FORMAT,##__VA_ARGS__);
    
    char password[] = "ChinaIsPowerful";
    //加密
    JNIEXPORT void JNICALL
    Java_com_zhangpan_myjnicmake_Encryptor_cryption(JNIEnv *env, jclass jcla, jstring normal_path_jstr, jstring crypt_path_jstr) {
        //jstring --> char*
        char* normal_path = (*env)->GetStringUTFChars(env, normal_path_jstr, NULL);
        char* crypt_path = (*env)->GetStringUTFChars(env, crypt_path_jstr, NULL);
    
        LOGD("%s", normal_path);
        //打开文件
        FILE* nomal_fp = fopen(normal_path, "rb");
        FILE* crypt_fp = fopen(crypt_path, "wb");
    
        if (nomal_fp == NULL) {
            LOGD("%s", "文件打开失败");
            return;
        }
    
        //一次读取一个字符
        int ch = 0;
        int i = 0;
        int pwd_length = strlen(password);
        while ((ch = fgetc(nomal_fp)) != EOF) { //End of File
            //写入(异或运算)
            fputc(ch ^ password[i % pwd_length], crypt_fp);
            i++;
        }
    
        //关流
        fclose(nomal_fp);
        fclose(crypt_fp);
    }
    

    CMakeLists配置:

    add_library( # Sets the name of the library.
                 file_encryption
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                 src/main/cpp/file_encryption.c)
    
    target_link_libraries( # Specifies the target library.
                           file_encryption
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    

    解密核心实现:

    JNIEXPORT void JNICALL
    Java_com_zhangpan_myjnicmake_Encryptor_decryption(JNIEnv *env, jclass jcla, jstring crypt_path_jstr, jstring decrypt_path_jstr) {
        //jstring --> char*
        char *crypt_path = (*env)->GetStringUTFChars(env, crypt_path_jstr, NULL);
        char *decrypt_path = (*env)->GetStringUTFChars(env, decrypt_path_jstr, NULL);
        FILE* crypt_fp = fopen(crypt_path, "rb");
        FILE* decrypt_fp = fopen(decrypt_path, "wb");
    
        int ch;
        int i = 0;
        int pwd_length = strlen(password);
        while ((ch = fgetc(crypt_fp)) != EOF)
        {
            fputc(ch ^ password[i % pwd_length], decrypt_fp);
            i++;
        }
    
        fclose(crypt_fp);
        fclose(decrypt_fp);
    }
    

    创建FileEncryptionActivity

    public class FileEncryptionActivity extends AppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_file_encryption);
        }
    
        public void mCryption(View view) {
            String normalPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Shape@2x.png";
    //        String normalPath = "/sdcard/Shape@2x.png";
            String cryptPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Shape@2xcrypt.png";
            Encryptor.cryption(normalPath, cryptPath);
            Log.d("zhangpan", "加密完成了...");
        }
    
        public void mDecryption(View view) {
            String cryptPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Shape@2xcrypt.png";
            String decryptPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Shape@2xdecrypt.png";
            Encryptor.decryption(cryptPath, decryptPath);
            Log.d("zhangpan", "解密完成了...");
        }
    }
    

    布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center">
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="加密"
            android:onClick="mCryption"/>
    
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="解密"
            android:onClick="mDecryption"/>
    
    </LinearLayout>
    

    编译运行,点击加密,再点击解密,Logcat输出:

    11-30 12:13:50.548 6981-6981/? D/zhangpan: 加密完成了...
    11-30 12:14:01.358 6981-6981/? D/zhangpan: 解密完成了...
    

    注意:
    1.添加文件的读写权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    2.文件存储路径/mnt/sdcard/,此例中是将Shape@2x.png放到sd卡中,加密是需要确定sd卡中存在此图片。
    3.Android 6.0动态权限申请,如果你的手机是Android 6.0+,没有动态申请权限,需要手动去设置里面打开权限。

    项目地址

    https://github.com/fsrmeng/MyJniCmake-Master

    展望

    本篇博客简单介绍了JNI中文件的加密与解密,接下来我将介绍JNI中文件的拆分与合并,敬请期待!
    喜欢本篇博客的简友们,就请来一波点赞,您的每一次关注,将成为我前进的动力,谢谢!

    相关文章

      网友评论

        本文标题:Android Studio NDK开发(七):文件的加密与解密

        本文链接:https://www.haomeiwen.com/subject/qgqwpxtx.html