Android 应用程序中的字符串保护
Strings protection in Android application
我想保护我的 Android 应用程序中的一些字符串,其中包含不应查看的信息。到目前为止,我最好的想法是使用 AES 算法或其他算法对这些字符串进行加密,并将密码放入 Google 云存储文件中,该文件只能通过身份验证(通过 Firebase Auth)查看,所以理论上应用程序总是在需要时访问该文件。这是个好主意?
关于NDK可以参考:
示例:
#include <string.h>
#include <jni.h>
jstring Java_com_riis_sqlndk_MainActivity_invokeNativeFunction(JNIEnv* env,
jobject javaThis) {
return (*env)->NewStringUTF(env, "pass123");
}
并在 Android 中使用:
public class MainActivity extends Activity {
static {
System.loadLibrary("sqlndk"); // line 11
}
private native String invokeNativeFunction(); // line 14
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String key = invokeNativeFunction(); // line 21
}
}
希望对您的问题有所帮助!
这似乎是个好主意,只要您在离线模式下不需要此字符串即可。否则使用密钥库。
更多信息:https://developer.android.com/training/articles/keystore.html
示例:https://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/
此外当您在离线模式下不需要此值时 - 您可以将其存储在密钥库中并仅远程存储私钥而不是所有字符串。
我已经解决了我的问题,我有这两种方法很好用:
public static String encrypt(String message, String key) {
String cipherText = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
byte[] bytes = cipher.doFinal(message.getBytes("UTF-8"));
cipherText = Base64.encodeToString(bytes, Base64.DEFAULT);
} catch(Exception ex) {
ex.printStackTrace();
}
return cipherText;
}
public static String decrypt(String encoded, String key) {
String decryptString = null;
try {
byte[] bytes = Base64.decode(encoded, Base64.DEFAULT);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
decryptString = new String(cipher.doFinal(bytes), "UTF-8");
} catch(Exception ex) {
ex.printStackTrace();
}
return decryptString;
}
encrypt方法将消息用AES加密后,使用Base64将byte[]变成可读的String,可以存储在strings.xml文件或JavaClass,而 decrypt 方法执行相反的操作。而我的应用程序只能通过 Firebase 存储在线获取密钥。
现在,如果有人试图对我的代码进行逆向工程,他们唯一能看到的是:
<string name="code_1">nuD559T1j8VSqjidiF3Yag==</string>
<string name="code_2">+4MTk9TaJJAJEV6D07K++Q==</string>
<string name="code_3">4GlPuHyAGhd48bjuSvcvQQ==</string>
<string name="code_4">yQnq3/tEIxJe67bhBuzoHw==</string>
<string name="code_5">p/sDptvxdi0ynsuybvfI+A==</string>
<string name="code_6">dE4aV0wG0aINh/dw0wwevQ==</string>
<string name="code_7">vxNaPmHvnbGsydOYXSOSUA==</string>
<string name="code_8">fClfcC/Eweh9tA8xz6ktGw==</string>
<string name="code_9">FxzAZpH+SJt5Lv6VFU/BEQ==</string>
<string name="code_10">qh3jFGHOGMzt50WOwTG4H4Y2Vbr7TzO433tbB3s6P34=</string>
<string name="code_11">u7kZjN/bxkMEqDws4nvbnQ==</string>
<string name="code_12">Ccf2u8FJGJ1lsiR7aX5OSw==</string>
<string name="code_13">E4XsWDHO28pOhV4ter/f2A==</string>
<string name="code_14">kgPr+Yz3t4S+Y5zQXjkvJA==</string>
<string name="code_15">19CpjUzKOw1fL8bZH8xkMg==</string>
我想保护我的 Android 应用程序中的一些字符串,其中包含不应查看的信息。到目前为止,我最好的想法是使用 AES 算法或其他算法对这些字符串进行加密,并将密码放入 Google 云存储文件中,该文件只能通过身份验证(通过 Firebase Auth)查看,所以理论上应用程序总是在需要时访问该文件。这是个好主意?
关于NDK可以参考: 示例:
#include <string.h>
#include <jni.h>
jstring Java_com_riis_sqlndk_MainActivity_invokeNativeFunction(JNIEnv* env,
jobject javaThis) {
return (*env)->NewStringUTF(env, "pass123");
}
并在 Android 中使用:
public class MainActivity extends Activity {
static {
System.loadLibrary("sqlndk"); // line 11
}
private native String invokeNativeFunction(); // line 14
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String key = invokeNativeFunction(); // line 21
}
}
希望对您的问题有所帮助!
这似乎是个好主意,只要您在离线模式下不需要此字符串即可。否则使用密钥库。
更多信息:https://developer.android.com/training/articles/keystore.html
示例:https://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/
此外当您在离线模式下不需要此值时 - 您可以将其存储在密钥库中并仅远程存储私钥而不是所有字符串。
我已经解决了我的问题,我有这两种方法很好用:
public static String encrypt(String message, String key) {
String cipherText = null;
try {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
byte[] bytes = cipher.doFinal(message.getBytes("UTF-8"));
cipherText = Base64.encodeToString(bytes, Base64.DEFAULT);
} catch(Exception ex) {
ex.printStackTrace();
}
return cipherText;
}
public static String decrypt(String encoded, String key) {
String decryptString = null;
try {
byte[] bytes = Base64.decode(encoded, Base64.DEFAULT);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(), "AES"));
decryptString = new String(cipher.doFinal(bytes), "UTF-8");
} catch(Exception ex) {
ex.printStackTrace();
}
return decryptString;
}
encrypt方法将消息用AES加密后,使用Base64将byte[]变成可读的String,可以存储在strings.xml文件或JavaClass,而 decrypt 方法执行相反的操作。而我的应用程序只能通过 Firebase 存储在线获取密钥。
现在,如果有人试图对我的代码进行逆向工程,他们唯一能看到的是:
<string name="code_1">nuD559T1j8VSqjidiF3Yag==</string>
<string name="code_2">+4MTk9TaJJAJEV6D07K++Q==</string>
<string name="code_3">4GlPuHyAGhd48bjuSvcvQQ==</string>
<string name="code_4">yQnq3/tEIxJe67bhBuzoHw==</string>
<string name="code_5">p/sDptvxdi0ynsuybvfI+A==</string>
<string name="code_6">dE4aV0wG0aINh/dw0wwevQ==</string>
<string name="code_7">vxNaPmHvnbGsydOYXSOSUA==</string>
<string name="code_8">fClfcC/Eweh9tA8xz6ktGw==</string>
<string name="code_9">FxzAZpH+SJt5Lv6VFU/BEQ==</string>
<string name="code_10">qh3jFGHOGMzt50WOwTG4H4Y2Vbr7TzO433tbB3s6P34=</string>
<string name="code_11">u7kZjN/bxkMEqDws4nvbnQ==</string>
<string name="code_12">Ccf2u8FJGJ1lsiR7aX5OSw==</string>
<string name="code_13">E4XsWDHO28pOhV4ter/f2A==</string>
<string name="code_14">kgPr+Yz3t4S+Y5zQXjkvJA==</string>
<string name="code_15">19CpjUzKOw1fL8bZH8xkMg==</string>