android端NDK封装DES加密

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博客:这里写链接内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350