这是我用来执行简单 HTTPS 请求的代码的简化版本:
// Assume the variables host, file and postData have valid String values
final URL url = new URL("https", host, file);
final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-length", String.valueOf(postData.length()));
final DataOutputStream output = new DataOutputStream(connection.getOutputStream());
output.writeBytes(postData);
output.close();
final InputStream input = new DataInputStream(connection.getInputStream());
for (int c = input.read(); c != -1; c = input.read()) {
System.out.print((char) c);
}
System.out.println();
input.close();
直到最近完成了一些安全升级后,它才可以很好地连接到我们的服务器(如果我使用 http 作为协议(protocol),它仍然可以)。
现在它给我这个问题中提到的“Could not generate DH keypair”和“Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)”错误:
Java: Why does SSL handshake give 'Could not generate DH keypair' exception?
事实证明这是 Java 中的一个已知错误,建议使用 BouncyCaSTLe 的 JCE 实现。
我的问题是……我如何使用 BouncyCaSTLe 来做这样的事情?还是有更多选择?
免责声明:我对密码学和使 HTTPS 查询成为可能的底层技术知之甚少,也不感兴趣。相反,我更愿意专注于我的应用程序逻辑,让各种库处理低级别的问题。
我查看了 BouncyCaSTLe 网站和文档,并通过 Google 搜索以查找有关 JCE 等的更多信息,但总而言之,我无法找到任何简单的代码示例来执行类似上述代码的操作。
最佳答案
以下示例代码使用jdk1.6.0_45和bcprov-jdk15on-153.jar进行简单的https查询:
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;
import org.bouncycastle.crypto.tls.CertificateRequest;
import org.bouncycastle.crypto.tls.DefaultTlsClient;
import org.bouncycastle.crypto.tls.TlsAuthentication;
import org.bouncycastle.crypto.tls.TlsClientProtocol;
import org.bouncycastle.crypto.tls.TlsCredentials;
public class TestHttpClient {
// Reference: http://boredwookie.net/index.php/blog/how-to-use-bouncy-castle-lightweight-api-s-tlsclient/
// bcprov-jdk15on-153.tar\src\org\bouncycastle\crypto\tls\test\TlsClientTest.java
public static void main(String[] args) throws Exception {
java.security.SecureRandom secureRandom = new java.security.SecureRandom();
Socket socket = new Socket(java.net.InetAddress.getByName("www.google.com"), 443);
TlsClientProtocol protocol = new TlsClientProtocol(socket.getInputStream(), socket.getOutputStream(),secureRandom);
DefaultTlsClient client = new DefaultTlsClient() {
public TlsAuthentication getAuthentication() throws IOException {
TlsAuthentication auth = new TlsAuthentication() {
// Capture the server certificate information!
public void notifyServerCertificate(org.bouncycastle.crypto.tls.Certificate serverCertificate) throws IOException {
}
public TlsCredentials getClientCredentials(CertificateRequest certificateRequest) throws IOException {
return null;
}
};
return auth;
}
};
protocol.connect(client);
java.io.OutputStream output = protocol.getOutputStream();
output.write("GET / HTTP/1.1\r\n".getBytes("UTF-8"));
output.write("Host: www.google.com\r\n".getBytes("UTF-8"));
output.write("Connection: close\r\n".getBytes("UTF-8")); // So the server will close socket immediately.
output.write("\r\n".getBytes("UTF-8")); // HTTP1.1 requirement: last line must be empty line.
output.flush();
java.io.InputStream input = protocol.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
}
}
关于java - 使用 BouncyCaSTLe 进行简单的 HTTPS 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8171802/