NIO 使用 TLS

近日有项目需要将现有系统得TCP连接升级到加密的TLS连接,但是遇到得问题是,原来用得是SocketChannel等NIO类作为连接层。
但是众所周之,传统IO做SSL的话只要换Socket为SSLSocket就可以了,兼容原来的系统做
得很好
但是如果用了NIO,是没有一个叫做SSLSocketChannel的类的,如果想不大规模修改源代码的话,又不使用框架,就只可以使用jdk的SSLEngine类了。当然,工作量会非常大。这是一个很实际的需求,所以直接网上搜索资料去:
苦苦搜索之后在网上艰难地发现了一个实现了SSl的SocketChannel类,是属于某个开源框架的一部分,我从中抽离出来:
原链接如下,版权归原作者所有:
http://www.koders.com/java/fid3BBC1D50296CAB0AB23ED725C45FFBDC4A0EF698.aspx?s=cdef%3aftp+client



SSLSocketChannel.java:

/**
* Copyright (C) 2003 Alexander Kout
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package de.kout.wlFxp;

import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import javax.net.ssl.*;
import java.io.*;
import de.kout.wlFxp.Utilities;

/**
*  a SocketChannel with TLS/SSL encryption
*
*@author     Alexander Kout
*@created    25. Mai 2005
*/

public class SSLSocketChannel {

int SSL;
ByteBuffer clientIn, clientOut, cTOs, sTOc, wbuf;
SocketChannel sc = null;
SSLEngineResult res;
SSLEngine sslEngine;

public SSLSocketChannel() throws IOException {
sc = SocketChannel.open();
}

public SSLSocketChannel(SocketChannel sc) {
this.sc = sc;
}

public int tryTLS(int pSSL) throws IOException {
SSL = pSSL;
if (SSL == 0)
return 0;

SSLContext sslContext=null;
try {
// create SSLContext
sslContext = SSLContext.getInstance("TLS");

sslContext.init(null,
new TrustManager[] {new EasyX509TrustManager(null)},
null);
// create Engine
sslEngine = sslContext.createSSLEngine();
// begin
sslEngine.setUseClientMode(true);

sslEngine.setEnableSessionCreation(true);
SSLSession session = sslEngine.getSession();
createBuffers(session);
// wrap
clientOut.clear();
sc.write(wrap(clientOut));
while (res.getHandshakeStatus() !=
SSLEngineResult.HandshakeStatus.FINISHED) {
if (res.getHandshakeStatus() ==
SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
// unwrap
sTOc.clear();
while (sc.read(sTOc) < 1)
Thread.sleep(20);
sTOc.flip();
unwrap(sTOc);
if (res.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.FINISHED) {
clientOut.clear();
sc.write(wrap(clientOut));
}
} else if (res.getHandshakeStatus() ==
SSLEngineResult.HandshakeStatus.NEED_WRAP) {
// wrap
clientOut.clear();
sc.write(wrap(clientOut));
} else {Thread.sleep(1000);}
}
clientIn.clear();
clientIn.flip();
SSL = 4;
Utilities.print("SSL established\n");
} catch (Exception e) {
e.printStackTrace(System.out);
SSL = 0;
}
return SSL;
}

private synchronized ByteBuffer wrap(ByteBuffer b) throws SSLException {
cTOs.clear();
res = sslEngine.wrap(b, cTOs);
cTOs.flip();
Utilities.print("wrap:\n"+res.toString()+"\n");
return cTOs;
}

private synchronized ByteBuffer unwrap(ByteBuffer b) throws SSLException {
clientIn.clear();
int pos;
Utilities.print("b.remaining "+b.remaining()+"\n");
while (b.hasRemaining()) {
Utilities.print("b.remaining "+b.remaining()+"\n");
res = sslEngine.unwrap(b, clientIn);
Utilities.print("unwrap:\n"+res.toString()+"\n");
if (res.getHandshakeStatus() ==
SSLEngineResult.HandshakeStatus.NEED_TASK) {
// Task
Runnable task;
while ((task=sslEngine.getDelegatedTask()) != null)
{
Utilities.print("task...\n");
task.run();
}
Utilities.print("task:\n"+res.toString()+"\n");
} else if (res.getHandshakeStatus() ==
SSLEngineResult.HandshakeStatus.FINISHED) {
return clientIn;
} else if (res.getStatus() ==
SSLEngineResult.Status.BUFFER_UNDERFLOW) {
Utilities.print("underflow\n");
Utilities.print("b.remaining "+b.remaining()+"\n");
return clientIn;
}
}
return clientIn;
}

private void createBuffers(SSLSession session) {

int appBufferMax = session.getApplicationBufferSize();
int netBufferMax = session.getPacketBufferSize();

clientIn = ByteBuffer.allocate(65536);
clientOut = ByteBuffer.allocate(appBufferMax);
wbuf = ByteBuffer.allocate(65536);

cTOs = ByteBuffer.allocate(netBufferMax);
sTOc = ByteBuffer.allocate(netBufferMax);

}

public int write(ByteBuffer src) throws IOException {
if (SSL == 4) {
return sc.write(wrap(src));
}
return sc.write(src);
}

public int read(ByteBuffer dst) throws IOException {
Utilities.print("read\n");
int amount = 0, limit;
if (SSL == 4) {
// test if there was a buffer overflow in dst
if (clientIn.hasRemaining()) {
limit = Math.min(clientIn.remaining(), dst.remaining());
for (int i = 0; i < limit; i++) {
dst.put(clientIn.get());
amount++;
}
return amount;
}
// test if some bytes left from last read (e.g. BUFFER_UNDERFLOW)
if (sTOc.hasRemaining()) {
unwrap(sTOc);
clientIn.flip();
limit = Math.min(clientIn.limit(), dst.remaining());
for (int i = 0; i < limit; i++) {
dst.put(clientIn.get());
amount++;
}
if (res.getStatus() != SSLEngineResult.Status.BUFFER_UNDERFLOW) {
sTOc.clear();
sTOc.flip();
return amount;
}
}
if (!sTOc.hasRemaining())
sTOc.clear();
else
sTOc.compact();

if (sc.read(sTOc) == -1) {
Utilities.print("close from SSLSocketChannel"+"\n");
sTOc.clear();
sTOc.flip();
return -1;
}
sTOc.flip();
unwrap(sTOc);
// write in dst
clientIn.flip();
limit = Math.min(clientIn.limit(), dst.remaining());
for (int i = 0; i < limit; i++) {
dst.put(clientIn.get());
amount++;
}
Utilities.print("dst.remaining "+dst.remaining()+"\n");
return amount;
}
return sc.read(dst);
}

public boolean isConnected() {
return sc.isConnected();
}

public void close() throws IOException {
if (SSL == 4) {
sslEngine.closeOutbound();
clientOut.clear();
sc.write(wrap(clientOut));
sc.close();
} else
sc.close();
}

public SelectableChannel configureBlocking(boolean b) throws IOException {
return sc.configureBlocking(b);
}

public boolean connect(SocketAddress remote) throws IOException {
return sc.connect(remote);
}

public boolean finishConnect() throws IOException {
return sc.finishConnect();
}

public Socket socket() {
return sc.socket();
}

public boolean isInboundDone() {
return sslEngine.isInboundDone();
}
}


