我有一个带有网络服务网址的安卓应用程序。如果有人解密我的apk文件,网络服务网址将变得可见。我正在使用HTTP POST来调用Web服务。
任何人都可以通过从此站点反编译apk文件来阅读代码。
我的注册页面网址被黑客入侵,并向该网址发送了包含帖子数据的批量请求。我正在使用API_KEY
并发送带有帖子数据的API_KEY
。API_KEY
存储在gradle.properties
文件中。
我没有使用
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'` when its got hacked.
经过一些搜索,我知道没有100%安全的方法来隐藏url。
我的注册代码是:
String link = "http://xxxxxxxxxx.php";
String data = URLEncoder.encode("name", "UTF-8") + "=" + URLEncoder.encode(name, "UTF-8");
data += "&" + URLEncoder.encode("phone", "UTF-8") + "=" + URLEncoder.encode(phone, "UTF-8");
data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8");
URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
我不知道这是否是将数据发布到 URL 的正确方法。
如何保护我的源代码?
我可以将所有 Web 服务 URL 存储在服务器中吗?
我是安卓的初学者。请帮忙!
我在我开发的所有安卓应用程序中都使用它
gradle.properties
API = http://ec2xxxxx.compute.amazonaws.com
API_KEY = $2c11SoL/NjJ28
创建utils.gradle
utils.gradle
class Utils {
static def r = new Random(System.currentTimeMillis())
}
def String toJavaCodeString(String string) {
byte[] b = string.getBytes();
int c = b.length;
StringBuilder sb = new StringBuilder();
sb.append("(new Object() {");
sb.append("int t;");
sb.append("public String toString() {");
sb.append("byte[] buf = new byte[");
sb.append(c);
sb.append("];");
for (int i = 0; i < c; ++i) {
int t = Utils.r.nextInt();
int f = Utils.r.nextInt(24) + 1;
t = (t & ~(0xff << f)) | (b[i] << f);
sb.append("t = ");
sb.append(t);
sb.append(";");
sb.append("buf[");
sb.append(i);
sb.append("] = (byte) (t >>> ");
sb.append(f);
sb.append(");");
}
sb.append("return new String(buf);");
sb.append("}}.toString())");
return sb.toString();}
ext.toJavaCodeString = this.&toJavaCodeString
build.gradle
apply from: "utils.gradle"
android {
defaultConfig {
buildConfigField 'String', 'API', toJavaCodeString(API)
buildConfigField 'String', 'API_KEY', toJavaCodeString(API_KEY)
}}
并访问您的私人网址;
public static final String API = BuildConfig.API;
无法保护"机密"信息,例如嵌入在 APK 中的网址。 一个坚定/有动力的黑客可以击败您关心设计的任何计划......如果他/她有权访问运行您的应用程序的平台。
为了使应用能够运行,在用户设备上运行的应用需要能够解密隐藏的 URL。 用户可以在应用程序的地址空间中以解密形式拦截 URL,或者他/她可以对您用于执行解密的算法和解密密钥进行逆向工程。
另一个"攻击"是你的应用需要使用 URL 发出请求。 该请求可以在用户设备上被SSL/TLS通道保护到您(可能)启用HTTPS的服务之前被拦截。
最重要的是,如果您将"秘密"URL嵌入到应用程序中,并且该机密遭到破坏,并且您必须关闭/重新定位服务器,那么您正在为应用程序的所有(合法,付费等)用户制造问题。 他们不会是快乐的露营者。
正确的方法是使您的服务安全...并使用某种身份验证机制,以便黑客需要的不仅仅是 URL 来发出请求。 用户可以/应该获得个人凭据(例如身份验证密钥),并且您需要实现一种方法来在服务器端使给定用户的凭据失效。
URL"代表通用资源定位器。URL的全部意义在于访问某种资源,为此,您显然必须告诉网络您正在连接到要获取的内容。
现在,如果您担心黑客可以访问您的源代码,那么他当然也可以连接Wireshark或Fiddler,并简单地观察您的应用程序正在建立哪些连接,以及您正在传递和接收的信息。
抱歉,但我根本看不出有什么好方法可以解决这个问题。
如果你担心你的服务器/服务被黑客入侵或DOS'ed,我认为你最好专注于尽可能保护它们,而不是试图隐藏它们。
我以两种方式解决了这个问题
-
用我的私钥加密了我的代码中的URL,并根据请求再次解密了它,
public static String encryptIt(String value) { try { DESKeySpec keySpec = new DESKeySpec(new byte[]{105, 107, 18, 51, 114, 83, 51, 120, 121}); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey key = keyFactory.generateSecret(keySpec); byte[] clearText = value.getBytes("UTF8"); // Cipher is not thread safe Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); // Log.d("aa", "Encrypted: " + value + " -> " + encrypedValue); return Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT); } catch (Exception e) { e.printStackTrace(); } return value;
}
并使用它来描述它
public static String decryptIt(String value) {
try {
DESKeySpec keySpec = new DESKeySpec(new byte[]{105, 107, 18, 51, 114, 83, 51, 120, 121});//cryptoPass.getBytes("UTF8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
byte[] encrypedPwdBytes = Base64.decode(value, Base64.DEFAULT);
// cipher is not thread safe
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));
// Log.d("aa", "Decrypted: " + value + " -> " + decrypedValue);
return new String(decrypedValueBytes);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
请注意,在我的情况下,私钥是new byte[]{105, 107, 18, 51, 114, 83, 51, 120, 121}
我认为它是$ecrEt
的,或者类似的东西,我忘记了它。
因此,如果他们反编译APK,他们将无法在您的代码中找到服务链接。
所以基本 URL 将是这样的public static final String ROOT_API = "aHR0cHSC86LSy9tbS2JpuZW50aWtoYWAbGUJhdC5qbw==";
2-您还必须将progaurd添加到代码中
但是,如果黑客是高级人员,他们可以对netweok进行蓝精灵并找到URL,在这种情况下,您必须使用SSl证书"https"并使网络服务发布。
希望你明白我的意思。