この質問は、さまざまなフレーバーで何度か聞かれています。残念ながら、どの答えも私にとって解決策にはなりませんでした。
クライアント側の認証を含めて、httpsプロトコルを使用してPython Webサーバー(以下のコード)に接続しようとしています。テスト用に作成したPythonクライアントを介して接続する場合、問題はありません。早送りします。Androidデバイスから接続しようとしています(再度フォローするコード)。
javax.net.ssl.SSLProtocolException
2つの証明書を発行した自己署名CAがあります。1つはクライアント用、もう1つはサーバー用です。
次を使用して、サーバーの秘密鍵からパスフレーズを削除しました。
openssl rsa -in serverKey.pem -out serverKey.pem
Linuxコマンドラインからopensslを使用してリクエストを発行しました。
クライアントの場合、リクエストを発行し、証明書を作成してから、BouncyCastleプロバイダーでkeytoolを使用して、CAをトラストストアにインポートし、クライアント証明書をキーストアにインポートしました(これらは同じ形式であることに気づきました。異なる名前で参照すると、それらは分離されます)。
関連するサーバーコード:
class ReuseHTTPServer(BaseHTTPServer.HTTPServer):
def __init__(self, address, handler):
BaseHTTPServer.HTTPServer.__init__(self, address, handler)
self.address = address
ssl_socket = ssl.wrap_socket(socket.socket(self.address_family,
self.socket_type),
keyfile = KEY_PATH,
certfile = CERTIFICATE_PATH,
server_side = True,
cert_reqs = ssl.CERT_REQUIRED,
ssl_version = ssl.PROTOCOL_SSLv23,
ca_certs = CA_PATH)
s = self.socket.getsockname()
print "serving:", s[0], "on port:", s[1]
self.socket = ssl_socket
self.server_bind()
self.server_activate()
def server_bind(self):
BaseHTTPServer.HTTPServer.server_bind(self)
Androidクライアントコード:
//add bouncy castle to the list of security providers
Security.insertProviderAt(new BouncyCastleProvider(), 1);
//load the trusted CA
KeyStore trusted = KeyStore.getInstance("BKS");
InputStream in = getResources().openRawResource(R.raw.mobilecastore);
trusted.load(in, "password".toCharArray());
in.close();
TrustManagerFactory trust_factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trust_factory.init(trusted);
//load the client keystore
KeyStore client = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream client_in = getResources().openRawResource(R.raw.client);
client.load(client_in, "password2".toCharArray());
client_in.close();
KeyManagerFactory key_factory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
key_factory.init(client, "password2".toCharArray());
SSLContext ssl_context = SSLContext.getInstance("SSL");
ssl_context.init(key_factory.getKeyManagers(), trust_factory.getTrustManagers(), null);
URL url = new URL("https", IP, 60000, "/cgi-bin/www_sel_jf");
connection = (HttpsURLConnection) url.openConnection();
connection.setSSLSocketFactory(ssl_context.getSocketFactory());
connection.setDoInput(true);
connection.setRequestMethod("GET");
connection.connect();
エラー:
12-31 07:23:37.917: W/System.err(3666): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x16bab18: Failure in SSL library, usually a protocol error
12-31 07:23:37.917: W/System.err(3666): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1234 0x16bf980:0x00000003)
12-31 07:23:37.917: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
12-31 07:23:37.917: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
12-31 07:23:37.917: W/System.err(3666): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
12-31 07:23:37.917: W/System.err(3666): at com.dsndata.sds2mobile.status.activities.ServerJobs$RetrieveJobNames.doInBackground(ServerJobs.java:143)
12-31 07:23:37.917: W/System.err(3666): at com.dsndata.sds2mobile.status.activities.ServerJobs$RetrieveJobNames.doInBackground(ServerJobs.java:1)
12-31 07:23:37.917: W/System.err(3666): at android.os.AsyncTask$2.call(AsyncTask.java:264)
12-31 07:23:37.925: W/System.err(3666): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-31 07:23:37.925: W/System.err(3666): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-31 07:23:37.925: W/System.err(3666): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
12-31 07:23:37.925: W/System.err(3666): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
12-31 07:23:37.925: W/System.err(3666): at java.lang.Thread.run(Thread.java:856)
12-31 07:23:37.925: W/System.err(3666): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x16bab18: Failure in SSL library, usually a protocol error
12-31 07:23:37.925: W/System.err(3666): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1234 0x16bf980:0x00000003)
12-31 07:23:37.925: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
12-31 07:23:37.925: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
12-31 07:23:37.925: W/System.err(3666): ... 16 more
12-31 07:23:37.925: W/System.err(3666): javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x16bab18: Failure in SSL library, usually a protocol error
12-31 07:23:37.925: W/System.err(3666): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1234 0x16bf980:0x00000003)
12-31 07:23:37.925: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:460)
12-31 07:23:37.925: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:441)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
12-31 07:23:37.925: W/System.err(3666): at libcore.net.http.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:164)
12-31 07:23:37.925: W/System.err(3666): at com.dsndata.sds2mobile.status.activities.ServerJobs$RetrieveJobNames.doInBackground(ServerJobs.java:143)
12-31 07:23:37.932: W/System.err(3666): at com.dsndata.sds2mobile.status.activities.ServerJobs$RetrieveJobNames.doInBackground(ServerJobs.java:1)
12-31 07:23:37.932: W/System.err(3666): at android.os.AsyncTask$2.call(AsyncTask.java:264)
12-31 07:23:37.932: W/System.err(3666): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-31 07:23:37.932: W/System.err(3666): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-31 07:23:37.932: W/System.err(3666): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
12-31 07:23:37.932: W/System.err(3666): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
12-31 07:23:37.932: W/System.err(3666): at java.lang.Thread.run(Thread.java:856)
12-31 07:23:37.932: W/System.err(3666): Caused by: javax.net.ssl.SSLProtocolException: SSL handshake terminated: ssl=0x16bab18: Failure in SSL library, usually a protocol error
12-31 07:23:37.932: W/System.err(3666): error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (external/openssl/ssl/s3_pkt.c:1234 0x16bf980:0x00000003)
12-31 07:23:37.932: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
12-31 07:23:37.932: W/System.err(3666): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:410)
12-31 07:23:37.932: W/System.err(3666): ... 16 more
私はjavax.net.sslライブラリを使用しており、apacheライブラリは使用していないことに注意してください。
編集:PythonサーバーはWindowsマシンでホストされています。WindowsポートのSSL用に考慮する必要のある追加の構成はありますか?
編集:はい、WindowsポートでSSLを許可するために実行する必要があることがあります。ポート443(SSLトラフィック用に指定)に切り替えて、進行中(遅い)です。
編集:Wiresharkを使用してリクエストを追跡できるようになりました(この問題について多くのことを学んでいます!)。Wiresharkは405エラーがあると言っています。これはSSLで、証明書の形式が認識されないことを意味します。PythonサーバーはPEM証明書(Pythonドキュメントで許可されている唯一の形式)を使用しており、Androidデバイスのキーストアにインポートされる証明書はDERです(私の知る限り、BKSで受け入れられる唯一の形式)。
どんな助けでも大歓迎です。