我有2个应用程序,一个是Servlet / Tomcat服务器,另一个是Android应用程序。
我想使用HttpURLConnection在两者之间发送和接收XML。
码:
private String sendPostRequest(String requeststring) {
DataInputStream dis = null;
StringBuffer messagebuffer = new StringBuffer();
HttpURLConnection urlConnection = null;
try {
URL url = new URL(this.getServerURL());
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
out.write(requeststring.getBytes());
out.flush();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
dis = new DataInputStream(in);
int ch;
long len = urlConnection.getContentLength();
if (len != -1) {
for (int i = 0; i < len; i++)
if ((ch = dis.read()) != -1) {
messagebuffer.append((char) ch);
}
} else {
while ((ch = dis.read()) != -1)
messagebuffer.append((char) ch);
}
dis.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
urlConnection.disconnect();
}
return messagebuffer.toString();
}
现在,我需要使用SSL来发送XML以确保安全。
首先,我使用Java Keytool生成.keystore文件。
Keytool -keygen -alias tomcat -keyalg RSA
然后我将XML代码放在Tomcat的server.xml文件中以使用SSL
<Connector
port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="c:/Documents and Settings/MyUser/.keystore"
keystorePass="password"
clientAuth="false" sslProtocol="TLS"
/>
然后,将其更改为HttpsURLConnection的HttpURLConnection
private String sendPostRequest(String requeststring) {
DataInputStream dis = null;
StringBuffer messagebuffer = new StringBuffer();
HttpURLConnection urlConnection = null;
//Conexion por HTTPS
HttpsURLConnection urlHttpsConnection = null;
try {
URL url = new URL(this.getServerURL());
//urlConnection = (HttpURLConnection) url.openConnection();
//Si necesito usar HTTPS
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
//Creo la Conexion
urlHttpsConnection = (HttpsURLConnection) url.openConnection();
//Seteo la verificacion para que NO verifique nada!!
urlHttpsConnection.setHostnameVerifier(DO_NOT_VERIFY);
//Asigno a la otra variable para usar simpre la mism
urlConnection = urlHttpsConnection;
} else {
urlConnection = (HttpURLConnection) url.openConnection();
}
//Do the same like up
并添加trustAllHosts方法以信任每个服务器(不要检查任何证书)
private static void trustAllHosts() {
X509TrustManager easyTrustManager = new X509TrustManager() {
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
// Oh, I am easy!
}
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
// Oh, I am easy!
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
这些更改效果很好,但是我不想信任每台服务器。我想使用我的密钥库文件来验证连接并以正确的方式使用SSL。我在互联网上阅读了很多书,做了很多测试,但是我不明白我必须做些什么以及如何做。
有人可以帮我吗?
非常感谢你
对不起,我英语不好
好吧,我还在努力。我做了一个新方法来设置KeyStore,InputStream等
该方法如下所示:
private static void trustIFNetServer() {
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore ks = KeyStore.getInstance("BKS");
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
String keyPassword = "password";
ks.load(in, keyPassword.toCharArray());
in.close();
tmf.init(ks);
TrustManager[] tms = tmf.getTrustManagers();
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, tms, new java.security.SecureRandom());
} catch (Exception e) {
e.printStackTrace();
}
}
首先,我在密钥和证书方面遇到很多问题,但现在可以正常工作了(我认为是这样)
我现在的问题是超时异常。我不知道为什么会生成。我认为这与数据写入有关,但是我还无法解决。
任何想法?
您需要按照此处所述为自签名证书创建信任存储文件。在客户端使用它来连接服务器。不管您使用JKS还是其他格式都没有关系,我现在假设使用JKS。
要实现您的想法TrustManager
,显然需要一个不同的方法。您可以将TrustManagerFactory
其信任设置与新创建的信任存储区一起使用。
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream in = new FileInputStream("<path to your key store>");
ks.load(in, "password".toCharArray());
in.close();
tmf.init(ks);
TrustManager[] tms = tmf.getTrustManagers();
使用tms
来初始化你SSLContext
,而不是为新的信任设置用于您的SSL / TLS连接。
你还应该确保该CN
服务器TLS证书的一部分,等于您的服务器,如的FQDN(完全合格的域名),如果你的服务器基本URL是“
https://www.example.com ”,那么CN
的证书应为“
www.example.com”。主机名验证需要此功能,此功能可防止中间人攻击。您可以禁用此功能,但只有在使用此功能时,您的连接才会真正安全。
我得到一个"异常在线程"主"javax.net.ssl.SSLHandshake异常:收到致命警报:handshake_failure"下面的代码。有人知道如何修复它吗?
问题内容: 我正在做一个https帖子,但是却得到ssl异常的一个例外,不受信任的服务器证书。如果我做正常的HTTP,它工作正常。我是否必须以某种方式接受服务器证书? 问题答案: 我正在猜测,但是如果你想进行实际的握手,则必须让android知道你的证书。如果你只想接受任何内容,请使用以下伪代码通过Apache HTTP Client获得所需的内容: CustomSSLSocketFactory:
我的连接代码如下所示: 干杯,马尔辛
我试图使用PowerShell从https网站抓取html内容。 不幸的是,该站点只例外一组有限的SSL/TLS密码套件,不支持Powershell可用的套件。 如果尝试使用Invoke-WebRequest cmdlet,我会收到以下错误消息: 调用-网络请求:请求被中止:无法创建SSL/TLS安全通道。 问题: 是否有办法指定PowerShell使用的客户端SSL/TLS密码套件? 还有其他c
我有一个问题,当我尝试读取任何输入时,我的网络连接会抛出一个EOFException。该代码适用于某些网络调用,但不适用于其他网络调用。如果我尝试从连接中读取任何内容,则会失败并出现上述错误。 例: 以下是每个堆栈的跟踪: getResponse: 缓冲输入流: 感谢您的任何帮助, 瑞克 编辑 我找到了我的答案: 这不是一个有据可查的答案。它出现在一些较新版本的android中,存在一个带有回收u
我在Java中与SSL连接有问题。 我使用java 1.7.80和S. O.: ubuntu 14.04 我的问题是证书,甚至证书。我有四个必须使用pkcs12格式连接的元素。 -- -- -- -- 1) 步骤-将文件cer转换为文件pem 2)步骤-创建链证书的联合pem文件 3)步骤-创建p12文件 好啊我的第一个测试是在浏览器(Mozilla Firefox)中导入p12文件以验证操作。导