美文网首页
android端NDK封装DES加密

android端NDK封装DES加密

作者: 航行在蓝天的蚂蚱 | 来源:发表于2018-01-10 10:39 被阅读82次

    DES定义(百度百科)

    DES对称加密,对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码),是一种对称加密算法。DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。

    DES加密需要注意:加密模式、加密填充方式、偏移量。

    加密模式: ECB、CBC、CTR、OFB、CFB。
    加密填充方式:pacs7padding、pacs5padding、zeropadding、iso10126、ansix923。
    偏移量:ECB没有偏移量,对秘钥没有位数限制。CBC以及其他模式是需要偏移量和秘钥是8位的,在有的很多语言中封装的并没有对偏移量与秘钥进行位数超过8位进行限定,内部其实对偏移量和秘钥进行了截取前8位的操作的。

    DES的作用:

    1、移动端对数据进行DES加密之后,向服务器传输明文数据和已加密数据,这样防止通过链接恶意攻击服务器,
    2、对密码进行加密,传输到服务器端,再进行解密,这样不裸露传输,有效的保护密码。

    android端使用

    DES加密需要服务器端和移动端共同持有相同的秘钥和偏移量,为了安全,秘钥和偏移量就得重点保护,android端中对秘钥和偏移量的有效保护就只能选择使用NDK在c/c++中进行调用了。

    java与C++ 代码:

      /**
         * 加密
         * @param source 明文
         * @return 密文
         */
    public class DESUtils {
      static {
            System.loadLibrary("native-demo-lib");
        }
     /**
         * 加密
         * @param source 明文
         * @return 密文
         */
        public native static byte[] encryptNative(byte[] source);
    
        /**
         * 解密
         * @param source 密文
         * @return 明文
         */
        public native static byte[] decryptNative(byte[] source);
     /**
         * 封装秘钥
         *
         * @return 秘钥对象
         * @throws Exception 异常
         */
        private static Key toKey(byte[] key,String desType) throws Exception {
            DESKeySpec dks = new DESKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(desType);
            return  keyFactory.generateSecret(dks);
        }
    
        /**
         * DES解密,NDK中调用,方法名与参数列表不得更改
         *
         * @param data 密文
         * @return 明文
         * @throws Exception 异常
         */
        public static byte[] decrypt(byte[] data, byte[] key, byte[] py,String desType,String desMode) throws Exception {
            Key k = toKey(key,desType);
            Cipher cipher = Cipher.getInstance(desMode);
            IvParameterSpec iv = new IvParameterSpec(py);
            cipher.init(Cipher.DECRYPT_MODE, k, iv);//解密模式
    
            return cipher.doFinal(data);
        }
    
        /**
         * DES加密,NDK中调用,方法名与参数列表不得更改
         *
         * @param data 明文
         * @return 密文
         * @throws Exception 异常
         */
        public static byte[] encrypt(byte[] data, byte[] key, byte[] py,String desType,String desMode) throws Exception {
            Key k = toKey(key,desType);
            Cipher cipher = Cipher.getInstance(desMode);
            IvParameterSpec iv = new IvParameterSpec(py);
            cipher.init(Cipher.ENCRYPT_MODE, k, iv);//加密模式
            return cipher.doFinal(data);
        }
    
        /**
         * 加密字符串
         *
         * @param data 被加密字符串
         * @return 返回加密字符串
         */
        public static String encryptString(String data) {
            try {
                return encryptBASE64(encryptNative(data.getBytes("UTF-8")));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return "";
        }
    
        /**
         * 解密字符串
         * @param source 密文
         * @return 明文
         */
        public static String decryptString(String source){
            try{
                return new String(decryptNative(decryptBASE64(source)),"UTF-8");
            }catch (Exception ex){
                ex.printStackTrace();
            }
            return "";
        }
    }
    
    
    //秘钥(自定义)
    #define KEY "12345678"
    //偏移量(自定义)
    #define PY "qwertyui"
    //加密方式
    const char *DES_TYPE = "DES";
    //DES加密填充方式(也可以选择PKCS5Padding)
    const char *DES_MODE = "DES/CBC/PKCS7Padding";
    jbyteArray getBytes(JNIEnv *env, const char *source);
    
    jbyteArray getArray(JNIEnv *env,  _jclass *type, const _jbyteArray *source_, const char*name,const char*sig);
    
    extern "C" {
    /**
     * DES加密
     * @param env
     * @param type
     * @param source_ 明文
     * @return 密文
     */
    JNIEXPORT jbyteArray JNICALL
    Java_com_wanhe_eng100_listening_utils_DESUtils_encryptNative(JNIEnv *env, jclass type,
                                                                 jbyteArray source_) {
        const char* name = "encrypt";
        const char* sig = "([B[B[BLjava/lang/String;Ljava/lang/String;)[B";
        jbyteArray result = getArray(env, type, source_,name,sig);
        name = NULL;
        sig = NULL;
        return result;
    }
    
    /**
     * DES解密
     * @param env
     * @param type
     * @param source_ 密文
     * @return 明文
     */
    JNIEXPORT jbyteArray JNICALL
    Java_com_wanhe_eng100_listening_utils_DESUtils_decryptNative(JNIEnv *env, jclass type,
                                                                 jbyteArray source_) {
        const char* name = "decrypt";
        const char* sig = "([B[B[BLjava/lang/String;Ljava/lang/String;)[B";
    
        jbyteArray result = getArray(env, type, source_,name,sig);
    
        name = NULL;
        sig = NULL;
        return result;
        }
    }
    /**
     * 返回加密或者解密之后的jbyteArray
     * @param env 
     * @param type 
     * @param source_ 
     * @param name 
     * @param sig 
     * @return 
     */
    jbyteArray getArray(JNIEnv *env,  _jclass *type, const _jbyteArray *source_, const char* name, const char* sig) {
        jstring desType_, desMode_;
        jbyteArray keyArray, pyArray;
        jmethodID encryptMid;
    
        desType_ = env->NewStringUTF(DES_TYPE);
        desMode_ = env->NewStringUTF(DES_MODE);
        //将key转转成jbyteArray
        keyArray = getBytes(env, KEY);
        //将偏移量转成jbyteArray
        pyArray = getBytes(env, PY);
    
        encryptMid = env->GetStaticMethodID(type, name,
                                            sig);
        //调用DESUtils类中的加密方法
        jbyteArray result = (jbyteArray) env->CallStaticObjectMethod(type, encryptMid, source_,
                                                                     keyArray, pyArray, desType_,
                                                                     desMode_);
        //释放
        env->DeleteLocalRef(desType_);
        env->DeleteLocalRef(desMode_);
        env->DeleteLocalRef(keyArray);
        env->DeleteLocalRef(pyArray);
        return result;
    }
    /**
     * 将字符串转换jbyteArray
     * @param env
     * @param source
     * @return
     */
    jbyteArray getBytes(JNIEnv *env, const char *source) {
        jstring str = env->NewStringUTF(source);
        jstring utf8 = env->NewStringUTF("UTF-8");
        jclass stringClazz = env->FindClass("java/lang/String");//寻找 java里面String.class
        jmethodID stringMid = env->GetMethodID(stringClazz, "getBytes", "(Ljava/lang/String;)[B");
        return (jbyteArray) env->CallObjectMethod(str, stringMid, utf8);
    }
    

    本文章著作版权所属:微笑面对,请关注我的CSDN博客:这里写链接内容

    相关文章

      网友评论

          本文标题:android端NDK封装DES加密

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