Utilities .java:


/**
* Copyright (C) 2003 Alexander Kout
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package de.kout.wlFxp;

import java.text.*;
import java.io.*;
import java.util.*;
import java.util.regex.*;

//import de.kout.wlFxp.ftp.FtpFile;

/**
*  Utility class
*
*@author     Alexander Kout
*@created    30. M�rz 2002
*/
public class Utilities {

/**
*  verbose output
*/
public static boolean debug = false;
/**
*  the FileWriter for the debug mode
*/
public static FileWriter logFile = null;

private static final String[] monthsWS = {" Jan ", " Feb ", " Mar ", " Apr ",
" May ", " Jun ", " Jul ", " Aug ", " Sep ",
" Oct ", " Nov ", " Dec "};
private static final String[] months = {"Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"};


/**
*  transforms a long into a String like 4KiB
*
*@param  size  Description of Parameter
*@return       Description of the Returned Value
*/
public static String humanReadable(double size) {
DecimalFormat df = new DecimalFormat("###0.00");
double f1;
double f2;
double f3;
if ((f1 = size / 1024.0) > 1.0) {
if ((f2 = f1 / 1024.0) > 1.0) {
if ((f3 = f2 / 1024) > 1.0) {
return df.format(f3) + "GiB";
}
return df.format(f2) + "MiB";
}
return df.format(f1) + "KiB";
}
return df.format(size) + "B";
}


/**
*  Description of the Method
*
*@param  size  Description of Parameter
*@return       Description of the Returned Value
*/
public static String humanReadable(long size) {
return humanReadable(size * 1.0);
}

public static String humanReadableTime(double time) {
DecimalFormat df = new DecimalFormat("###0");
double min, hour, day, sec;
sec = time *1.0;
StringBuffer buf = new StringBuffer(50);
// minutes
if ((min = sec /60.0) >= 1.0) {
// hours
if ((hour = min /60.0) >= 1.0) {
// days
if ((day = hour/24.0) >= 1.0) {
buf.append(df.format(day)).
append("d ").
append(df.format(hour-Math.floor(day)*24.0)).
append("h ").
append(df.format(min-Math.floor(hour)*60.0)).
append("min ").
append(df.format(sec-Math.floor(min)*60.0)).
append("s");
return buf.toString();
}
buf.append(df.format(hour)).
append("h ").
append(df.format(min-Math.floor(hour)*60.0)).
append("min ").
append(df.format(sec-Math.floor(min)*60.0)).
append("s");
return buf.toString();
}
buf.append(df.format(min)).
append("min ").
append(df.format(sec-Math.floor(min)*60.0)).
append("s");
return buf.toString();
}
buf.append(df.format(sec)).append("s");
return buf.toString();
}

public static String humanReadableTime2(double time) {
DecimalFormat df = new DecimalFormat("00");
double min, hour, day, sec;
sec = time *1.0;
StringBuffer buf = new StringBuffer(50);
// minutes
if ((min = sec /60.0) >= 1.0) {
// hours
if ((hour = min /60.0) >= 1.0) {
// days
if ((day = hour/24.0) >= 1.0) {
buf.append(df.format(day)).
append("d:").
append(df.format(hour-Math.floor(day)*24.0)).
append(":").
append(df.format(min-Math.floor(hour)*60.0)).
append(":").
append(df.format(sec-Math.floor(min)*60.0));
return buf.toString();
}
buf.append(df.format(hour)).
append(":").
append(df.format(min-Math.floor(hour)*60.0)).
append(":").
append(df.format(sec-Math.floor(min)*60.0));
return buf.toString();
}
buf.append(df.format(min)).
append(":").
append(df.format(sec-Math.floor(min)*60.0));
return buf.toString();
}
buf.append(new DecimalFormat("#0").format(sec));
return buf.toString();
}

/**
*  Heapsort "with bottom-up linear search" algorithm
*
*@param  list  must be a list of Strings
*/
public static void sortList(String list[]) {
// Heap creation
int n = list.length;
for (int i = n / 2; i > 0; i--) {
reheap(list, i, n);
}
for (int m = n; m > 0; m--) {
String t = list[0];
list[0] = list[m - 1];
list[m - 1] = t;
reheap(list, 1, m - 1);
}
}


/**
*  reheap method for heapsort
*
*@param  array  String array to be sorted
*@param  root   position of root
*@param  end    position of end
*/
private static void reheap(String[] array, int root, int end) {
int[] stack = new int[new Double(Math.log(array.length) / Math.log(2)).intValue() + 10];
int s = 0;
int pos = root;
stack[s++] = pos;
while (2 * pos <= end) {
if (2 * pos + 1 > end) {
stack[s++] = 2 * pos;
break;
}
if (array[2 * pos - 1].compareToIgnoreCase(array[2 * pos]) > 0) {
stack[s++] = 2 * pos;
} else {
stack[s++] = 2 * pos + 1;
}
pos = stack[s - 1];
}
pos = root;
for (int i = s - 1; i >= 0; i--) {
if (array[stack[i] - 1].compareToIgnoreCase(array[root - 1]) > -1) {
pos = stack[i];
s = i + 1;
break;
}
}

String temp = array[root - 1];
for (int i = 1; i < s; i++) {
array[stack[i] / 2 - 1] = array[stack[i] - 1];
}
array[pos - 1] = temp;
}


/**
*  Heapsort "with linear bottom-up search" algorithm
*
*@param  list    FtpFile array which is going to be sorted
*@param  sortBy  Description of the Parameter
*/
// public static void sortFiles(Vector list, String sortBy, boolean prio, Vector prioList) {
// // Heap creation
// int n = list.size();
// for (int i = n / 2; i > 0; i--) {
// reheap(list, i, n, sortBy, prio, prioList);
// }
// for (int m = n; m > 0; m--) {
// FtpFile t = (FtpFile) list.elementAt(0);
// list.setElementAt(list.elementAt(m - 1), 0);
// list.setElementAt(t, m-1);
// reheap(list, 1, m - 1, sortBy, prio, prioList);
// }
// }


/**
*  reheap method for heapsort
*
*@param  array   array to be sorted
*@param  root    position of root
*@param  end     position of end
*@param  sortBy  Description of the Parameter
*/
// private static void reheap(Vector array, int root, int end, String sortBy, boolean prio, Vector prioList) {
// int[] stack = new int[new Double(Math.log(array.size()) / Math.log(2)).intValue() + 10];
// int s = 0;
// int pos = root;
// stack[s++] = pos;
// while (2 * pos <= end) {
// if (2 * pos + 1 > end) {
// stack[s++] = 2 * pos;
// break;
// }
// if (compareFiles(array.elementAt(2 * pos - 1), array.elementAt(2 * pos), sortBy, prio, prioList) > 0) {
// stack[s++] = 2 * pos;
// } else {
// stack[s++] = 2 * pos + 1;
// }
// pos = stack[s - 1];
// }
// pos = root;
// for (int i = s - 1; i >= 0; i--) {
// if (compareFiles(array.elementAt(stack[i] - 1), array.elementAt(root - 1), sortBy, prio, prioList) > -1) {
// pos = stack[i];
// s = i + 1;
// break;
// }
// }
//
// Object temp = array.elementAt(root - 1);
// for (int i = 1; i < s; i++) {
// array.setElementAt(array.elementAt(stack[i] - 1), stack[i] / 2 - 1);
// }
// array.setElementAt(temp, pos - 1);
// }


/**
*  compare method for sorting
*
*@param  f1      first file
*@param  f2      second file
*@param  sortBy  Description of the Parameter
*@return         result of compareToIgnoreCase
*/
// private static int compareFiles(Object o1, Object o2, String sortBy,boolean prio, Vector prioList) {
// int ret;
// FtpFile f1 = (FtpFile) o1;
// FtpFile f2 = (FtpFile) o2;
// if (prio) {
// int m1 = matches(prioList, f1.getName()), m2 = matches(prioList, f2.getName());
// if (m1 != -1 || m2 != -1) {
// if (m1 > m2) {
// return -1;
// }
// else if (m2 > m1) {
// return 1;
// }
// }
// }
// if (f1.isDirectory() && !f2.isDirectory()) {
// return -1;
// }
// if (!f1.isDirectory() && f2.isDirectory()) {
// return 1;
// }
// if (sortBy.equals("Name")) {
// return f1.getName().compareToIgnoreCase(f2.getName());
// } else if (sortBy.equals("IName")) {
// return -f1.getName().compareToIgnoreCase(f2.getName());
// } else if (sortBy.equals("Size")) {
// ret = (int) (f1.getSize() - f2.getSize());
// } else if (sortBy.equals("ISize")) {
// ret = (int) (f2.getSize() - f1.getSize());
// } else if (sortBy.equals("Date")) {
// if (f1.getDate().indexOf("/") == 2 && f2.getDate().indexOf("/") > 2) {
// return 1;
// } else if (f1.getDate().indexOf("/") > 2 && f2.getDate().indexOf("/") == 2) {
// return -1;
// }
// ret = f1.getDate().compareToIgnoreCase(f2.getDate());
// } else if (sortBy.equals("IDate")) {
// if (f1.getDate().indexOf("/") == 2 && f2.getDate().indexOf("/") > 2) {
// return -1;
// } else if (f1.getDate().indexOf("/") > 2 && f2.getDate().indexOf("/") == 2) {
// return 1;
// }
// ret = -f1.getDate().compareToIgnoreCase(f2.getDate());
// } else {
// return f1.getName().compareToIgnoreCase(f2.getName());
// }
// if (ret == 0) {
// ret = f1.getName().compareToIgnoreCase(f2.getName());
// }
// return ret;
// }

private static int matches(Vector v, String s) {
for (int i = 0; i < v.size(); i++) {
try {
if (Pattern.matches(((String) v.elementAt(i)).toLowerCase(), s.toLowerCase())) {
return (v.size()-i);
}
} catch (Exception e) {}
}
return -1;
}


/**
*  print method which writes to a file if debug is true
*
*@param  s  String to be printed
*/
public static void print(String s) {
if (debug) {
String settings = System.getProperty("user.home", ".") + File.separator + ".wlFxp";
System.out.print(s);
try {
if (logFile == null) {
if (!new File(settings).isDirectory()) {
new File(settings).mkdir();
}
logFile = new FileWriter(settings + File.separator + "log.txt", true);
}
logFile.write(s);
logFile.flush();
} catch (IOException e) {
System.err.println(e.toString());
}
}
}


/**
*  saves the stack trace of an exception
*
*@param  e  Description of the Parameter
*/
public static void saveStackTrace(Exception e) {
String settings = System.getProperty("user.home", ".") + File.separator + ".wlFxp" + File.separator + "logs";
try {
if (!new File(settings).isDirectory()) {
new File(settings).mkdirs();
}
FileWriter exceptionFile = new FileWriter(settings + File.separator + "exception: " + System.currentTimeMillis() / 1000);
StackTraceElement[] t = e.getStackTrace();
exceptionFile.write(e.toString() + "\n");
for (int i = 0; i < t.length; i++) {
exceptionFile.write(t[i].toString() + "\n");
}
exceptionFile.flush();
} catch (IOException ex) {
System.err.println(ex.toString());
}
}


/**
*  parses the output of a list command into an array of FtpFiles
*
*@param  output  output of a LIST
*@param  ftpDir  directory of the LIST
*@return         array of FtpFiles
*/
// public static Vector parseList(String output, String ftpDir) {
// String[] completeList = split(output, "\r\n");
// // FtpFile[] tmpfiles = new FtpFile[completeList.length];
// Vector files = new Vector(completeList.length, 100);
// FtpFile tmp;
// int k = 0;
// int index;
// for (int i = 0; i < completeList.length; i++) {
//// if (!Pattern.matches("([A-Za-z][A-Za-z][A-Za-z]) .[0-9] [0-9 ][0-9]", completeList[i]))
// // ...
// index = -1;
// int j = 0;
// int tindex = 0;
// while (j < monthsWS.length) {
// tindex = completeList[i].indexOf(monthsWS[j]);
// if (tindex != -1 && (index == -1 || tindex < index)) {
// index = tindex;
// }
// j++;
// }
// if (index == -1) {
// continue;
// }
//// System.out.println(index);
// tmp = new FtpFile("");
// files.addElement(tmp);
// if (completeList[i].indexOf(" -> ") != -1) {
// completeList[i] = completeList[i].substring(0, completeList[i].indexOf(" -> "));
// }
// tmp.setName(completeList[i].substring(
// completeList[i].substring(index + 10,
// completeList[i].length()).indexOf(" ")
// + 11 + index,
// completeList[i].length()));
// // if the server outputs the "." or ".." with list
// if (tmp.getName().equals(".")
// || tmp.getName().equals("..")) {
// files.removeElementAt(files.size()-1);
// continue;
// }
// tmp.setSize(Long.parseLong(completeList[i].substring(completeList[i].substring(0, index).lastIndexOf(" ") + 1, index)));
// tmp.setMode(completeList[i].substring(0, 10));
// tmp.setFtpMode(true);
// tmp.setDate(parseDate(completeList[i].substring(index, index + 13)));
// if (ftpDir.equals("/"))
// tmp.setAbsolutePath(ftpDir + tmp.getName());
// else
// tmp.setAbsolutePath(ftpDir +"/"+tmp.getName());
// k++;
// }
// return files;
// }


/**
*  parses the dates of the LIST output into good looking Strings
*
*@param  input  Description of the Parameter
*@return        Description of the Return Value
*/
private static String parseDate(String input) {
String[] tdate = split(input, " ");
String[] date = new String[3];
int k = 0;
for (int i = 0; i < tdate.length; i++) {
if (tdate[i].equals("")) {
continue;
}
date[k++] = tdate[i];
}
StringBuffer ret = new StringBuffer(30);
for (int j = 0; j < 12; j++) {
if (date[0].equals(months[j])) {
if (j < 9) {
// ret = "0" + (j + 1);
ret.append("0").append(j + 1);
} else {
// ret = (j + 1) + "";
ret.append(j + 1);
}
break;
}
}
int t = Integer.parseInt(date[1]);
if (t < 10) {
// ret += "/0" + t;
ret.append("/0").append(t);
} else {
// ret += "/" + t;
ret.append("/").append(t);
}
if (date[2].indexOf(":") != -1) {
// ret += " " + date[2];
ret.append(" ").append(date[2]);
} else {
// ret = date[2] + "/" + ret;
String tmp = ret.toString();
ret.delete(0, ret.length());
ret.append(date[2]).append("/").append(tmp);
}
return ret.toString();
}


/**
*  parses the dates of local files into good looking Strings
*
*@param  date  Description of the Parameter
*@return       Description of the Return Value
*/
public static String parseDate(long date) {
GregorianCalendar cal = new GregorianCalendar();
int curYear;
cal.setTime(new Date());
curYear = cal.get(Calendar.YEAR);
cal.setTime(new Date(date));
StringBuffer ret = new StringBuffer(30);
StringBuffer month = new StringBuffer(2);
month.append(cal.get(Calendar.MONTH) + 1);
if (month.length() == 1) {
month.insert(0, "0");
}
StringBuffer day = new StringBuffer(2);
day.append(cal.get(Calendar.DATE));
if (day.length() == 1) {
day.insert(0, "0");
}
StringBuffer hour = new StringBuffer(2);
hour.append(cal.get(Calendar.HOUR_OF_DAY));
if (hour.length() == 1) {
hour.insert(0, "0");
}
StringBuffer minute = new StringBuffer(2);
minute.append(cal.get(Calendar.MINUTE));
if (minute.length() == 1) {
minute.insert(0, "0");
}
if (curYear > cal.get(Calendar.YEAR)) {
// ret = "" + cal.get(Calendar.YEAR);
ret.append(cal.get(Calendar.YEAR)).append("/").append(month).append("/").append(day);
} else {
// ret = "" + month;
ret.append(month).append("/").append(day).append(" ").append(hour).append(":").append(minute);
}
return ret.toString();
}


/**
*  rewrite of the split method from java.lang.String because it
*  makes problems with gcj
*
*@param  s    Description of the Parameter
*@param  key  Description of the Parameter
*@return      Description of the Return Value
*/
public static String[] split(String s, String key) {
Vector v = new Vector(100, 50);
while (s.length() > 0 && s.indexOf(key) != -1) {
v.addElement(s.substring(0, s.indexOf(key)));
s = s.substring(s.indexOf(key) + key.length(), s.length());
}
v.addElement(s);
while (v.size() > 0 && ((String) v.elementAt(v.size() - 1)).equals("")) {
v.removeElementAt(v.size() - 1);
}
String[] t = new String[v.size()];
for (int i = 0; i < v.size(); i++) {
t[i] = (String) v.elementAt(i);
}
return t;
}


/**
*  no more errors with parsing ints with this method
*
*@param  s  Description of the Parameter
*@return    Description of the Return Value
*/
public static int parseInt(String s) {
StringBuffer b = new StringBuffer(s.length());
for (int i = 0; i < s.length(); i++) {
if (Pattern.matches("[-0-9]", s.substring(i, i + 1))) {
b.append(s.substring(i, i + 1));
}
}
return Integer.parseInt(b.toString());
}
}

