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

來源:互聯網
上載者:User

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

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

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

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


項目代碼結構圖:



Java中的AES演算法邏輯:

publicclass SecurityUtil {

privatestaticbyte[]keyValue;

privatestaticbyte[]iv;

privatestatic SecretKeykey;

privatestatic AlgorithmParameterSpecparamSpec;

privatestatic Cipherecipher;

static {

System.loadLibrary("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);

}

}

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

加解密的對照:


:請點這裡



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.