我有一个Android应用程序,其中硬编码(静态字符串常量)凭据(用户/密码)用于通过SMTP发送电子邮件。
问题在于,.apk中的.dex文件可以很容易地被反向工程化,每个人都可以看到我的密码。
是否有一种方法可以保护这些凭据,同时我仍然能够在我的类中使用它们?
我有一个Android应用程序,其中硬编码(静态字符串常量)凭据(用户/密码)用于通过SMTP发送电子邮件。
问题在于,.apk中的.dex文件可以很容易地被反向工程化,每个人都可以看到我的密码。
是否有一种方法可以保护这些凭据,同时我仍然能够在我的类中使用它们?
我猜你可以尝试使用代码混淆器,但实际上这并不能使你的密码100%安全,而且我不知道它与Android编译器的兼容性如何。为什么不使用像Google一样的安全Web身份验证呢?
以下操作会很有用:
1- 您可以加密它们并混淆加密算法。任何加密与混淆(在Adnroid中使用progaurd)都是有用的。
2- 最好将字符串作为字节数组硬编码到您的代码中。许多反向工程应用程序可以获取您的硬编码字符串列表并猜测它们是什么。但当它们以字节数组形式存在时,它们是不可读的。但是,Proguard仍然是必要的。(它仅从RAM字符串常量搜索中隐藏,并且它们仍然可以从.class文件中搜索)
3- 如果在硬编码之前对它们进行加密并使用C++代码解密,则使用C ++ 代码托管您的常量并不是一个坏主意。
这里还有一篇很棒的文章:
https://rammic.github.io/2015/07/28/hiding-secrets-in-android-apps/
我认为唯一可能有效的方法是将凭据托管在仅您的应用程序可以通过某种单独的身份验证通过Web服务调用访问的服务器上 - 类似于FB的哈希键。 如果它对他们有用,那么对我们也应该有用。
我正在研究一个类似的问题,然后发现了这个有用的帖子:http://www.dreamincode.net/forums/topic/208159-protect-plain-string-from-decompilers/
虽然我对Android开发不太熟悉,但是相同的思路应该适用。
如果您没有进行Web授权的手段,您将需要在应用程序中包含第三方解密。
以下是您可以尝试的方法: 1)编写一个独立的程序,仅用于创建一次性密码哈希值。(此程序不应是您应用程序的一部分)。记下生成的哈希值。 http://www.mindrot.org/projects/jBCrypt/
// Hash a password for the first time.
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
2) 将此密码哈希作为字符串常量存储在您的 APK 中。
3) 然后每次需要检查密码时,使用 bcrypt 与哈希密码进行比较。
// Check that an unencrypted password matches one that has
// previously been hashed
if (BCrypt.checkpw(candidate, hashed))
System.out.println("It matches");
else
System.out.println("It does not match");
jBCrypt是一个单一的Java文件,可以直接包含在您的应用程序中。它被认为是密码加密算法中最强大的之一。 即使解密算法存在于您的APK中,试图破解它也非常耗时,详情请参阅下面的文章。
阅读此文章以了解bcrypt的详细信息和安全性。
http://codahale.com/how-to-safely-store-a-password/
再次强调,只有在没有进行基于Web的身份验证的手段时才使用此方法。
candidate
字符串怎么样?我是不是漏掉了什么,或者这个答案没用。 - AxeEffect你可以百分之百地保护你的硬编码字符串。
首先,不要使用 pro-guard,而是使用 allatori。
其次,不要将硬编码字符串存储在任何变量中,只需像这样使用该字符串:
if(var=="abc"){}
"abc"
是一个硬编码字符串的例子。
Allatori 可以完全混淆像上面代码中使用的所有字符串。
希望对您有所帮助。
使用某种只有你(和你的代码)能理解的简单加密或密码。将字符串反转,将其存储为整数数组,其中需要取217的模数或其他愚蠢的数字才能找到真正的密码。