保护嵌入式密码

时间:2020-03-06 14:26:15  来源:igfitidea点击:

我在Java中有一个属性文件,在其中存储我的应用程序的所有信息,例如徽标图像文件名,数据库名称,数据库用户和数据库密码。
我可以将加密的密码存储在属性文件中。
但是,可以使用反编译器从罐子中读取密钥或者密码短语。
有没有一种方法可以将db pass安全地存储在属性文件中?

解决方案

不,那里没有。即使我们对它进行加密,也会有人反编译解密它的代码。

有多种方法可以解决此问题。如果我们能找到一种方法,让用户在应用程序启动时为密钥库提供密码,则最合适的方法是使用密钥对所有值进行加密,然后将此密钥存储在密钥库中。密钥库的命令行界面是使用keytool进行的。但是,JSE也具有API以编程方式访问密钥库。

如果我们没有能力让用户在启动时(例如,对于Web应用程序)手动向密钥库提供密码,则一种方法是编写一个异常复杂的混淆例程,该例程可以对密钥进行混淆并将其存储在属性文件。要记住的重要事项是,混淆和反混淆逻辑应该是多层的(可能涉及加扰,编码,引入虚假字符等),并且本身应该至少具有一个可以在应用程序的其他类中隐藏的键使用不直观的名称。这不是一种完全安全的机制,因为具有反编译器并且有相当多的时间和智能的人仍然可以解决该问题,但这是我所知道的唯一一种不需要我们破解本机(即,不容易反编译)代码的机制。 。

我们可以为密码(直接DB密码或者密钥密码)创建一个单独的属性文件(在jar之外),并且不将该属性文件包含在分发中。或者,我们也许可以使服务器仅接受来自特定计算机的登录,这样就需要进行欺骗。

我们将密码的SHA1哈希存储在属性文件中。然后,当我们验证用户密码时,可以对他们的登录尝试进行哈希处理,并确保两个哈希值匹配。

这是将为我们哈希一些字节的代码。我们可以使用getBytes()方法轻松地从字符串中提取字节。

/**
     * Returns the hash value of the given chars
     * 
     * Uses the default hash algorithm described above
     * 
     * @param in
     *            the byte[] to hash
     * @return a byte[] of hashed values
     */
    public static byte[] getHashedBytes(byte[] in)
    {
        MessageDigest msg;
        try
        {
            msg = MessageDigest.getInstance(hashingAlgorithmUsed);
        }
        catch (NoSuchAlgorithmException e)
        {
            throw new AssertionError("Someone chose to use a hashing algorithm that doesn't exist.  Epic fail, go change it in the Util file.  SHA(1) or MD5");
        }
        msg.update(in);
        return msg.digest();
    }

除了如上所述对密码进行加密之外,还将所有密码放在单独的属性文件中,并在部署时尝试为该文件提供最大程度的锁定权限。

例如,如果应用程序服务器在Linux / Unix上以" root"身份运行,则将" root"拥有的密码属性文件设置为具有400 /-r --------权限。

经过某种方式的身份验证后,我们是否可以让该应用通过https与服务器联系并下载密码?