Utilisation de BouncyCastle pour une simple requête HTTPS
Voici une version simplifiée du code que j'utilise pour effectuer des requêtes HTTPS simples:
// 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();
cela fonctionnait bien pour se connecter à notre serveur (et le fait encore si j'utilise http comme protocole) jusqu'à récemment quand certaines mises à jour de sécurité ont été faites.
maintenant il me donne le "ne pouvait pas générer DH keypair" et" la taille de Prime doit être multiple de 64, et ne peut que varier de 512 à 1024 (inclus) " erreurs mentionnées dans ce question:
Java: pourquoi la poignée de main SSL donne' ne pourrait pas générer l'exception DH keypair'?
S'avère être un bug connu en Java et la recommandation est d'utiliser L'implémentation JCE de BouncyCastle.
ma question Est... Comment puis-je utiliser le château gonflable pour quelque chose comme ça? Ou il y a plus de solutions de rechange?
Avertissement: j'ai très peu de connaissance et d'intérêt dans les domaines de la cryptologie et la technologie sous-jacente qui rend les requêtes HTTPS possibles. Je préférerais plutôt me concentrer sur ma logique d'application et laisser diverses bibliothèques s'occuper des problèmes de bas niveau.
j'ai vérifié le site Web et la documentation de BouncyCastle et J'ai cherché sur Google pour en savoir plus sur JCE etc, mais tout compte fait, c'est assez accablant et je n'ai pas été en mesure de trouver des exemples de code simples pour faire quelque chose comme le code ci-dessus.
4 réponses
le code d'échantillon suivant utilise jdk1.6.0_45 et bcprov-jdk15on-153.jar pour effectuer une requête https simple:
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);
}
}
}
Ici est une page sur la façon de s'inscrire château gonflable JCE fournisseur. Si vous choisissez la deuxième option, assurez-vous que la valeur de N
(ordre de préférence) est telle qu'elle précède le fournisseur de Sun JCE (et ajustez en conséquence l'ordre de préférence de L'enregistrement du fournisseur de Sun JCE).
j'ai trouvé une solution différente (bien que via le lien que srkavin a posté) qui ne nécessite même pas d'utiliser BouncyCastle:
après avoir téléchargé "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" à partir du Java download site et en remplaçant les fichiers dans mon JRE, le code ci-dessus a commencé à fonctionner sans aucune modification.
j'ai le même problème et à le résoudre, y compris cette ligne
Security.addProvider(new BouncyCastleProvider());
System.setProperty("https.protocols", "TLSv1");