我正在尝试编写一个通过安全连接(SSL / TLS)与Java PC服务器通信的Android应用程序我已经阅读了几个教程并遵循它们,以下代码在PC到PC上使用时有效,但是当我但是在Android(3.2)设备上的客户端代码在SSL或TLS握手上停止。 以下是客户端通信代码:
public class ClientCommunicationManager implements Runnable{
/**
* Application context
*/
private Context context;
/**
* Host string
*/
private String host;
/**
* port number
*/
private int port;
/**
* Report Recieved Listeners vector
*/
private Vector<ReportRecievedListener> rrListeners;
/**
* Connection to the client
*/
private DataInputStream din;
/**
* Connection to the client
*/
private DataOutputStream dout;
/**
* KeyStore for storing our public/private key pair
*/
private KeyStore clientKeyStore;
/**
* KeyStore for storing the server's public key
*/
private KeyStore serverKeyStore;
/**
* Used to generate a SocketFactory
*/
private SSLContext sslContext;
/**
* A list of visible postings
*/
private Set postings = new HashSet();
/**
* Passphrase for accessing our authentication keystore
*/
static private final String passphrase = "a1n2d3r4o5i6d";
/**
* A source of secure random numbers
*/
static private SecureRandom secureRandom;
public ClientCommunicationManager( String host, int port,Context context ) {
this.context = context;
this.host = host;
this.port = port;
rrListeners = new Vector<ReportRecievedListener>();
secureRandom = new SecureRandom();
secureRandom.nextInt();
}
public void registerRRListener(ReportRecievedListener listener){
rrListeners.add(listener);
}
private void setupServerKeystore() throws GeneralSecurityException, IOException {
serverKeyStore = KeyStore.getInstance( "BKS" );
serverKeyStore.load( context.getResources().openRawResource(R.raw.serverbks),
"public".toCharArray() );
}
private void setupClientKeyStore() throws GeneralSecurityException, IOException {
clientKeyStore = KeyStore.getInstance( "BKS" );
clientKeyStore.load( context.getResources().openRawResource(R.raw.clientbks),
passphrase.toCharArray() );
}
private void setupSSLContext() throws GeneralSecurityException, IOException {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init( serverKeyStore );
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init( clientKeyStore, passphrase.toCharArray() );
sslContext = SSLContext.getInstance( "SSL" );
sslContext.init( kmf.getKeyManagers(),
tmf.getTrustManagers(),
secureRandom );
}
public void connect() {
new Thread(new Runnable() {
public void run() {
try {
setupServerKeystore();
setupClientKeyStore();
setupSSLContext();
} catch (GeneralSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
SSLSocketFactory sf = sslContext.getSocketFactory();
SSLSocket socket= null;
InputStream in = null;
OutputStream out = null;
try {
socket = (SSLSocket)sf.createSocket( host, port );
socket.setUseClientMode(true);
socket.startHandshake();
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
din = new DataInputStream( in );
dout = new DataOutputStream( out );
if(socket!=null)
new Thread( this ).start();
}
}).start();
}
public void run() {
boolean isConnected = true;
try {
while (isConnected) {
String msg = din.readUTF();
if(msg.equals("END"))
isConnected = false;
else
fireReportRecievedEvent(new ReportRecievedEvent(msg));
}
} catch( IOException ie ) {
ie.printStackTrace();
}
}
private void fireReportRecievedEvent(ReportRecievedEvent event){
for(ReportRecievedListener listener : rrListeners){
listener.onReportRecieved(event);
}
}
}
以下是服务器代码:
public class CommunicationManager implements Runnable{
private int port = Constants.SERVER_PORT;
private HashSet<ConnectionProcessor> connections = new HashSet<ConnectionProcessor>();
private KeyStore clientKeyStore;
private KeyStore serverKeyStore;
private SSLContext sslContext;
static private SecureRandom secureRandom;
private boolean running;
private SSLServerSocket ss=null;
private static CommunicationManager instance=null;
private CommunicationManager(){
}
public static CommunicationManager getInstance(){
if(instance == null){
instance = new CommunicationManager();
}
return instance;
}
public int getSecureRandom(){
SecureRandom securerandom = new SecureRandom();
return securerandom.nextInt();
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
public void startServer(){
if(!isRunning()){
setRunning(true);
new Thread(this).start();
}
}
public void stopServer(){
setRunning(false);
for(ConnectionProcessor cp : connections){
cp.close();
}
try {
if(ss!=null)
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void setupClientKeyStore() throws GeneralSecurityException, IOException {
clientKeyStore = KeyStore.getInstance( "JKS" );
clientKeyStore.load( new FileInputStream( "resources/client.public" ),
"public".toCharArray() );
}
private void setupServerKeystore() throws GeneralSecurityException, IOException {
serverKeyStore = KeyStore.getInstance( "JKS" );
serverKeyStore.load( new FileInputStream( "resources/server.private" ),
Constants.SERVER_KEYSTORE_PWD.toCharArray() );
}
private void setupSSLContext() throws GeneralSecurityException, IOException {
TrustManagerFactory tmf = TrustManagerFactory.getInstance( TrustManagerFactory.getDefaultAlgorithm() );
tmf.init( clientKeyStore );
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm() );
kmf.init( serverKeyStore, Constants.SERVER_KEYSTORE_PWD.toCharArray() );
sslContext = SSLContext.getInstance( "TLS" );
sslContext.init( kmf.getKeyManagers(),
tmf.getTrustManagers(),
secureRandom );
}
@Override
public void run() {
try {
setupClientKeyStore();
setupServerKeystore();
setupSSLContext();
} catch (GeneralSecurityException | IOException e) {
e.printStackTrace();
}
SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
try {
ss = (SSLServerSocket)sf.createServerSocket( port );
} catch (IOException e) {
e.printStackTrace();
}
// Require client authorization
ss.setNeedClientAuth( true );
System.out.println( "Listening on port "+port+"..." );
while (isRunning()) {
Socket socket=null;
try {
socket = ss.accept();
} catch (IOException e) {
if(e.getClass() == SocketException.class){
System.out.print("accept() threw SocketException because of close\n");
}
}
if(socket!=null && socket.isConnected()){
System.out.println( "Got connection from "+socket );
ConnectionProcessor cp = new ConnectionProcessor( this, socket );
connections.add( cp );
}
}
closeServer();
}
private void closeServer() {
for(ConnectionProcessor cp : connections){
cp.close();
}
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Remove a connection that has been closed from our set
* of open connections
*/
public void removeConnection( ConnectionProcessor cp ) {
connections.remove( cp );
}
/**
* Return an iteration over open connections
*/
public Iterator getConnections() {
return connections.iterator();
}
/**
* Broadcast a report over all connections
*/
public void broadcastReport(String report){
for(ConnectionProcessor cp : connections){
cp.send(report);
}
}
/**
* Broadcast a report over all connections using a new thread
*/
public void broadcastOnThread(final String report) {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
if(isRunning())
broadcastReport(report);
}
}) ;
t.start();
}
/**
* recieve a new report to be broadcasted
*/
public void acceptReport(String report_string) {
broadcastOnThread(report_string);
}
}
非常感谢任何帮助或见解。谢谢。
答案 0 :(得分:1)
问题是没有交换数据(尚未)因此握手从未完成。