Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.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 使用bouncycastle提供程序后,有没有办法解决连接重置问题_Java_Ssl_Bouncycastle_Tls1.2_Connection Reset - Fatal编程技术网

Java 使用bouncycastle提供程序后,有没有办法解决连接重置问题

Java 使用bouncycastle提供程序后,有没有办法解决连接重置问题,java,ssl,bouncycastle,tls1.2,connection-reset,Java,Ssl,Bouncycastle,Tls1.2,Connection Reset,我使用的是java 1.6.0_111,它不支持tlsv1.2,但我的服务器只接受tlsv1.2,因此我尝试使用bouncycastle提供程序,但仍然无法正常工作,因为它抛出了连接重置错误。即使我将connecttimeout增加到30000,它仍然在conn.getoutputstream处出错 下面是我的代码: Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); Security.insertProviderAt(new

我使用的是java 1.6.0_111,它不支持tlsv1.2,但我的服务器只接受tlsv1.2,因此我尝试使用bouncycastle提供程序,但仍然无法正常工作,因为它抛出了连接重置错误。即使我将connecttimeout增加到30000,它仍然在conn.getoutputstream处出错

下面是我的代码:

Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
Security.insertProviderAt(new BouncyCastleProvider(), 1);

Security.removeProvider(BouncyCastleJsseProvider.PROVIDER_NAME);
Security.insertProviderAt(new BouncyCastleJsseProvider(), 2);

SSLContext sslContext = SSLContext.getInstance("TLSv1.2", new BouncyCastleJsseProvider());

log("The Supported Protocols are::"+Arrays.asList(protocols));

/*sslContext.init(null, tmf.getTrustManagers(), null);
SSLContext.setDefault(sslContext);;*/
String https_url ="myprodurl";
String json = mattArray.toString().trim();
URL url = new URL(https_url);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
log("after opening connection");
conn.setConnectTimeout(30000);
log("step1");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setRequestMethod("POST");
log("step2");
OutputStream os = conn.getOutputStream();
log("step3");
os.write(json.getBytes("UTF-8"));
log("step4");
os.close();
log("after closing outputstream");
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = IOUtils.toString(in, "UTF-8");
log("Result after Reading JSON Response\n\n");
log(response);
我得到的错误是:

2020-02-04 21:00:42,386 [system] [DEBUG] test - ERROR2 :java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:168)
    at com.ibm.jsse2.a.a(a.java:148)
    at com.ibm.jsse2.a.a(a.java:96)
    at com.ibm.jsse2.tc.a(tc.java:302)
    at com.ibm.jsse2.tc.g(tc.java:208)
    at com.ibm.jsse2.tc.a(tc.java:482)
    at com.ibm.jsse2.tc.startHandshake(tc.java:597)
    at com.ibm.net.ssl.www2.protocol.https.c.afterConnect(c.java:44)
    at com.ibm.net.ssl.www2.protocol.https.d.connect(d.java:36)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1014)
    at com.ibm.net.ssl.www2.protocol.https.b.getOutputStream(b.java:66)

我无法测试IBM j6,但对于Sun/Oracle j6(6u45,最后一个免费版本),它对TLS1.0具有相同的限制,您设置providerlist的方法对我来说很有效,因为我没有其他代码更改默认值,因此显式设置SSLContext默认值、HttpsURLConnection默认值或连接实例也是如此,正如我所说。如果服务器想要使用ECC,后三个确实需要提供程序列表中的bcprov,就像今天的许多服务器一样,因为Sun j6没有ECC提供程序;我对IBMJ6没有把握。对于我的测试服务器,我可以使用默认的信任库(因为我之前已经设置了默认的信任库来处理我的测试服务器);这对你来说可能有所不同。我必须使用一个显式的非默认随机源,否则我会得到神秘的错误

我对这四种方法的测试代码(可选择在后三种方法中包括bcprov)为:

static void SO60068561BouncyTLS(字符串[]args)引发异常{
字符串url=args[0];
int n=Integer.parseInt(args[1]);
Provider p1=(Provider)Class.forName(“org.bouncycastle.jce.Provider.BouncyCastleProvider”).newInstance();
Provider p2=(Provider)Class.forName(“org.bouncycastle.jsse.Provider.BouncyCastleJsseProvider”).newInstance();
SSLContext ctx=null;
如果(n==1){Security.insertProviderAt(p1,1);Security.insertProviderAt(p2,2);}
else{ctx=SSLContext.getInstance(“TLSv1.2”,p2);ctx.init(null,null,new SecureRandom());}
if(n<0){Security.addProvider(p1);n=-n;}
如果(n==2)SSLContext.setDefault(ctx);
如果(n==3)HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
HttpsURLConnection conn=(HttpsURLConnection)新URL(URL).openConnection();
如果(n==4)conn.setsslssocketfactory(ctx.getSocketFactory());
连接();
System.out.println(连接getCipherSuite()+“”+连接getResponseCode());
}

