javaの業務で、ファイルを他サーバーに転送しなくちゃなのですが、できなくて困っています。
転送先のサーバがFTPはFTPSのみ受け付けている、という状態です。
大変困っています。ご回答お待ちしています。よろしくお願い致します。
以下のようなコードを書きましたが、
ハンドシェイクに失敗します。
code
Socket ctrlSocket; PrintWriter ctrlOutput; BufferedReader ctrlInput; byte[] localHostAddress; char[] inbuffer; int i; String sendCommand; try { // FTPサーバーへ接続します ctrlSocket = new Socket(host, port); localHostAddress = ctrlSocket.getLocalAddress().getAddress(); ctrlOutput = new PrintWriter(ctrlSocket.getOutputStream()); ctrlInput = new BufferedReader(new InputStreamReader(ctrlSocket.getInputStream())); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); // 暗号化する場合(FTPS) if (isEncrypt) { sendCommand = "AUTH TLS"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); ★ SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); ctrlSocket = (SSLSocket) factory.createSocket(ctrlSocket, host, port, true); ☆ ((SSLSocket)ctrlSocket).startHandshake(); sendCommand = "PBSZ 0"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); sendCommand = "PROT P"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); } if (isPasv) { sendCommand = "PASV"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); } // ユーザー認証します sendCommand = "USER " + userName; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); sendCommand = "PASS " + password; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); // 指定したディレクトリに移動します sendCommand = "CWD /"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); // バイナリモードに変更します sendCommand = "TYPE I"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); // アップロードします Socket dataSocket = dataConnection("STOR " + uploadPath); OutputStream outstr = dataSocket.getOutputStream(); byte[] buf = readFileToByte(inputPath); outstr.write(buf); outstr.flush(); dataSocket.close(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); // 終了 sendCommand = "QUIT"; ctrlOutput.println(sendCommand); ctrlOutput.flush(); inbuffer = new char[1000]; i = ctrlInput.read(inbuffer); 以下略
【状況】
★factoryの中身
c53d99[SSL_NULL_WITH_NULL_NULL: Socket[addr=ホスト/IPアドレス,port=21,localport=58782]]
☆を実行したあとExceptionが発生します
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
※FTPSではない、暗号化してないFTP通信ではファイル転送に成功しています。
通信相手はショッピングモールの「ポンパレモール」の店舗向けFTPサーバになります。
また、FTPソフトの「winSCP」や「FFFTP」で接続したところ問題なくファイル転送ができました。
WireSharkで上記プログラム実行中FTPのパケットモニタリングしてみたところ、
RES 220 FTP
REQ AUTH TLS
RES 234 AUTH TLS successful
REQ \200e\001\003 …
RES \026\003\001 …
RES \275\036C\207K …
REQ \025\003\001 …
RES 550 TLS handshake failed
という結果になりました。
【質問】
☆の位置でハンドシェイクに失敗していまいます。
FTPSでファイル転送をする場合
・コマンド送信の順番
・SSLSocketの作成手順
に間違いがあるのかもしれませんが、わからなくて困っています。
また、ハンドシェイクに成功したあとは「PBSZ 0」「PROT P」というコマンドを送信し、
FTPSではない、FTPでのファイル転送と同じ手順で、ファイル転送ができるのでしょうか?
具体的なコードを交えて教えていただけると大変助かります。
よろしくお願い致します。m(_ _)m
まだ回答がついていません
会員登録して回答してみよう