Download cryptography 456 android secure file transfer w/ ssl

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
CRYPTOGRAPHY 456
ANDROID SECURE FILE TRANSFER
W/ SSL
Daniel Collins
Advisor: Dr. Wei Zhong
Contents






Create Key Stores and Certificates
Multi-Threaded Android applications
UI Handlers
Creating client and server SSL Sockets with Java
Android Intents
Screen Shots
Creating Keystores for Android

Android natively supports Bouncy Castle (BKS) key
stores.
 However,
the most recent version of Bouncy Castle is not
compatible with Android.
 Replace the version of Bouncy Castle in the lib/ext
folder with bcprov-jdk15on-146.jar

We will create the keystores with the Bouncy Castle
provider for use in an Android Application
Commands for Creating Keystores


Create a BKS keystore for the client

keytool -genkey -u -keyalg RSA -keystore
clientkeystore -storetype BKS -provider
org.bouncycastle.jce.provider.BouncyCastleProvid
er -providerpath /path/to/bcprov-jdk15on-146.jar

In this example, I will use “client” as the password
Create a BKS keystore the server

keytool -genkey -u -keyalg RSA -keystore
serverkeystore -storetype BKS -provider
org.bouncycastle.jce.provider.BouncyCastleProvid
er -providerpath /path/to/bcprov-jdk15on-146.jar

In this example, I will use “server” as the password
Commands for Creating Certificates

Export Client Certificate from client keystore


keytool -export -v -file clientcer -keystore
clientkeystore -storetype BKS -provider
org.bouncycastle.jce.provider.BouncyCastleProvid
er -providerpath /path/to/bcprov-jdk15on-146.jar
Export Server Certificate from server keystore

keytool -export -v -file servercer -keystore
serverkeystore -storetype BKS -provider
org.bouncycastle.jce.provider.BouncyCastleProvid
er -providerpath /path/to/bcprov-jdk15on-146.jar
Commands for Trusting Certificates

Import client certificate into server keystore


keytool -import -v -alias filetransferclient –
file clientcer -keystore serverkeystore storetype BKS -provider
org.bouncycastle.jce.provider.BouncyCastleProvid
er -providerpath /path/to/bcprov-jdk15on-146.jar
Import server certificate into client keystore

keytool -import -v -alias filetransferserver –
file servercer -keystore clientkeystore storetype BKS -provider
org.bouncycastle.jce.provider.BouncyCastleProvid
er -providerpath /path/to/bcprov-jdk15on-146.jar
Add Keystores to Android Application

Copy the clientkeystore and serverkeystore files into
the res/raw folder in your Android application.

You may need to create this folder
Code Overview

MainActivityServer.java
 Creates

FileTransferServer.java
 Creates
client.

the SSL Secured Socket and communicates with
MainActivityClient.java
 Creates

the server-side user interface.
the client-side user interface.
FileTransferClient.java
 Creates
server.
the SSL Secured Socket and communicates with
Creating the Server Main Activity UI

The MainActivityServer.java class will
contain:
Handler classes to allow the background thread to update
the user interface.
 Two EditText widgets named FileNameEt and PortEt
 A TextView named mServerStatusTv

A
button named ReceiveFileBtn with an
onClickListener

A progress bar will be constructed and the
FileTransferServer.java thread will be started when it
is clicked
UI Handler Classes




The Android’s Handler class can be extended to allow
an application to update the UI from a background
thread.
The class overrides the handleMessage() function
of Android’s Handler class.
The handleMessage() function receives a Message
object which contains the data for the update.
The uiHandler and pbHandler classes are selfcontained in the MainActivityServer class in this
example.
The uiHandler Class
private class uiHandler extends Handler {
@Override
public void handleMessage(Message msg) {
TextView mStatusMessagesTv = (TextView)
findViewById(R.id.serverStatusTv);
mStatusMessagesTv.append(
(CharSequence) ("\n" + (String) msg.obj));
}
}


The Message object’s variable, obj, is an arbitrary
Java Object
In this case, obj contains the string to display in
mServerStatusTv.
pbHandler ‘s handleMessage() Function
if(msg.what == 1) {
progressBar.setMessage("Receiving file from " + (String)
msg.obj + " ...");
progressBar.setMax(msg.arg1);
} else if(msg.what == 2) {
progressBar.setProgress(msg.arg1);
... // etc
}

