AES+JNI 加密方案

来源:互联网 发布:胡歌车祸知乎 编辑:程序博客网 时间:2024/06/02 06:32

首先Aes加密方案比较简单,也比较高效。至于它的优点,大家自己去网上搜索吧。我这里只是说一种android上应用AES的方案。
至于AES的代码大家也可以从网上搜索到,我这里直接贴上吧

package com.turingfac.encryptiondemo;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import android.annotation.SuppressLint;/** *  * @ClassName: com.example.androiddemo.AESUtil * @Description: AES加密解密工具类 * @author zhaokaiqiang * @date 2014-11-15 上午10:08:44 *  */@SuppressLint("TrulyRandom")public class AESUtil {    private final static String HEX = "0123456789ABCDEF";    private final static int JELLY_BEAN_4_2 = 17;    /**     * 加密     *      * @param key     *            密钥     * @param src     *            加密文本     * @return     * @throws Exception     */    public static String encrypt(String key, String src) throws Exception {        byte[] rawKey = getRawKey(key.getBytes());        byte[] result = encrypt(rawKey, src.getBytes());        return toHex(result);    }    /**     * 解密     *      * @param key     *            密钥     * @param encrypted     *            待揭秘文本     * @return     * @throws Exception     */    public static String decrypt(String key, String encrypted) throws Exception {        byte[] rawKey = getRawKey(key.getBytes());        byte[] enc = toByte(encrypted);        byte[] result = decrypt(rawKey, enc);        return new String(result);    }    /**     * 获取256位的加密密钥     *      * @param seed     * @return     * @throws Exception     */    @SuppressLint("TrulyRandom")    private static byte[] getRawKey(byte[] seed) throws Exception {        KeyGenerator kgen = KeyGenerator.getInstance("AES");        SecureRandom sr = null;        // 在4.2以上版本中,SecureRandom获取方式发生了改变        if (android.os.Build.VERSION.SDK_INT >= JELLY_BEAN_4_2) {            sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");        } else {            sr = SecureRandom.getInstance("SHA1PRNG");        }        sr.setSeed(seed);        // 256 bits or 128 bits,192bits        kgen.init(256, sr);        SecretKey skey = kgen.generateKey();        byte[] raw = skey.getEncoded();        return raw;    }    /**     * 真正的加密过程     *      * @param key     * @param src     * @return     * @throws Exception     */    private static byte[] encrypt(byte[] key, byte[] src) throws Exception {        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");        Cipher cipher = Cipher.getInstance("AES");        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);        byte[] encrypted = cipher.doFinal(src);        return encrypted;    }    /**     * 真正的解密过程     *      * @param key     * @param encrypted     * @return     * @throws Exception     */    private static byte[] decrypt(byte[] key, byte[] encrypted)            throws Exception {        SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");        Cipher cipher = Cipher.getInstance("AES");        cipher.init(Cipher.DECRYPT_MODE, skeySpec);        byte[] decrypted = cipher.doFinal(encrypted);        return decrypted;    }    public static String toHex(String txt) {        return toHex(txt.getBytes());    }    public static String fromHex(String hex) {        return new String(toByte(hex));    }    public static byte[] toByte(String hexString) {        int len = hexString.length() / 2;        byte[] result = new byte[len];        for (int i = 0; i < len; i++)            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),                    16).byteValue();        return result;    }    public static String toHex(byte[] buf) {        if (buf == null)            return "";        StringBuffer result = new StringBuffer(2 * buf.length);        for (int i = 0; i < buf.length; i++) {            appendHex(result, buf[i]);        }        return result.toString();    }    private static void appendHex(StringBuffer sb, byte b) {        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));    }}

这里面涉及到key不能被其他的用户看到,所以我选择使用jni来封装key的获取方式。首先写一个GetKey.java 代码如下:

package com.turingfac.encryptiondemo;public class GetKey {    public static native String getencryptkey();}

jni 中c相关代码,jni不懂的可以自己搜索一下。

/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */#include <string.h>#include <stdio.h>#include <jni.h>jstring JNIEXPORT  JNICALL Java_com_turingfac_encryptiondemo_GetKey_getencryptkey  (JNIEnv * env, jobject obj){    return (*env)->NewStringUTF(env,"helloturing");}

最后使用NDK 编译成功以后,我们就可以在任何一个类中使用GetKey.getkey()来获取加密密钥,这样的方式比较安全一些

0 0