Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用URL.openConnection()建立HTTPS连接_Java_Android_Https_Bouncycastle_Keystore - Fatal编程技术网

Java 使用URL.openConnection()建立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

我正在尝试与证书设置为2013年4月到期并使用GlobalSign作为根证书的建立HTTPS连接

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

多亏了各种各样的人对这一点的提示,有许多事情都需要正确才能让它工作

  • 如果HTTPS站点的证书由受信任的根证书签名,那么它将在没有自定义
    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,导致与下一种情况混淆

  • 您需要使用Bouncy Castle提供程序的适当版本(,)。在大多数情况下,这似乎是 这可以放在JRE的
    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修复了版本问题。我在下面写了一个完整的解决方案/解释。