Java 使用URL.openConnection()建立HTTPS连接
我正在尝试与证书设置为2013年4月到期并使用GlobalSign作为根证书的建立HTTPS连接Java 使用URL.openConnection()建立HTTPS连接,java,android,https,bouncycastle,keystore,Java,Android,Https,Bouncycastle,Keystore,我正在尝试与证书设置为2013年4月到期并使用GlobalSign作为根证书的建立HTTPS连接 HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); // urlConnection.setSSLSocketFactory(sslSocketFactory); urlConnection.setDoOutput(true); urlConnection.setChunkedStreamingM
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
// urlConnection.setSSLSocketFactory(sslSocketFactory);
urlConnection.setDoOutput(true);
urlConnection.setChunkedStreamingMode(0);
// Send the POST data
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
out.write(postParamString.toString().getBytes("UTF8"));
// Read the reply
InputStream in = urlConnection.getInputStream();
目前,当调用getOutputStream()
时,会抛出javax.net.ssl.SSLHandshakeException:org.bouncycastle.jce.exception.ExtCertPathValidatorException:无法验证证书签名。
此网站和证书在HTC股票网络浏览器和桌面浏览器中有效。当我使用相同的代码访问时,它工作正常(但随后抱怨404错误)。StackOverflow上的各种帖子都暗示它应该“正常工作”,其他人说应该设置自己的密钥存储(或禁用所有HTTPS验证!)我认为行为的不同在于使用的不同根密钥存储(有人能澄清这一点吗?)
我现在尝试使用bouncy castle创建密钥存储,但无法将其加载到我的设备上
从Firefox导出证书后,我使用以下方法创建密钥存储:
keytool.exe -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -keystore res\raw\keystore
然后使用以下方法加载并在应用程序中使用:
InputStream stream = context.getResources().openRawResource(R.raw.keystore);
// BKS seems to be the default but we want to be explicit
KeyStore ks = KeyStore.getInstance("BKS");
ks.load(stream, "www.onlinescoutmanager.co.uk".toCharArray());
stream.close();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(ks);
X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0];
SSLContext context2 = SSLContext.getInstance("TLS");
context2.init(null, new TrustManager[] { defaultTrustManager }, null);
sslSocketFactory = context2.getSocketFactory();
这在java.io.IOException:密钥存储的版本错误时失败。
调用keystore.Load()
时
我有,正如在撰写本文时一样,如果需要的话。Bouncy Castle 1.47正在使用不同的版本标题。你能试试吗,它应该有用
keytool -import -alias onlinescoutmanager -file www.onlinescoutmanager.co.uk.crt -storetype BKS -storepass osmosm -keystore C:/keystore -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-ext-jdk15on-1.46.jar
多亏了各种各样的人对这一点的提示,有许多事情都需要正确才能让它工作
SSLSocketFactory
的情况下立即运行。
受信任的根证书可能与浏览器使用的根证书不同,因此不要假设如果它在Android web浏览器中工作,那么它将在您的应用程序中工作。如果它不是一个受信任的根证书,并且您得到了异常,如
javax.net.ssl.SSLHandshakeException:org.bouncycastle.jce.exception.ExtCertPathValidatorException:无法验证证书签名。
,那么您需要创建并加载密钥存储,如下所示keytool
命令行上指定-storetype bks
来使用Bouncy Castle提供程序()生成密钥存储。如果Bouncy Castle未正确安装,则会出现各种异常,包括
java.security.KeyStoreException:BKS not found
。
如果密钥存储不是使用Bouncy Castle提供程序创建的,那么您可能会得到java.io.IOException:密钥存储的版本错误。
exception,导致与下一种情况混淆lib/ext/
文件夹中,并将类名添加到lib/security/java.security
,或者直接在命令行上指定到keytool
。
如果它是一个不兼容的版本(或存储类型),您将得到如下异常:java.io.IOException:key store的错误版本。
javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidatorException:Trust-anchor for certification path not found.
异常javax.net.ssl.SSLHandshakeException:org.bouncycastle.jce.exception.ExtCertPathValidatorException:IssuerName(CN=XYZ)与签名证书的SubjectName(CN=ABC)不匹配。
或者再次,通用javax.net.ssl.SSLHandshakeException:java.security.cert.CertPathValidator异常:找不到证书路径的信任锚。
我还没有找到办法在钥匙店订购,所以只好求助我认为这涵盖了我发现的每一个陷阱,但请随意扩展并将linsk添加到相关问题中。这绝对是我在任何方面见过的最好的公式化问题site@AndreaLigios我必须回答几个问题,我应该知道规则以及如何“提出一个体面的问题”:p@Deanna创建密钥库时,您是否应该在选项中设置-trustedcacerts,以便它使用受信任的证书验证证书?(neve根据核心java相似性使用BKS猜测)@Deanna道歉,打字错误。应该是信任的人。希望这能起作用,如果不行,我将把它留给实际使用过BKSI的人。我也尝试过将上面的两个CA证书添加到密钥库并信任它们,但结果是相同的:|。我已经使用了1.45(我最初使用的是1.47,请参见问题)1.46会有所不同吗?请记住,我目前的目标是使用1.45.Hmmm的Android 2.3,我没有尝试使用1.45版本,但我可以说您的项目成功加载了1.46版本创建的密钥库。谢谢,使用1.46修复了版本问题。我在下面写了一个完整的解决方案/解释。