EasyX509TrustManager.java:

package de.kout.wlFxp;

import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;

public class EasyX509TrustManager implements X509TrustManager {
private X509TrustManager standardTrustManager = null;

public EasyX509TrustManager(KeyStore keystore)
throws NoSuchAlgorithmException, KeyStoreException {
super();
TrustManagerFactory factory = TrustManagerFactory
.getInstance("SunX509");
factory.init(keystore);
TrustManager[] trustmanagers = factory.getTrustManagers();
if (trustmanagers.length == 0) {
throw new NoSuchAlgorithmException(
"SunX509 trust manager not supported");
}
this.standardTrustManager = (X509TrustManager) trustmanagers[0];
}

public void checkClientTrusted(X509Certificate[] certificates,
String authType) throws CertificateException {
this.standardTrustManager.checkClientTrusted(certificates, authType);
}

public void checkServerTrusted(X509Certificate[] certificates,
String authType) throws CertificateException {
if ((certificates != null) && (certificates.length == 1)) {
X509Certificate certificate = certificates[0];
try {
certificate.checkValidity();
} catch (CertificateException e) {
}
} else {
this.standardTrustManager
.checkServerTrusted(certificates, authType);
}
}

public X509Certificate[] getAcceptedIssuers() {
return this.standardTrustManager.getAcceptedIssuers();
}
}


 


用法:
用旧 SocketChannel作为参数构建SSLSocketChannel
然后,tryTLS(1)

你可能感兴趣的:(.net,框架,socket,Security,J#)