Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android中使用jni對字符串加解密實現分析

android中使用jni對字符串加解密實現分析

編輯:關於Android編程

android中使用jni對字符串加解密實現分析

最近項目有個需求,就是要對用戶的敏感信息進行加密處理,比如用戶的賬戶密碼,手機號等私密信息。在java中,就對字符串的加解密我們可以使用AES算法加密字符串,使用它的好處就不必多說了,但我們又知道android的源代碼是可以被反編譯的,所以使用純Java方式的AES加密是不安全的,所以想到了使用android中的jni來對字符串加解密處理,它會產生一個.so文件,更重要的是它通過C/C++代碼實現,所以安全行比較高,它可以被反編譯成機器碼,但幾乎不能被還原反編譯,那麼下面就詳細介紹下這種的加密處理。

鑒於完全使用C/C++代碼進行字符串的加解密,我們需要考慮不同系統平台上數據類型的差異問題,這裡推薦另一種易於實現的方法,即使用Java中的AES加解密邏輯,而將AES加解密所需要的核心秘鑰放入到C中,通過調用jni來從靜態類庫中讀取需要的秘鑰,具體實現如下:


項目代碼結構圖:

\


<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CkphdmHW0LXEQUVTy+O3qMLfvK2jujwvcD4KPHA+CnB1YmxpY2NsYXNzIFNlY3VyaXR5VXRpbCB7PC9wPgo8cD4KcHJpdmF0ZXN0YXRpY2J5dGVbXWtleVZhbHVlOzwvcD4KPHA+CjwvcD4KPHA+CiAgICBwcml2YXRlc3RhdGljYnl0ZVtdaXY7CiAgPC9wPgo8cD4KICAgIDwvcD4KPHA+CiAgICBwcml2YXRlc3RhdGljIFNlY3JldEtleWtleTsgCiAgICAgICAgICAgICAgICAgICAgICA8L3A+CjxwPgogICAgcHJpdmF0ZXN0YXRpYyBBbGdvcml0aG1QYXJhbWV0ZXJTcGVjcGFyYW1TcGVjOwogICAgPC9wPgo8cD4KICAgIHByaXZhdGVzdGF0aWMgQ2lwaGVyZWNpcGhlcjsKICAgICAgICAgICAgICAgICAgPC9wPgo8cD4KICAgICAgPC9wPgo8cD4KICAgIHN0YXRpYyB7PC9wPgo8cD4KICAgIFN5c3RlbS5sb2FkTGlicmFyeSg="cwtlib");

keyValue = getKeyValue();

iv = getIv();

if(null != keyValue &&

null !=iv) {

KeyGeneratorkgen;

try {

kgen = KeyGenerator.getInstance("AES");

kgen.init(128,new SecureRandom(keyValue));

key =kgen.generateKey();

paramSpec =new IvParameterSpec(iv);

ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

} catch (NoSuchAlgorithmExceptione) {

} catch (NoSuchPaddingExceptione) {

}

}

}

publicstaticnativebyte[] getKeyValue();

publicstaticnativebyte[] getIv();

publicstatic String encode(Stringmsg) {

String str ="";

try {

//用密鑰和一組算法參數初始化此 cipher

ecipher.init(Cipher.ENCRYPT_MODE,key,paramSpec);

//加密並轉換成16進制字符串

str = asHex(ecipher.doFinal(msg.getBytes()));

} catch (BadPaddingExceptione) {

} catch (InvalidKeyExceptione) {

} catch (InvalidAlgorithmParameterExceptione) {

} catch (IllegalBlockSizeExceptione) {

}

returnstr;

}

publicstatic String decode(Stringvalue) {

try {

ecipher.init(Cipher.DECRYPT_MODE,key,paramSpec);

returnnew String(ecipher.doFinal(asBin(value)));

} catch (BadPaddingExceptione) {

} catch (InvalidKeyExceptione) {

} catch (InvalidAlgorithmParameterExceptione) {

} catch (IllegalBlockSizeExceptione) {

}

return"";

}

privatestatic String asHex(bytebuf[]) {

StringBuffer strbuf =new StringBuffer(buf.length * 2);

inti;

for (i = 0;i

if (((int)buf[i] & 0xff) < 0x10)//小於十前面補零

strbuf.append("0");

strbuf.append(Long.toString((int)buf[i] & 0xff, 16));

}

returnstrbuf.toString();

}

privatestaticbyte[] asBin(Stringsrc) {

if (src.length() < 1)

returnnull;

byte[]encrypted =newbyte[src.length() / 2];

for (inti = 0;i

inthigh = Integer.parseInt(src.substring(i * 2, i * 2 + 1), 16);//取高位字節

intlow = Integer.parseInt(src.substring(i * 2 + 1, i * 2 + 2), 16);//取低位字節

encrypted[i] = (byte) (high * 16 +low);

}

returnencrypted;

}


C中的讀取秘鑰的實現:

#include

#include"cwtlib.h"



constchar keyValue[] = {

21, 25, 21, -45, 25, 98, -55, -45, 10, 35, -45, 35,

26, -5, 25, -65, -78, -99, 85, 45, -5, 10, -0, 11,

-35, -48, -98, 65, -32, 14, -67, 25, 36, -56, -45, -5,

12, 15, 35, -15, 25, -14, 62, -25, 33, -45, 55, 12, -8

};


constchar iv[] = {

-33, 32, -25, 25, 35, -27, 55, -12, -15, 23, 45, -26, 32, 5 - 2, 74, 54

};


JNIEXPORT jbyteArray JNICALL Java_com_cwtlib_aesencript_SecurityUtil_getKeyValue

(JNIEnv *env, jclass obj)

{

jbyteArray kvArray = (*env)->NewByteArray(env,sizeof(keyValue));

jbyte *bytes = (*env)->GetByteArrayElements(env,kvArray,0);

int i;

for (i = 0; i

{

bytes[i] = (jbyte)keyValue[i];

}

(*env)->SetByteArrayRegion(env,kvArray, 0,sizeof(keyValue),bytes);

(*env)->ReleaseByteArrayElements(env,kvArray,bytes,0);

return kvArray;

}


JNIEXPORT jbyteArray JNICALL Java_com_cwtlib_aesencript_SecurityUtil_getIv

(JNIEnv *env, jclass obj)

{

jbyteArray ivArray = (*env)->NewByteArray(env,sizeof(iv));

jbyte *bytes = (*env)->GetByteArrayElements(env,ivArray, 0);

int i;

for (i = 0; i

{

bytes[i] = (jbyte)iv[i];

}

(*env)->SetByteArrayRegion(env,ivArray, 0,sizeof(iv), bytes);

(*env)->ReleaseByteArrayElements(env,ivArray,bytes,0);

return ivArray;

}


在android中如何調用:

publicclass MainActivityextends Activity {

privatestaticfinal StringTAG ="MainActivity";

private StringencriptStr ="18721002361";//加密的字符串

@Override

protectedvoid onCreate(BundlesavedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//加密後

String enstr = SecurityUtil.encode(encriptStr);

Log.d(TAG,"加密後:" +enstr);

//解密後

String destr = SecurityUtil.decode(enstr);

Log.d(TAG,"解密後:" +destr);

}

}

這裡以一個手機號為例進行加解密處理,具體的效果圖可以在日志中查看到,具體如下。

加解密的對照效果圖:





好了,到這裡我已經羅列出了所有主要文件實現,如果有問題可以在評論或是群(179914858)中進行討論。另外,原創作品來自不易,轉載請注明出處,謝謝。

最後附上原代碼供參考,下載地址:請點這裡



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved