Android uses jni to encrypt and decrypt strings for analysis. androidjni
Analysis of string encryption and decryption using jni in android
Recently, a demand for projects is to encrypt users' sensitive information, such as users' account passwords, mobile phone numbers, and other private information. In java, we can use the AES algorithm to encrypt and decrypt the string. The benefits of using the string do not need to be discussed, but we know that the android source code can be decompiled, therefore, AES encryption in pure Java mode is not secure. Therefore, we thought of using jni in android to encrypt and decrypt strings. so file, more importantly, it is implemented through C/C ++ code, so the security line is relatively high, it can be decompiled into machine code, but almost cannot be restored and decompiled, the following describes the encryption process in detail.
Considering that C/C ++ Code is fully used for string encryption and decryption, we need to consider the differences in data types on different system platforms. Here we recommend another method that is easy to implement, that is, the AES encryption and decryption logic in Java is used, and the core key required for AES encryption and decryption is put into C, and the required key is read from the static class library by calling jni, the specific implementation is as follows:
Project code structure:
AES algorithm logic in Java:
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 (nosuchalgorithm1_tione ){
} Catch (nosuchpaddingeffectione ){
}
}
}
Publicstaticnativebyte [] getKeyValue ();
Publicstaticnativebyte [] getIv ();
Publicstatic String encode (Stringmsg ){
String str = "";
Try {
// Use the key and a set of algorithm parameters to initialize the cipher
Ecipher. init (Cipher. ENCRYPT_MODE, key, paramSpec );
// Encrypt and convert to a hexadecimal string
Str = asHex (ecipher. doFinal (msg. getBytes ()));
} Catch (badpaddingeffectione ){
} Catch (invalidkeypolictione ){
} Catch (invalidalgorithmparametergatetione ){
} Catch (illegalblocksizeeffectione ){
}
Returnstr;
}
Publicstatic String decode (Stringvalue ){
Try {
Ecipher. init (Cipher. DECRYPT_MODE, key, paramSpec );
Returnnew String (ecipher. doFinal (asBin (value )));
} Catch (badpaddingeffectione ){
} Catch (invalidkeypolictione ){
} Catch (invalidalgorithmparametergatetione ){
} Catch (illegalblocksizeeffectione ){
}
Return "";
}
Privatestatic String asHex (bytebuf []) {
StringBuffer strbuf = new StringBuffer (buf. length * 2 );
Inti;
For (I = 0; I <buf. length; I ++ ){
If (int) buf [I] & 0xff) <0x10) // Add zero before 10
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 <src. length ()/2; I ++ ){
Inthigh = Integer. parseInt (src. substring (I * 2, I * 2 + 1), 16); // get the high byte
Intlow = Integer. parseInt (src. substring (I * 2 + 1, I * 2 + 2), 16); // get the lowest byte
Encrypted [I] = (byte) (high * 16 + low );
}
Returnencrypted;
}
How to read the key in C:
# Include <stdio. h>
# 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 <sizeof (keyValue); 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 <sizeof (iv); I ++)
{
Bytes [I] = (jbyte) iv [I];
}
(* Env)-> SetByteArrayRegion (env, ivArray, 0, sizeof (iv), bytes );
(* Env)-> ReleaseByteArrayElements (env, ivArray, bytes, 0 );
Return ivArray;
}
How to call in android:
Publicclass MainActivityextends Activity {
Privatestaticfinal StringTAG = "MainActivity ";
Private StringencriptStr = "18721002361"; // encrypted string
@ Override
Protectedvoid onCreate (BundlesavedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. activity_main );
// After Encryption
String enstr = SecurityUtil. encode (encriptStr );
Log. d (TAG, "encrypted:" + enstr );
// After decryption
String destr = SecurityUtil. decode (enstr );
Log. d (TAG, "decrypted:" + destr );
}
}
Here, we use a mobile phone number as an example for encryption and decryption. The specific information can be viewed in the log, as shown below.
Comparison of encryption and decryption:
Now, I have listed all major file implementations. If you have any questions, you can discuss them in comments or in group (179914858. In addition, it is not easy for original works to come from. Please indicate the source for reprinting. Thank you.
The original code is attached for reference. Click here.
Why is it better to use jni to edit android programs? Compared with pure java?
Android jni can be developed using c/c ++. Compared with java, the running efficiency is much improved, especially when performing image algorithms or game logic, jni greatly improves the efficiency. For example, if a game uses opengl and loads a 3d model composed of 1000 polygon, jni is several times faster than java, thus ensuring that the fps of the game is not too low.
Another advantage is that in memory management, java memory management is all managed by virtual machines, and C ++ is managed by programmers, so the utilization is much better.
And other advantages.
Since there are so many advantages, why is an android program not developed using pure c? Because android UI framework uses java, java is used for development on the UI.
[Help] when Android uses JNI, the following message is displayed in the Code: <jinstitutes>
I also saw the same problem on EOEandroid. I don't know if it's you. Accessing SDCARD is definitely a JAVA code, what JNI has to do is implement some data processing interfaces 6114 you must use JAVA code to access SDCARD, and then use JNI to read the file to implement 395