6

単純な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を使用する場合でも機能します)。

これで、「DHキーペアを生成できませんでした」および「プライムサイズは64の倍数である必要があり、512〜1024(両端を含む)の範囲でしかありません」というエラーが表示されます。

Java:SSLハンドシェイクで「DHキーペアを生成できませんでした」という例外が発生するのはなぜですか?

これはJavaの既知のバグであることが判明したため、BouncyCastleのJCE実装を使用することをお勧めします。

私の質問は...このようなものにBouncyCastleをどのように使用するのですか?または、他に選択肢はありますか?

免責事項:私は、暗号化とHTTPSクエリを可能にする基盤技術についての知識と関心をほとんど持っていません。むしろ、アプリケーションロジックに焦点を当て、さまざまなライブラリに低レベルの問題を処理させたいと思います。

BouncyCastleのWebサイトとドキュメントをチェックし、GoogleでJCEなどの詳細を調べましたが、全体としては非常に圧倒的であり、上記のコードのようなことを行うための簡単なコード例を見つけることができませんでした。

4

4 に答える 4

5

次のサンプルコードは、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);
        }
    }
}
于 2015-10-19T09:27:46.233 に答える
3

弾力がある城のJCEプロバイダーを登録する方法のページはここにあります。2番目のオプションを選択する場合は、N(優先順位)の値がSun JCEプロバイダーに先行するようになっていることを確認してください(したがって、Sun JCEプロバイダー登録の優先順位を調整してください)。

于 2011-11-17T18:21:23.313 に答える
1

BouncyCastleを使用する必要さえない別の解決策を(srkavinが投稿したリンクを介して)見つけました:

Javaダウンロードサイトから「JavaCryptographyExtension(JCE)Unlimited Strength Jurisdiction Policy Files」をダウンロードし、JRE内のファイルを置き換えた後、上記のコードは変更なしで機能し始めました。

于 2011-11-18T10:53:24.270 に答える
0

私は同じ問題を抱えており、この行を含めて解決します

Security.addProvider(new BouncyCastleProvider());
System.setProperty("https.protocols", "TLSv1");
于 2018-07-12T10:54:44.723 に答える