2014-02-08 75 views
8

假设密钥库的密码不是由用户密码提供或绑定的(这或多或少意味着它只是代码中的某个字符串或数组[] []],它是一种足够的保护,它不能或不能只能很难从字节码中提取出来?好习惯:如何在android/java中处理密钥库密码?

我知道,对于一个密钥库(JKS/BKS)的密码只是用来验证密钥库的完整性。此外,我非常清楚,我必须假设应用程序运行在或多或少的可信环境中以保证“安全”。但无论如何,是否有可能从apk文件中提取密码?

就觉得这是不对的硬编码的应用程序的源代码中的任何密码,所以也许有一些想法,如何使它真正威胁较小。 例如在外部配置文件中配置密码或者在安装应用程序期间随机生成密码(以及应该存储在哪里)会更好吗?

+0

不难提取出来的东西字节/ APK中。如果你反编译它,你可以再次以明文形式粗略地显示你的源代码。我不会打扰太多,如果你的应用程序(或者你隐藏的秘密)值得黑客入侵,那么将会有一个这样做。 – zapl

+0

我会说它值得黑客入侵。 :)所以对我来说,重要的是如果密码被破坏,其他应用程序安装不会受到感染。所以创建一个安装密码似乎至少是一个“更好”的解决方案。 – evildead

+0

在密钥库密码的情况下,我可以简单地添加一个'println'到[Keystore.load](https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/security/KeyStore.java)到我的自定义固件中,甚至不需要触摸你的应用。这很简单。 Dexguard不能防止调用不受信任的平台代码,您需要推出自己的实现,以便我需要嗅探网络流量或从内存转储中读取值。 – zapl

回答

4

它是一种足够的保护,它不能或只能很难从字节码中提取出来吗?

“足够” 是主观术语;只有你可以确定你对自己的感觉是否足够。

是有可能刚刚从apk文件解压密码?

是的,作为APK文件可以反编译,未加密的网络会话可以嗅探等

如何使它真正威胁较小

你可以购买一个许可证DexGuard并使用它,因为这会加密硬编码的字符串,如密码。这是否值得额外防守是你的决定。

会是更好地使外部配置文件

任何人谁根的设备可以得到在文件中的密码进行配置。

或者在安装应用程序期间随机生成它(以及它应该存储在哪里)?

它将被存储在某个地方,这个地方至少可以被固定设备用户使用。

+0

所以这意味着,购买dexGuard或与之共存? – evildead

+0

@evildead:你可以尝试推出你自己的加密,但是你可能会追逐你的尾巴(你在哪里存储*那个加密密钥?),你不可能比DexGuard做得更好。我不知道有任何其他现成的解决方案。 – CommonsWare

+0

是的,建立在自己的加密上是没有意义的。很遗憾没有普通解决方案。否则,我想,我已经在这里或谷歌搜索中找到它了。 :) – evildead

3

使用密码对密钥库进行加密是非常普遍的事情,但它并非必不可少。

将密码存储在靠近密钥库的位置或多或少等同于密钥库未加密。这可能是完全正确的。在两个证书的未加密密钥库中使用其他方式保护密钥库文件的服务器上的私钥是很常见的。

你似乎试图在这里防范的攻击类型是如果有人能够改变密钥库的内容。密码可以用来验证密钥库的完整性,但只有在攻击者未知的情况下才可以。它无法想象攻击者可以访问密钥库但无法访问应用程序的字节码或应用程序的其他配置的典型场景。

Android中应用程序的文件系统是合理安全的,但不以任何方式防弹。如果您不信任该文件系统,则需要使用用户输入的密码或从设备外部其他位置获取的密码对密钥库进行加密。另一方面,如果您信任文件系统,则实际上根本不需要加密密钥库(或者,如果您的开发更容易,可以使用众所周知的密码对其进行加密)。使用代替密码为空

1

尝试(见this question

final KeyStore keyStore = KeyStore.getInstance("BKS"); 
    keyStore.load(context.getResources().openRawResource(R.raw.serverkeys), null); 

    final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 
    keyManager.init(keyStore, null); 

    final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
    trustFactory.init(keyStore); 

    sslContext = SSLContext.getInstance("TLS"); 
    sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), null);