我无法测试IBM j6,但对于Sun/Oracle j6(6u45,最后一个免费版本),它对TLS1.0具有相同的限制,您设置providerlist的方法对我有效,因为我没有其他代码更改默认值,因此显式设置SSLContext默认值、HttpsURLConnection默认值或连接实例也是如此,正如我所说。如果服务器想要使用ECC,后三个确实需要提供程序列表中的bcprov,就像今天的许多服务器一样,因为Sun j6没有ECC提供程序;我对IBMJ6没有把握。对于我的测试服务器,我可以使用默认的信任库(因为我之前已经设置了默认的信任库来处理我的测试服务器);这对你来说可能有所不同。我必须使用一个显式的非默认随机源,否则我会得到神秘的错误

我对这四种方法的测试代码(可选择在后三种方法中包括bcprov)为:

static void SO60068561BouncyTLS(字符串[]args)引发异常{
字符串url=args[0];
int n=Integer.parseInt(args[1]);
Provider p1=(Provider)Class.forName(“org.bouncycastle.jce.Provider.BouncyCastleProvider”).newInstance();
Provider p2=(Provider)Class.forName(“org.bouncycastle.jsse.Provider.BouncyCastleJsseProvider”).newInstance();
SSLContext ctx=null;
如果(n==1){Security.insertProviderAt(p1,1);Security.insertProviderAt(p2,2);}
else{ctx=SSLContext.getInstance(“TLSv1.2”,p2);ctx.init(null,null,new SecureRandom());}
if(n<0){Security.addProvider(p1);n=-n;}
如果(n==2)SSLContext.setDefault(ctx);
如果(n==3)HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
HttpsURLConnection conn=(HttpsURLConnection)新URL(URL).openConnection();
如果(n==4)conn.setsslssocketfactory(ctx.getSocketFactory());
连接();
System.out.println(连接getCipherSuite()+“”+连接getResponseCode());
}

(1)重置和超时是完全不同和不相关的事情(2)stacktrace表明您实际上没有使用BC实现,即使您将其放在提供程序列表中;检查是否存在任何其他(以前的)代码设置
SSLContext
default或
HttpsURLConnection
default工厂——和/或在此处取消注释
SSLContext
default的设置,或将
HttpsURLConnection
的默认设置或实例工厂设置替换为
HttpsURLConnection
,请通过提供对上述代码的修改来帮助,该代码有效(1)重置和超时是完全不同和不相关的事情(2)stacktrace表明您实际上没有使用BC实现,即使您将其放在提供者列表中;检查是否存在任何其他(以前的)代码设置
SSLContext
默认值或
HttpsURLConnection
默认工厂-和/或在此处取消注释
SSLContext
默认值的设置,或将
HttpsURLConnection
的默认设置或实例工厂设置替换为
HttpsURLConnection
请提供对上述代码的修改,以帮助,我没有这样做理解什么是“n”值正如我所说,有四种方法可以做到这一点,其中三种方法有所不同
n
是作为程序输入提供的一个数字——具体来说,通过
args[1]
——它控制执行这些方法中的哪一个,因此我只需要一个程序而不是七个。我不明白“n”值是什么,因为我说过有四种方法,其中三种不同
n
是作为程序输入提供的一个数字——特别是通过
args[1]
——它控制执行哪些方法,因此我只需要一个程序而不是七个程序。
static void SO60068561BouncyTLS (String[] args) throws Exception {
    String url = args[0];
    int n = Integer.parseInt (args[1]);
    Provider p1 = (Provider)Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider").newInstance();
    Provider p2 = (Provider)Class.forName("org.bouncycastle.jsse.provider.BouncyCastleJsseProvider").newInstance();
    SSLContext ctx = null;
    if( n == 1 ){ Security.insertProviderAt(p1, 1); Security.insertProviderAt(p2, 2); }
    else{ ctx = SSLContext.getInstance("TLSv1.2", p2); ctx.init(null, null, new SecureRandom()); }
    if( n < 0 ){ Security.addProvider(p1); n = -n; }

    if( n == 2 ) SSLContext.setDefault (ctx);
    else if( n == 3 ) HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());
    HttpsURLConnection conn = (HttpsURLConnection) new URL(url).openConnection();
    if( n == 4 ) conn.setSSLSocketFactory(ctx.getSocketFactory());
    conn.connect();
    System.out.println (conn.getCipherSuite()+" "+conn.getResponseCode());
}