To update the progress bar, the Message objects (int) what
and (int) arg1 variables are used.
 what notifies the handler what the message is about
 arg1 is used to update the progress bar’s status.
Creating the OnClickListener
receiveFileBtn.setOnClickListener(new
Button.OnClickListener() {
@Override
Public void onClick(View v) {
// Create progress bar dialog
...
// Start the FileTransferServer thread
...
}

v is the View object and will be used to transfer
the UI’s context to the thread.
Creating the Progress Bar
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(true);
progressBar.setMessage(SERVERIP + " is listening on " + mServerPort + "
...");
progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressBar.setProgress(0);
progressBar.setMax(0);
progressBar.show();


SERVERIP is the device’s IP Address.
mServerPort is the user specified port for
communication. This can be retrieved from portEt.
Starting the Server Thread
Thread mServerThread = new FileTransferServer(SERVERIP,
mServerPort, new uiHandler(), new pbHandler(),
v.getContext(), mServerFilePath);
mServerThread.start();


v.getContext() will be used to retrieve the
keystore from Android’s res/raw folder.
mServerFilePath is the user specified
fileName from fileNameEt
The FileTransferServer.java Class
public class FileTransferServer extends Thread {
public FileTransferServer(String LocalIP, int Port, Handler uiHandler,
Handler ProgressBarHandler, Context context, String fileToReceive) {
...
}
public void run() {
...
}
}


The constructor simply assigns it’s parameters to class
variables
The run() function does the following:
 Creates the SSL Socket
 Receives a file from the client on this socket.
Creating the SSL Socket (Server)

Get instance of a KeyManagerFactory object


KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.
getDefaultAlgorithm());
Get a Bouncy Castle instance of a KeyStore object

KeyStore keyStore = KeyStore.getInstance("BKS");
Creating the SSL Socket (Server) cont’d…

Load the keystore file into the keystore object
 keyStore.load(UiContext.getResourc
es().openRawResource(R.raw.filetra
nsferserverkeystore),
"server".toCharArray());


The first parameter loads the serverkeystore file from the Android
res/raw folder using the UI class’s context.
The second parameter is the keystore password.
Creating the SSL Socket (Server) cont’d…

Initialize the KeyManagerFactory with the KeyStore


Get Instance of TrustManagerFactory


kmf.init(keyStore,
"server".toCharArray());
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustMan
agerFactory.getDefaultAlgorithm());
Initialize TrustManagerFactory

tmf.init(keyStore);
Creating the SSL Socket (Server) cont’d…

Create SSLContext object
 SSLContext
SSLctx =
SSLContext.getInstance("TLS");

Initialize the SSLContext
 SSLctx.init(kmf.getKeyManagers(),
tmf.getTrustManagers(), null);

Initiate ServerSocketFactory
 SSLServerSocketFactory
ssf =
SSLctx.getServerSocketFactory();
Creating the SSL Socket (Server) cont’d…

Create Server Socket
 SSLServerSocket
ss =
(SSLServerSocket)
ssf.createServerSocket(myPort);

Authenticate Client
 ss.setNeedClientAuth(true);
Receiving the File (Server)


A secure socket is now available to receive a file
from the client.
This file will be received in two parts
 First,
the file size will be sent
 Then the client will begin the actual file transfer, which
will be sent in packets of 1024 bytes.

As the file is being received, the progress bar is
updated.
Updating the UI from Server Thread
public void updateUI(String message) {
Message msg = Message.obtain(mHandler);
msg.obj = message;
mHandler.sendMessage(msg);
}



The updateUI function is part of the
FileTransferServer class.
mHandler references the uiHandler class we
created in MainActivityServer.java
After assigning data to the Message object, msg, we
send it to the Handler which will update the UI.
Updating the ProgressBar
public void updatePBMax(long fileSize, String clientIP) {
Message msg = Message.obtain(pbHandler);
msg.arg1 = (int) fileSize;
msg.obj = clientIP;
msg.what = 1;
pbHandler.sendMessage(msg);
}


pbHandler references the pbHandler class
we created in MainActivityServer.java
After assigning data to the Message object, msg,
we send it to the Handler which will update the UI.
Updating the ProgressBar cont’d...
public void updatePBProgress(int progress) {
Message msg = Message.obtain(pbHandler);
msg.arg1 = progress;
msg.what = 2;
pbHandler.sendMessage(msg);
}
public void closePB() {
Message msg = Message.obtain(pbHandler);
msg.what = 3;
pbHandler.sendMessage(msg);
}

These two functions send unique msg.what
variables which allow the pbHandler to
determine the purpose of the message.
Creating the Client Main Activity UI

The MainActivityClient.java class will
contain:
A Handler class for the ProgressBar and TextViews
 Two EditText widgets named serverIpEt and portEt
 Two TextView widgets named
main_local_ip_address_tv and
main_chat_box_tv
 Two buttons named selectFileBtn and
main_send_file_btn with OnClickListeners

selectFileBtn will launch an Android Intent to allow the
user to choose a file
 main_send_file_btn will create a progress bar and start
the FileTransferClient thread

Android Intents




Android Intents can be used to allow separate applications to transfer data
with each other
When the Intent is broadcast, the Android system displays a list of
applications that can handle the request.
This example looks for a file explorer application
 Not all Android devices have a pre-installed file browser. You can
download a third-party file browser, such as ES File Explorer, to handle
the Intent
 To install ES File Explorer on an emulator:
 Download the apk file and store it on the device sdcard
 Open an internet browser
 type "file:///sdcard/es_file_explorer_file_name.apk" then press Go
The function, onActivityResult() will be called when the user selects a file.
Launching the Intent
selectFileBtn.setOnClickListener(new
Button.OnClickListener(){
@Override
public void onClick(View v) {
//
Create a new intent
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//
Look for any file type
intent.setType("file/*");
//
Start the Activity
startActivityForResult(intent,PICKFILE_RESULT_CODE);
}
});
Getting Results from the Intent
@Override
protected void onActivityResult(int requestCode, int
resultCode, Intent data) {
switch(requestCode){
case PICKFILE_RESULT_CODE:
if(resultCode==RESULT_OK){
//
Gets data from Intent
Uri dataURI = data.getData();
//
...
}
break;
}
}
Verify file existance and get details
Starting the Client Thread
mClientThread = new FileTransferClient(SERVERIP,
mClientFilePort, new uiHandler(), new pbHandler(),
mClientFilePath, mClientFileSize, v.getContext());
mClientThread.start();


The thread will be started from the
main_send_file_btn OnClickListener
mClientFilePath and mClientFileSize
are available in the URI data from the Intent.
The FileTransferClient.java Class
public class FileTransferClient extends Thread {
public FileTransferClient(String remoteIP, int remotePort, Handler
UIHandler, Handler PBHandler, String fileToSend, long
fileSendSize, Context uicontext) {
...
}
public void run() {
...
}
}


The constructor simply assigns it’s parameters to class
variables
The run() function does the following:
 Creates the SSL Socket
 Sends a file to the server on this socket.
Creating the SSL Socket (Client)

Setting up the KeyManagerFactory, TrustManagerFactory, and SSL context
is the same for the client as it is the server.

KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDe
faultAlgorithm());
KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(UiContext.getResources().openRawResourc
e(R.raw.filetransferclientkeystore),
"client".toCharArray());
kmf.init(keyStore, "client".toCharArray());
SSLContext SSLctx = SSLContext.getInstance("TLS");
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(TrustManagerFactory.g
etDefaultAlgorithm());
tmf.init(keyStore);
SSLctx.init(kmf.getKeyManagers(),
tmf.getTrustManagers(), null);
Creating the SSL Socket (Client) cont’d…

Initiate Client SSLSocketFactory


Create the SSL secured socket


SSLSocketFactory sf =
SSLctx.getSocketFactory();
SSLSocket socket = (SSLSocket)
sf.createSocket(serverAddr, serverPort);
Start handshake with server

socket.startHandshake();
Client and Server decide which protocol and cipher’s to use.
 Client and Server authenticate each other’s digital certificates.

Sending the File (Client)


A secure socket is now available to send a file to
the server.
This file will be sent in two parts
 First,
the file size will be sent
 Then the client send the file in packets of 1024 bytes.

As the file is being sent, the progress bar is
updated.
Screen Shots (Server)
Server GUI
Server waiting for file
Screen Shots (Client)
Client GUI
Client sending file
Screen Shots (Intent)
Intent Broadcast
Selecting a file w/ ES File Explorer