Java 如何在Android中使用自签名SSL证书
这件事已经困扰我好几天了。我已经阅读了很多关于整个问题的其他问题,但仍然无法继续 我创建了一个简单的测试应用程序,只是为了在Android上测试SSL。该应用程序只有一个按钮,单击该按钮时,该应用程序会尝试通过SSL加密连接将“Hello World”发送到我的测试服务器,然后该服务器会使用完全相同的短语进行响应 首先,我使用openssl为我的服务器创建了一个测试密钥和测试证书。然后我一直在按照中显示的说明进行操作。我直接从Bouncy Castle的网站上获得了Bouncy Castle提供商,创建了一个可信的密钥库,如疯狂鲍勃的博客所示,我相信在这一点上一切都是正确的 当我试图运行我的代码时,我得到了异常“IOException:密钥存储的错误版本”。然后我在StackOverflow上发现。有人建议我应该尝试使用更老的Bouncy Castle提供者,而不是最新的bcprov-jdk15on-147.jar。我考虑到了这一点,实际上最终尝试了从jdk13-146到jdk16-146的每一个bcprovider。但每次我都会收到同样的“IoException:密钥存储的错误版本”例外 然后我在StackOverflow上发现了类似的问题。有人设法通过使用512位大小的密钥而不是1024位大小的密钥来消除该异常。嗯,我试了一下,什么也没做,但还是一样的例外 所以我现在在这里,想知道下一步该做什么。我的想法和谷歌搜索结果都快用完了 我的web代码是crazy bob代码的1对1副本,除此之外,应用程序只有只处理按钮的activity类。我试图在API级别7上实现这一点 任何帮助都将不胜感激。谢谢。当我试图请求EWS时也是如此。你可以参考和下载,然后像我的答案一样修改它。希望这有帮助 更新:Java 如何在Android中使用自签名SSL证书,java,android,ssl,https,android-networking,Java,Android,Ssl,Https,Android Networking,这件事已经困扰我好几天了。我已经阅读了很多关于整个问题的其他问题,但仍然无法继续 我创建了一个简单的测试应用程序,只是为了在Android上测试SSL。该应用程序只有一个按钮,单击该按钮时,该应用程序会尝试通过SSL加密连接将“Hello World”发送到我的测试服务器,然后该服务器会使用完全相同的短语进行响应 首先,我使用openssl为我的服务器创建了一个测试密钥和测试证书。然后我一直在按照中显示的说明进行操作。我直接从Bouncy Castle的网站上获得了Bouncy Castle提供
以下命令对我有效(我大约2个月前尝试过): 您可以看到,我使用了bcprov-jdk16-145.jar和openssl库。你可以试试。
创建密钥库的另一个工具:2个选项:
我也遇到了同样的情况,为了解决这个问题,我从R4j引用的同一篇博文()中获得了帮助。涉及的步骤如下:
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;
}
关于我选择的详细原因,您可以参考本文。如果您将目标API移动到10或14左右,它是否开始工作?在旧的API级别上工作时,在新的API级别上测试并不是一个坏主意,只是为了确保它不存在兼容性问题。我需要为我的Android brain tree项目创建“.pem”文件。我安装了openssl并运行以下cmd:openssl>s|u client-connect$2>&1 |\sed-ne'/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'>mycert.pem,但我在s|u client中遇到错误。请帮帮我。我从疯狂鲍勃的博客中得到了这个命令。谢谢你的链接,但仍然无法克服“密钥存储错误版本”的异常。我不确定我是否真的了解你在第一行中所做的事情,因为在我看来,你从来没有使用过你在那里创建的PEM。你能解释一下吗?否则,您的解决方案看起来与我尝试过的非常相似。我已经尝试过bcprov-jdk16-145.jar(以及其他版本)和openssl。我建议您检查您的证书文件,因为我与您的问题相同。然后我尝试使用另一个文件,它成功了。如果我使用“信任所有”选项,是否意味着我的应用程序是唯一信任所有站点的应用程序?换句话说,我只是想确保它不会以任何方式影响手机上的其他应用程序。我的应用程序正在使用的URL是硬编码的,因为它从不更改,因此允许应用程序信任所有站点可能是安全的
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);
}
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;
}