这件事现在已经困扰了我好几天了。我已经阅读了很多关于这整个问题的其他问题,但仍然无法继续。
我创建了一个简单的测试应用程序,只是为了在Android上测试SSL。应用程序只有一个按钮,当单击时,应用程序尝试通过SSL加密连接将“Hello World”发送到我的测试服务器,然后测试服务器以完全相同的短语进行响应。
首先,我使用openssl为我的服务器创建了测试密钥和测试证书。然后我一直按照Crazy Bob's blog中的说明进行操作。我直接从Bouncy Castle的网站获得了Bouncy Castle提供商,创建了一个可信赖的密钥库,如Crazy Bob的博客所示,并且我相信这一切都是正确的。
当我尝试运行我的代码时,我得到了异常“IOException:密钥库的错误版本。”然后我在StackOverflow上找到了this question。有人建议我尝试使用较旧的Bouncy Castle Providers而不是最新的 bcprov-jdk15on-147.jar 。我继续考虑到这一点,实际上最终尝试了从jdk13-146到jdk16-146的每个bcprovider。仍然每次我都得到相同的“IOExcpetion:错误版本的密钥库”。异常。
然后我在StackOverflow上找到了关于类似问题的yet another question。有人设法通过使用512位大小的密钥而不是1024大小的密钥来摆脱该异常。好吧,我试了一下,什么都没做,但同样的例外。
所以我现在在这里,想知道接下来该做什么。我几乎没有想法和谷歌搜索结果。
我的网络代码是疯狂bob代码的一对一副本,此外应用程序只有处理按钮的活动类。我正在尝试在API级别7上实现这一点。
非常感谢任何帮助。感谢。
答案 0 :(得分:2)
2个选择:
你可以做你做的事情并创建自己的密钥库,我已经完成了,这里是我存储的代码中的说明(因为它让它工作非常耗时):
生成PKS:
创建TRUST ALL KeyStore并忘记所有这些。基本上,您可以使用任何SSL而不会出错。如果你真的在乎,请在生产中禁用它。这是我用来准备SSL客户端的代码(假设您使用Apache Http客户端)
private HttpClient getHttpClient()
{
HttpParams params = new BasicHttpParams();
//Set main protocol parameters
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
// Turn off stale checking. Our connections break all the time anyway, and it's not worth it to pay the penalty of checking every time.
HttpConnectionParams.setStaleCheckingEnabled(params, false);
// FIX v2.2.1+ - Set timeout to 30 seconds, seems like 5 seconds was not enough for good communication
HttpConnectionParams.setConnectionTimeout(params, 30 * 1000);
HttpConnectionParams.setSoTimeout(params, 30 * 1000);
HttpConnectionParams.setSocketBufferSize(params, 8192);
// Don't handle redirects -- return them to the caller. Our code often wants to re-POST after a redirect, which we must do ourselves.
HttpClientParams.setRedirecting(params, false);
// Register our own "trust-all" SSL scheme
SchemeRegistry schReg = new SchemeRegistry();
try
{
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
TrustAllSSLSocketFactory sslSocketFactory = new TrustAllSSLSocketFactory(trustStore);
sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Scheme sslTrustAllScheme = new Scheme("https", sslSocketFactory, 443);
schReg.register(sslTrustAllScheme);
}
catch (Exception ex)
{
LogData.e(LOG_TAG, ex, LogData.Priority.None);
}
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params,schReg);
return new DefaultHttpClient(conMgr, params);
}
答案 1 :(得分:0)
当我尝试向EWS请求时,它类似于my question。您可以参考this link并下载example source code,然后像我的回答一样修改它。希望这有帮助!
<强>更新强>:
以下命令对我有用(我大约2个月前试过):
C:\OpenSSL-Win32\bin>keytool -importcert -v -trustcacerts -file "d:/cer.cer"
-alias parkgroup_restful -keystore "D:/parkgroup-ws-client.bks"
-provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath
"D:/bcprov-jdk16-145.jar" -storetype BKS -storepass 1234567
.... /**It should show the result here**/
Trust this certificate? [no]: yes
Certificate was added to keystore
[Storing D:/parkgroup-ws-client.bks]
C:\OpenSSL-Win32\bin>keytool -list -keystore "D:/parkgroup-ws-client.bks" -provi
der org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "D:/bcprov-
jdk16-145.jar" -storetype BKS -storepass 1234567
Keystore type: BKS
Keystore provider: BC
Your keystore contains 1 entry
parkgroup_restful, Apr 10, 2012, trustedCertEntry,
Certificate fingerprint (MD5): 36:47:88:62:23:1C:F3:52:17:BE:7A:A9:94:56:19:18
你可以看到,我使用 bcprov-jdk16-145.jar 和openssl lib。你可以尝试一下 另一个创建密钥库的工具:http://portecle.sourceforge.net/
答案 2 :(得分:0)
我也面临同样的情况并解决它我从 R4j 引用的同一篇博文(http://nelenkov.blogspot.in/2011/12/using-custom-certificate-trust-store-on.html)中获得了帮助。以下是涉及的步骤:
最后要创建安全的HTTPClient,您可以执行以下操作:
public static DefaultHttpClient getSecureHttpClient(){
SchemeRegistry schemeRegistry = new SchemeRegistry();
SSLContext sslContext = null;
try {
sslContext = createSslContext(true);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
final X509HostnameVerifier delegate = new BrowserCompatHostnameVerifier();
MySSLSocketFactory socketFactory = new MySSLSocketFactory(sslContext, delegate);
schemeRegistry.register(new Scheme("https", socketFactory, 443));
DefaultHttpClient client = new DefaultHttpClient();
HttpParams params = client.getParams();
client = new DefaultHttpClient(new ThreadSafeClientConnManager(params,
schemeRegistry), params){
protected HttpParams determineParams(HttpRequest req) {
HttpParams params = req.getParams(); // req is an HttpRequest object
HttpConnectionParams.setSoTimeout(params, 60000);
HttpConnectionParams.setConnectionTimeout(params, 60000);
return params;
}
};
return client;
}
有关我选择的详细原因,您可以参阅此帖http://fuking-android.quora.com/Implement-HTTPS-for-android-apps-a-novices-tale。