以纯文本格式存储用户名和密码

时间:2014-12-31 14:11:05

标签: android

我需要存储整个应用程序中常见的用户名和密码,因为它们用于连接到我的Android应用中的热点,但我不确定如何执行此操作,或者如何加密它们

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

Greg Ennis提到的答案,为您提供加密字符串的代码。我们有各种加密算法。

现在的挑战是 - 如果应用程序源代码是逆向工程并且数据被盗会怎么样?

要保护代码不受此影响,请尝试以下解决方案。

解决方案1 ​​ - Proguard

ProGuard在将Java jar文件转换为classes.dex文件之前对其进行模糊处理。

请参阅SO链接Enabling ProGuard in Eclipse for Android以了解如何在应用程序中配置proguard。

阅读此链接以了解我们可以在proguard属性文件中配置的不同选项。 http://proguard.sourceforge.net/manual/examples.html#androidapplication

一个其他简单选项将使用 proguard GUI

要启动GUI,请从SourceForge at下载 http://proguard.sourceforge.net。解压缩并执行以下命令 在lib文件夹中,假设您已将目标proguard.cfg文件复制到 proguard \ lib文件夹。您应该看到许多优化选项

解决方案2 - DashO界面(商业工具)

这包括控制流,重命名和字符串加密混淆选项。

  • 控制流程 - 重新排序字节码并旨在使其无法实现 反编译。
  • 字符串加密 - 加密许多字符串,即 作为另一个窃取API密钥的人的防范,可以非常有用 密码。
  • 重载归纳 - 类重命名:多个类可以命名为a()或b()因为 这样做是合法的Java,只要这些类有不同的方法参数。

使用DashO界面非常简单。

希望这些信息有所帮助。

答案 1 :(得分:1)

如果您在应用中将凭据存储为纯文本,则有人可以轻松地反编译并查看密码。如果您尝试加密信息,您在哪里放置加密密钥?你有同样的问题。

来自Google的blog post讨论了处理凭据的策略。但是,仅讨论存储在运行时接收的凭据,例如auth令牌或用户键入的密码。它完全避免了提出的问题和存储已知凭证的更常见情况,因为它没有答案

因此,我通常会花费一些精力来混淆信息,以便只有真正致力于了解信息的人才能看到它。这只是一个小障碍,以防止随意检查您的信息(例如,API密钥)。为此,我使用了这个助手类:

public class Obfuscator {
    private final String _P = "(PUT A RANDOM 16-CHAR STRING HERE)";

    public String obfuscate(String value) throws GeneralSecurityException {
        byte[] raw = _P.getBytes(Charset.forName("US-ASCII"));
        if (raw.length != 16) {
            throw new IllegalArgumentException("Invalid key size.");
        }

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));
        byte[] bytes = cipher.doFinal(value.getBytes(Charset.forName("US-ASCII")));
        return Base64.encodeToString(bytes, Base64.NO_WRAP);
    }

    public String deobfuscate(String encrypted) throws GeneralSecurityException {
        byte[] bytes = Base64.decode(encrypted, 0);
        byte[] raw = _P.getBytes(Charset.forName("US-ASCII"));
        if (raw.length != 16) {
            throw new IllegalArgumentException("Invalid key size.");
        }
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec,
                new IvParameterSpec(new byte[16]));
        byte[] original = cipher.doFinal(bytes);
        return new String(original, Charset.forName("US-ASCII"));
    }
}