在 Android 4+ (ICS) 中为 aSmack 使用 Android TrustStore
Posted
技术标签:
【中文标题】在 Android 4+ (ICS) 中为 aSmack 使用 Android TrustStore【英文标题】:Using the Android TrustStore for aSmack in Android 4+ (ICS) 【发布时间】:2012-06-01 12:30:14 【问题描述】:我不是密钥库方面的专家,很难理解其中的细微差别,但这就是我能做到的:
在使用 here 找到的 asmack 构建创建 xmpp 连接时,仍然需要更改信任库,通常,例如网络上的多个 sources,使用这些命令完成
ConnectionConfiguration config = new ConnectionConfiguration(host, Integer.parseInt(port), service);
config.setTruststorePath("/system/etc/security/cacerts.bks");
config.setTruststorePassword("changeit");
config.setTruststoreType("bks");
XMPPConnection connection = new XMPPConnection(connConfig);
connection.connect();
这适用于较旧的 android 版本,但在 ICS 下他们更改了一些内容,现在不再更改。现在的路径不同了。
显然是this can be fixed,但我不知道该怎么做。
显然,需要一种根据 SDK 版本返回路径的方法,该方法返回设置 sdk 路径所需的字符串,因为您不能只将密钥库本身返回到 xmpp 连接。
参考this,该方法如下所示:
private String getTrustStorePath()
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
if ( Build.VERSION.SDK_INT >= 14 )
//THIS IS THE PART I DONT KNOW
path="";
else
path = "/system/etc/security/cacerts.bks";
return path;
Here 一位评论者说,在 Android 下,“4.x;/etc/security/cacerts.bks 被替换为目录 /etc/security/cacerts/,其中包含作为单独 PEM 编码文件的证书。”但是,我不知道这有什么相关性(如果有的话)。
我还检查了使用 xmpp 和 asmack 的两个项目的代码(gtalksms 和 yaxim,但没有看到他们如何避免这个问题。
【问题讨论】:
我目前也在调查这个问题。我们最近有changed how we detect the truststore path on GTalkSMS,因为它也可以是seen here。但我很确定这还不够…… 【参考方案1】:试试这个:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
connectionConfiguration.setTruststoreType("AndroidCAStore");
connectionConfiguration.setTruststorePassword(null);
connectionConfiguration.setTruststorePath(null);
else
connectionConfiguration.setTruststoreType("BKS");
String path = System.getProperty("javax.net.ssl.trustStore");
if (path == null)
path = System.getProperty("java.home") + File.separator + "etc"
+ File.separator + "security" + File.separator
+ "cacerts.bks";
connectionConfiguration.setTruststorePath(path);
请参阅https://github.com/Flowdalic/asmack/wiki/Truststore 和http://nelenkov.blogspot.com/2011/12/ics-trust-store-implementation.html 的一些背景说明。
【讨论】:
嗨,我用上面的 Jellybean 代码,所以它工作正常,我也可以验证用户。但是我也看到了一个从proceedTLSReceived抛出的异常java.lang.NullPointerException,它又调用ServerTrustManager。它为 configuration.getTruststorePath() 崩溃。有什么想法吗? @anaargund 我也看到了同样的问题。 ICS 和 JellyBean。 @Geebs 我解决了。我从 asmack 网站下载了最新版本的 jar 文件。我之前遇到过问题,因为我使用的是一些旧的 jar 文件。刚开始用最新的,大部分问题都解决了。 如何创建信任存储路径和那些背景,请解释这些东西@Phillip【参考方案2】:ICS 中的信任存储不再位于单个 .bks 文件中,而是位于 /system/etc/security/cacerts
目录中的单独 PEM 编码文件中。用户添加的证书可以放在/data/misc/keychain/cacerts-added
。更多详情请见here。
您的证书文件必须命名为:subject-hash.N
其中 N 是从 0 开始的连续整数(通常只有 0,但如果已使用 0,则为 1,等等)。
要获取证书的主题哈希,您可以像这样使用 openssl:
openssl x509 -noout -subject_hash_old -in my-cert-file.pem
【讨论】:
谢谢,但是如何配置连接,如果不再存在,则需要设置信任库的路径?jivesoftware.smack.ConnectionConfiguration
需要使用 setTruststorePath
,因为最终结果需要是 XMPP 连接。
或者,换个方向:我可以在不设置信任存储的情况下创建连接吗?可以说是不受信任的连接。
你试过菲利普的答案吗?在 ICS 中您不需要设置信任存储路径,只需设置信任存储类型“AndroidCAStore”即可。
是的,我试过了,它(几乎)工作了(我认为错误出在我周围的代码中)。我现在进一步减少了它,没有使用任何类型的信任或加密。基本上是here 所示的最低限度。这当然缺乏任何安全性,但现在似乎可以让我从事其他工作......以上是关于在 Android 4+ (ICS) 中为 aSmack 使用 Android TrustStore的主要内容,如果未能解决你的问题,请参考以下文章
Android 4 ICS Ice Cream Sandwich - 包含表单的 iframe
使用 AsyncTask 的 Android ICS 和 MJPEG
带有 SQLite 的 Android 应用程序在 ICS 中运行,但在 Jelly Bean 中不运行 - IllegalStateException
ICS 4.0.3 上的 ActionBar 和 Fragments