- - PR -
URL openConnection()で止まってしまう。
«前のページへ
1|2|3
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-10-15 15:17
いっきゅうさん、ありがとうございます。
それから、おばけさんも本当にありがとうございます。いちおう、アドレスはIPで 設定しているので、名前解決は問題ないかと思っています。
Javaのバージョンは、"1.4.2-p6"でした。パッチやバグについては調べています。
はい。さっそくご提案に従い、いくつかの方法を試してみました。 HTTPs 1.Tomcat + URLConnection = × 2.Tomcat + SSLSocket = × 3.スタンドアローン + URLConnection = × HTTP 1.Tomcat + URLConnection = ○ 2.Tomcat + SSLSocket = ○ 3.スタンドアローン + URLConnection = ○ ということで、どうやら"HTTPs"だけ接続できないみたいです。 そうなると、サーバー自体の設定が何か必要なようなのですが、"HTTPs"接続を できるようにするためには、サーバーのどこをどのように設定する必要があるのでしょうか。ハード的なことについてはまだ勉強不足なものですから。 私自身はサーバーの管理まではしていないのですが、こちらのプログラムに問題がない ことを証明した上で、サーバーのどこを設定する必要があるのか指摘しないと納得して もらえそうにないのです。 だいぶ原因が絞られてきましたので、あともう一息、どなたか助けていただけませんで しょうか。 よろしくお願いします。 | ||||||||
|
投稿日時: 2004-10-15 18:27
Httpsの問題なら認証する際の問題みたいに見えるのですが
信頼できない証明書や証明書とサーバの名前解決で Exceptionが発生しているわけではないですよね? もし、上記処理に問題(バグ?)あるとするなら 下記のようなコードをコネクションを張る前に呼んで 無視するようにしてみてはどうでしょうか?
| ||||||||
|
投稿日時: 2004-10-15 19:15
unibon です。こんにちわ。
詳しいことは知らないのですが、もし可能ならば接続先を別の Web サーバーにしてみてはどうでしょうか。たとえば Yahoo! とかのサイトに(Yahoo! はあくまでも一例でしかありませんが)。もし現在の問題の原因が証明書まわりにあるのならば、他の著名なサイトならば接続できるはずです。 | ||||||||
|
投稿日時: 2004-10-15 19:20
いっきゅうさん、ありがとうございます。
実は、サーバー認証を無視するサンプルを見つけたので、それを利用しているのですが、一休さんの教えてくださったのと同じ方法みたいです。 でも、問題はそこに行く前のところで止まっているみたいなのです。 実際の接続処理のメソッドの中身は以下のようになっています。 このメソッドで作成したコネクションでデータの入出力ストリームを作成しています。 try { URL u = new URL("https://IP Address/xxx/xxx?xxx=xxx"); System.out.println("Try openConnection"); ↑ ここまで出力ログに記録されている URLConnection hCon = u.openConnection(); ↑問題の箇所 ここでURLConnectionのインスタンスを取得するときに止まっている エラーも何もスローされない しばらく放置してもタイムアウトにもならない System.out.println("URL openConnection:" + url); ↑ これは出力ログに記録されない // 入出力設定 hCon.setDoOutput(true); //****************************************************************** SSLSocketFactory sslsf = null; KeyManager[] km = null; //サーバーの証明書を強制的に認証させる TrustManager[] tm = { new RelaxedX509TrustManager() }; //ソケットプロトコルを実装するSSLContextを作成 SSLContext sslContext = SSLContext.getInstance( "SSL" ); //SSLContextを初期化 sslContext.init( km, tm, new SecureRandom() ); //SSLContextのSocketFactoryを取得 sslsf = sslContext.getSocketFactory(); //URLConnectionにSocketFactoryをセット ( ( HttpsURLConnection )hCon ).setSSLSocketFactory( sslsf ); //****************************************************************** //ホスト名を無視させる HostnameVerifier hv = new HostNameVeri(); ( ( HttpsURLConnection )hCon ).setHostnameVerifier(hv ); System.out.println("SSL connected"); } catch(Exception e) { System.out.println(e); throw new CreditCardException(); } | ||||||||
|
投稿日時: 2004-10-16 18:25
トラジャさんの見つけた方法についても私も参考したことがあります。
その方法ですとJSSE1.0.3での方法でJ2sdk1.4以降だと コンパイル時警告がでませんか? 私の方法は1.4で対応したものです。 Windowsですとどちらの方法でも問題なかったですが FreeBSDでもそうなのかは分からないですが、、 後、URLConnection hCon = u.openConnection(); を 呼ぶ前にサーバー認証を無視するコードを呼ばないと意味が無いと 思うのですが、 確認していませんが別環境で動いていたんでしょうか? //// 修正追加 ここから setDefault***の場合は初期化する前で setHostnameVerifier() とsetSSLSocketFactory()の場合 初期化したHttpsURLConnectionに直接設定するので 初期化後でも通信前までならいいみたいですね。 ちょっと間違えていたので補足します。 //// 修正追加 ここまで [ メッセージ編集済み 編集者: いっきゅう 編集日時 2004-10-16 18:55 ] | ||||||||
|
投稿日時: 2004-10-17 00:26
参考にさせていただいたのは、以下のサイトでした。 http://shinjuku.cool.ne.jp/kiuma/java/java/https.html このページの最後に「com.sun.net.sslとなっているパッケージはjavax.net.sslに 変わっています。」と書いてあったので、importするパッケージを"javax.net.ssl" にしたらコンパイルエラーは出ませんでした。 それから、"SSLSocket"を使って試した際のコードは以下のとおりです。 SSLSocketFactory sslsf = null; KeyManager[] km = null; //証明書の信頼性を決定するためのインターフェース TrustManager[] tm = { new RelaxedX509TrustManager() }; //ソケットプロトコルを実装するSSLContextを作成 SSLContext sslContext = SSLContext.getInstance( "SSL" ); //SSLContextを初期化 System.out.println("Start SSLContext.init"); ↑ここまでログに出力されている sslContext.init( km, tm, new SecureRandom() ); ↑ここで止まってしまっているみたい System.out.println("End SSLContext.init"); ↑ここはログに出力されない //SSLContextのSocketFactoryを取得 sslsf = sslContext.getSocketFactory(); Socket socket = sslsf.createSocket("IP Address",443); 上記のように、Socketを使った場合、sslContext.init()で止まってしまいます。 URL.openConnection()とSSLContext.init()は同じ処理をしているのでしょうか? | ||||||||
|
投稿日時: 2004-10-19 09:01
少し進展がありました。
SSLSocketによる接続をテストしていましたところ、なぜか1回目の接続はうまく いかないのですが、2回目からは sslContext.init( km, tm, new SecureRandom() ); で止まることなく、Socketを作るところまでいくようになりました。 ただ、そのSocketを使って実際に送信処理をした直後に、以下のExceptionが発生 します。これの意味がいろいろ探してみたのですが、いまいち分かりません。 javax.net.ssl.SSLProtocolException: java.io.IOException: java.io.IOException: Host portion is not a valid DNS name, IPv4 address, or IPv6 address at com.sun.net.ssl.internal.ssl.HandshakeMessage$CertificateMsg.<init>(DashoA6275) at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA6275) at com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA6275) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA6275) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA6275) at com.sun.net.ssl.internal.ssl.AppOutputStream.write(DashoA6275) at sun.nio.cs.StreamEncoder$CharsetSE.writeBytes(StreamEncoder.java:336) at sun.nio.cs.StreamEncoder$CharsetSE.implFlushBuffer(StreamEncoder.java:404) at sun.nio.cs.StreamEncoder$CharsetSE.implFlush(StreamEncoder.java:408) at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:152) at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:213) at jp.genux.ireserve.entry.CreditExamination.sendPostData(CreditExamination.java:165) at jp.genux.ireserve.struts.entry.RegReserveAction.execute(RegReserveAction.java:82) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:525) at javax.servlet.http.HttpServlet.service(HttpServlet.java:763) at javax.servlet.http.HttpServlet.service(HttpServlet.java:856) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:284) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204) at filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:169) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:233) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:204) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:257) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:245) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:199) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:184) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:164) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:149) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:156) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:151) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:567) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:972) at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:206) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:833) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:732) at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:619) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:688) at java.lang.Thread.run(Thread.java:534) Caused by: java.security.cert.CertificateParsingException: java.io.IOException: java.io.IOException: Host portion is not a valid DNS name, IPv4 address, or IPv6 address at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:157) at sun.security.x509.X509CertImpl.parse(X509CertImpl.java:1679) at sun.security.x509.X509CertImpl.<init>(X509CertImpl.java:173) at sun.security.provider.X509Factory.engineGenerateCertificate(X509Factory.java:90) at java.security.cert.CertificateFactory.generateCertificate(CertificateFactory.java:389) ... 47 more Caused by: java.io.IOException: java.io.IOException: Host portion is not a valid DNS name, IPv4 address, or IPv6 address at sun.security.x509.CertificateExtensions.parseExtension(CertificateExtensions.java:111) at sun.security.x509.CertificateExtensions.init(CertificateExtensions.java:78) at sun.security.x509.CertificateExtensions.<init>(CertificateExtensions.java:57) at sun.security.x509.X509CertInfo.parse(X509CertInfo.java:731) at sun.security.x509.X509CertInfo.<init>(X509CertInfo.java:155) ... 51 more Caused by: java.io.IOException: Host portion is not a valid DNS name, IPv4 address, or IPv6 address at sun.security.x509.URIName.parseName(URIName.java:205) at sun.security.x509.URIName.<init>(URIName.java:85) at sun.security.x509.GeneralName.<init>(GeneralName.java:94) at sun.security.x509.GeneralNames.<init>(GeneralNames.java:51) at sun.security.x509.DistributionPoint.<init>(DistributionPoint.java:193) at sun.security.x509.CRLDistributionPointsExtension.<init>(CRLDistributionPointsExtension.java:126) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:274) at sun.security.x509.CertificateExtensions.parseExtension(CertificateExtensions.java:105) ... 55 more | ||||||||
|
投稿日時: 2004-10-21 19:39
みなさん、たいへんお世話になりました。
すべて解決いたしましたので、他の方々の参考にでもなればと以下に、解決手順 をお知らせいたします。 ■HTTPs通信時、URL.openConnectionで止まるエラー。 ◎Java起動オプションまたはCATALINA_OPTに "-Djava.security.egd=file:/dev/urandom"を設定する。 参考文献URL http://sirius.itfrontier.co.jp/kb/cf_article.cfm?TYPE=en&ID=19127 これは、Java Virtual Machine (JVM) の SecureRandom() コールのシーディング中に /dev/random デバイスにより、 I/O がブロックされてしまうことが原因です。ColdFusion MX がスタートアップ/再起動後に呼び出される最初の cfapplication タグの cftoken 値を作成する時、JVM は java.Security.SecureRandom を開始します。SecureRandom は暗号的に強力な乱数ジェネレータであり、シーディング ソースとして特別な /dev/random デバイスを使用します。ランダム バイトのリクエストされた数を返すのに十分なインターフェースのために収集されるエントロピーがあるまで、/dev/random デバイスは I/O をブロックします。 SecureRandom は 1.3.x SDK のオプション パッケージと 1.4.x SDK で統合される今、J2EE Java Authentication と Authorization Service (JAAS) の一部です。JVM は 2 つのエントロピー デバイス (EGD) を許可します: /dev/random と /dev/urandom。通常、ColdFusion MX はデバイスを必要としませんが、あれば JVM はそれを使用しようとします。java.security マスター プロパティ ファイルはデフォルトで /dev/random になります。 対応方法: この問題を避けるために、JVM が /dev/urandom デバイスを使用するようにします。そのために、以下のオプションの 1 つを使用します: cf_root/runtime/jre/lib/security/java.security ファイルを編集します。このエントリを変更してください: securerandom.source=file:/dev/random 変更後 securerandom.source=file:/dev/urandom - または - ColdFusion Administrator を介して、あるいは cf_root/runtime/bin/jvm.config ファイルの java.args エントリの終わりに JVM 引数として -Djava.security.egd=file:/dev/urandom を追加します。 ■HTTPs接続で、SSLハンドシェーク時に"javax.net.ssl.SSLProtocolException: java.io.IOException: java.io.IOException: Host portion is not a valid DNS name, IPv4 address, or IPv6 address "エラーが発生する。 どうやら、FreeBSDのNative jdkのAPIは、linux版と違うみたいです。それで少々 不安はありましたが、いくつかのlinux版のAPIライブラリをFreeBSD Native jdk のライブラリと入れ替えてみました。 そうしたら、上記のエラーが発生しなくなりました。 1.linux-sun-jdk(linuxエミュレータ版)をインストールする 2.インストールした"linux-sun-jdk"の以下のJarファイルをFreeBSD Native jdkのJarファイルにコピーする。 linux-sun-jdk/lib/tools.jar linux-sun-jdk/jre/lib/jsse.jar linux-sun-jdk/jre/lib/rt.jar(このJarをコピーするだけでもエラーが消えるかもしれない) ■参考 1.HTTPs通信時のやりとりをdebugで表示させる方法 参考文献URL http://www.techfirm.co.jp/manual/jdk14ja/guide/security/jsse/JSSERefGuide.html 例 デバッグメッセージをすべて表示する場合は、次のように入力します。 java -Djavax.net.debug=all MyApp ハンドシェークメッセージを 16 進ダンプで表示するには、次のように入力します。コロンは省略できます。 java -Djavax.net.debug=ssl:handshake:data MyApp ハンドシェークメッセージを 16 進ダンプで表示し、さらにトラストマネージャのトレース状態を表示するには、次のように入力します。カンマは省略できます。 java -Djavax.net.debug=SSL,handshake,data,trustmanager MyApp 現在のオプションは次のとおりです。 all turn on all debugging ssl turn on ssl debugging The following can be used with ssl: record enable per-record tracing handshake print each handshake message keygen print key generation data session print session activity defaultctx print default SSL initialization sslctx print SSLContext tracing sessioncache print session cache tracing keymanager print key manager tracing trustmanager print trust manager tracing handshake debugging can be widened with: data hex dump of each handshake message verbose verbose handshake message printing record debugging can be widened with: plaintext hex dump of record plaintext 2.HTTPs通信時にサーバー認証を無視して強制的に認証させる方法 参考文献URL http://shinjuku.cool.ne.jp/kiuma/java/java/https.html [ メッセージ編集済み 編集者: トラジャ 編集日時 2004-10-21 19:42 ] |
«前のページへ
1|2|3