Cryptography 456 Senior Seminar 599 USC Upstate Encrypted One-Way File Transfer on Android Devices By Sheldon Smith, Instructor Dr. Zhong
Contents One-Way File Transfer Diagram Utilizing Cryptography Asymmetric Algorithm Symmetric Algorithm The Cryptosystem The Project Code Overview Screen Shots Demonstration
One-Way File Transfer Diagram Phase 1 Client Socket Server Receive Server s Public Key Generate RSA Key Pair Private Key Generate AES Key Encrypt AES Key Receive Encrypted AES Key Decrypt AES Key
One-Way File Transfer Diagram Phase 2 Client Socket Server File Input Stream AES Decrypt Cipher Data Input Stream Read in File to Buffer Read in Data to Buffer Cipher Output Stream Data Output Stream Cipher Output Stream Data Input Stream Data Output Stream AES Encrypt Cipher File Output Stream
Utilizing Cryptography Asymmetric Algorithm RSA Symmetric Algorithm AES (Advanced Encryption Scheme)
Asymmetric Algorithm RSA Supported key lengths: 1,024 to 4,096 bits Two keys: Public and Private Public is used for encryption Private is used for decryption Used to encrypt symmetric key for transportation
Asymmetric Algorithm RSA (ctd.) Advantages: Solves the problem of distributing the key Disadvantages: Impractical for encryption or decryption
Symmetric Algorithm AES (Advanced Encryption Scheme) Supported key lengths: 128, 192, and 256 bits Single key, typically referred to as a symmetric key or session key Used to encrypt and decrypt data
Symmetric Algorithm AES (ctd.) Advantages: Quick encryption and decryption, unique key for each session Disadvantages: Need a secure channel to transfer the key
The Cryptosystem Implements both asymmetric and symmetric algorithms Asymmetric algorithm is used for distributing the symmetric key Symmetric algorithm is used for encryption and decryption
The Project Socket Programming The server opens a server socket on a unique port, and a user connects to the socket using the IP address and port number
The Project Thread Diagram A thread is a concurrent unit of execution UI Thread (progress bar) UI Thread (UI) Handler Handler File Transfer Thread
Android Manifest The manifest holds information about the app needed by the Android system <uses-permission android:name="android.permission.internet" /> <uses-permission android:name="android.permission.write_external_storage" /> <uses-permission android:name="android.permission.read_external_storage" />
Android Manifest <activity android:name="com.example.filetransferclient.menuactivity" android:label="file Transfer"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <activity android:name="com.example.filetransferclient.serveractivity" android:label="server"> <intent-filter> <action android:name="android.intent.action.view" /> <category android:name="android.intent.category.default" /> </intent-filter> </activity>..
Menu Activity - Overview The menu activity was designed and incorporated to improve the flexibility of the app. Instead of a distinguished client and server app, the menu activity allows the user to choose whether he/she wants to run the app as a server or client. To achieve this flexibility, intents were utilized An intent is a passive data structure holding an abstract description of an operation to be performed
Menu Activity XML Sample <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#111111" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="horizontal" android:background="#111111" > <Button android:id="@+id/client_activity....android:onclick="onclick android:text="start Client android:textcolor="#ffffff" />..
Menu Activity Code Sample public void onclick(view v){ try{ switch(v.getid()){ case R.id.client_activity: Intent i = new Intent(MenuActivity.this, ClientActivity.class); startactivity(i); break; case R.id.server_activity: Intent j = new Intent(MenuActivity.this, ServerActivity.class); startactivity(j);..
Client and Server Activities - Overview Methods: oncreate() (Client side only) onclick() uihandler() progressbarhandler() getlocalipaddress() (Server side only) isexternalstorageusable()
Client and Server Activities XML Sample <TextView android:id="@+id/progress_bar_status" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_vertical center_horizontal....android:textcolor="#00ff00" android:visibility="gone" /> <ProgressBar android:id="@+id/progressbar" style="@android:style/widget.progressbar.horizontal" android:layout_width="fill_parent" android:layout_height="30dp"....android:progressdrawable="@drawable/greenprogress" android:visibility="gone" />..
Client and Server Activities Methods oncreate() Find all our views by their XML id mstatusmessagestv = (TextView) findviewbyid (R.id.client_local_ip_status_tv); (Client side only) Instantiate an Alert Dialog to manually input the server device s IP address alert = new AlertDialog.Builder(this); (Server side only) Creates and starts an instance of the File Transfer Server class ftransferserver = new FileTransferServer( ) ftransferserver.start();
Client and Server Activities Methods (Client side only) onclick() Contains the hardcoded file name and retrieves the file size on the client side Creates and starts an instance of the File Transfer Client class ftransferclient = new FileTransferClient(SERVERIP, serverport, new uihandler(), new progressbarhandler(), filename, filesize, progressbar, progressstatus); ftransferclient.start();
Client and Server Activities - Methods uihandler() Extends the handler class Handles messages sent back from the File Transfer Client or Server Thread message = msg.getdata().getstring("message"); mchatboxtv.settext(mchatboxtv.gettext().tostring () + "\n" + message);
Client and Server Activities Methods progressbarhandler() Extends the handler class Handles updates sent back from the File Transfer Client or Server Thread int progress = msg.getdata().getint("int"); progressbar.setprogress(progress); progressstatus.settext(progress + " %");
Client and Server Activities Methods getlocalipaddress() Returns a String representation of a device s IPv4 address or null if none was found (Server side only) isexternalstorageusable() Returns true if external storage can be read and written to Returns false for any other combination of access permissions
File Transfer Client and File Transfer Server - Overview The File Transfer Client and File Transfer Server classes are where all the work is done They run alongside the uihandler and progressbarhandler threads Methods: updateui() updateprogressbar() run()
File Transfer Client and File Transfer Server - Methods updateui() Sends bundled message back to the UI handler Message msg = mhandler.obtainmessage(); Bundle b = new Bundle(); b.putstring("message", message); b.putstring("type", "message_display_status"); msg.setdata(b); mhandler.sendmessage(msg);
File Transfer Client and File Transfer Server - Methods updateprogressbar() Sends bundled message back to the progress bar handler Message msg = phandler.obtainmessage(); Bundle b = new Bundle(); b.putint("int", percent); msg.setdata(b); phandler.sendmessage(msg);
File Transfer Client run() run() Connect to the server socket socket = new Socket(serverIP, serverport); Create data input and output streams DataOutputStream dos = new DataOutputStream(socket.getOutputStream()); Read in server s public key bytes from socket int keylength = dis.readint(); byte[] serverpubkey = new byte[keylength]; dis.readfully(serverpubkey);
File Transfer Client run() run() (ctd.) Generate server s public key using key bytes X509EncodedKeySpec keyspec = new X509EncodedKeySpec(serverPubKey); KeyFactory myfactory = KeyFactory.getInstance("RSA"); PublicKey pubkey = myfactory.generatepublic(keyspec); Create AES key and IV Key symmetrickey = CryptoUtils.createAESKey(256, random); IvParameterSpec ivspec = CryptoUtils.createAESCtrIv(random);
File Transfer Client run() run() (ctd.) Initialize RSA cipher for encryption Cipher pubcipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA1AndMGF1Pa dding"); pubcipher.init(cipher.encrypt_mode, pubkey); Encrypt the AES key for transmission byte[] encraesbytes = pubcipher.dofinal(symmetrickey.getencoded());
File Transfer Client run() run() (ctd.) Send the encrypted AES key and the IV bytes over the socket dos.writeint(encraesbytes.length); dos.write(encraesbytes); dos.write(ivspec.getiv()); Create and initialize the AES cipher for encrypting Cipher symcipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); symcipher.init(cipher.encrypt_mode, symmetrickey, ivspec);
File Transfer Client run() run() (ctd.) Create a data input stream DataInputStream file = new DataInputStream(new FileInputStream(fileName)); Send the packet size and file size over the socket dos.writeint(filesend_packet_size); dos.writeint(bytestosend); Create a cipher output stream CipherOutputStream cos = new CipherOutputStream(dos, symcipher);
File Transfer Client run() run() (ctd.) Transfer the file, simultaneously update the progress bar while((bytesread = file.read(data))!= -1) { cos.write(data, 0, bytesread); store += bytesread; progress = ((float)store/(float)filesize)*100; phandler.post(new Runnable(){ public void run() { updateprogressbar((int)progress); } }); }
File Transfer Server run() run() Create the server socket serversocket = new ServerSocket(serverPort); Wait for the client to connect client = serversocket.accept(); Create the data input and output streams DataOutputStream dos = new DataOutputStream(client.getOutputStream());
File Transfer Server run() run() (ctd.) Create the RSA key pair generator KeyPairGenerator generator = KeyPairGenerator.getInstance( RSA, BC ); generator.initialize(1024, random); Create an RSA key pair KeyPair pair = generator.generatekeypair(); PublicKey pubkey = pair.getpublic(); PrivateKey privkey = pair.getprivate();
File Transfer Server run() run() (ctd.) Send the RSA public key over the socket dos.writeint(pubkey.getencoded().length); dos.write(pubkey.getencoded()); Read in the encrypted AES key bytes from the socket byte[] encraeskey = new byte[dis.readint()]; dis.readfully(encraeskey); Read in the IV bytes from the socket byte[] IV = new byte[16]; dis.readfully(iv);
File Transfer Server run() run() (ctd.) Initialize the RSA cipher for decryption Cipher privcipher = Cipher.getInstance( RSA/NONE/OAEPWITHSHA1ANDMGF1P adding ); privcipher.init(cipher.decrypt_mode, privkey); Decrypt the AES key bytes byte[] AESKey = privcipher.dofinal(encraeskey); Recreate the AES key and IV SecretKeySpec keyspec = new SecretKeySpec(AESKey, AES );
File Transfer Server run() run() (ctd.) Initialize the AES cipher for decryption Cipher aescipher = Cipher.getInstance( AES/CBC/PKCS5Padding ); aescipher.init(cipher.decrypt_mode, keyspec, ivspec); Create a data output stream DataOutputStream file = new DataOutputStream(new FileOutputStream(fileName)); Create a cipher output stream CipherOutputStream cos = new CipherOutputStream(file, aescipher);
File Transfer Server run() run() (ctd.) Receive the file, simultaneously update the progress bar while((bytesread = dis.read(data))!= -1){ cos.write(data, 0, bytesread); byteswritten += bytesread; progress = ((float)byteswritten/(float)filesize)*100; phandler.post(new Runnable() { public void run() { updateprogressbar((int)progress); } }); }
Screenshots This is the menu activity.
Client: Manual inputting server IP address. Server: Waiting for a connection to be established.
Client: Connected to server. Server: Connection has been established.
Client: Reading in server s RSA public key. Server: Creating and sending RSA public key.
Client: Generate AES key and IV. Send both over the socket. Server: Read in encrypted AES key and IV. Recreate both of them.
Client: Initialize AES cipher for encryption. Create file input stream and cipher output stream. Server: Initialize AES cipher for decryption. Create file output stream and cipher output stream.
Client and Server: File transfer is complete.