Sei sulla pagina 1di 112

 

 
 
 
 
 
 
 
 
Department  of  Electronic  &  Electrical  Engineering  

 
MSc  Avionic  Systems  Engineering  
 
Dissertation  2015  
 
 
 
SafeTime  Application  
 
 
Student:     Viteri  Buendía,  Ricardo  Mauricio  
 
Registration:   140209688  
 
Date:       August  28,  2015  
 
 
 
Supervisor:     Dr.  Jonathan  M  Rigelsford  
 
Second  Marker:     Dr.  Gregory  Cook  
 
 
This  dissertation  is  a  part  requirement  for  the  degree  of  MSc  in  Avionic  
Systems  Engineering.  

 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
 

 
 
 
 
 
 
 
 
Abstract  
 
Communication   is   a   basic   part   of   our   lives   in   a   daily   basis,   messages   come   and   go  
from   various   places   worldwide   as   long   as   the   user   have   access   to   the   web.   All   those  
messages  transform  in  sets  of  bytes  that  will  be  “surfing”  through  the  net  to  get  to  
their   destination,   but   not   necessarily   in   a   secure   way.   Lately,   many   issues  
concerning  security  have  been  announced  in  the  news,  some  of  them  are  personal  
cases   such   as   photos   and   messages   hacked   from   celebrities   phones,   others  
concerning  big  companies  such  as  NBC.  
The   world   is   becoming   more   accessible   day-­‐by-­‐day   and   personal   security   is   also  
becoming   more   important.   This   project’s   aim   is   to   develop   an   instant   messaging  
application  in  Android  platform  that  will,  by  all  means  necessary,  protect  the  user’s  
data,  not  by  preventing  it  to  be  stolen,  but  preventing  it  to  be  read  by  any  peer  not  
involved  in  the  communication  nor  the  server  managing  the  communication.  

 
 

 
 
 
 
 
 
Acknowledgements  
 
To  my  supervisor,  Dr.  Jonathan  Rigelsford  for  his  support  and  help  during  
the  developing  of  this  project  and  helping  me  focus  my  ideas  and  objectives  
in  order  to  successfully  complete  not  only  what  was  intended,  but  more.  To  
my   family   and   friends   that   were   always   there   to   support   me   not   only  
during  my  studies,  but  throughout  my  life.  To  Pamela  Garcia  for  being  my  
biggest  support  in  the  most  stressful  moments  and  being  as  crazy  as  me  in  
my  craziest  moments.  
Juan   Marito,   this   is   what   your   uncle   was   doing   while   you   were   so   busy  
being  born.  
 
   

 
 

Table  of  Contents  


1.  Introduction  ..........................................................................................................................  1  
2.  Background  ...........................................................................................................................  2  
2.1  Instant  messaging  ......................................................................................................................  2  
2.2  Android  programming  .............................................................................................................  3  
2.3  Client/Server  communication  ...............................................................................................  4  
2.4  TCP/IP  sockets  ............................................................................................................................  6  
2.5  Encryption  algorithms  .............................................................................................................  7  
2.5.1  AES  algorithm  ........................................................................................................................................  8  
2.5.2  RSA  algorithm  ........................................................................................................................................  9  
3.  What  is  SafeTime?  ............................................................................................................  10  
3.1  How  it  works?  ...........................................................................................................................  11  
3.2  Application  flow  diagram  .....................................................................................................  12  
3.3  SafeTime  screen  by  screen  ...................................................................................................  13  
3.3.1  Login  screen  .........................................................................................................................................  13  
3.3.2  Register  screen  ....................................................................................................................................  14  
3.3.3  User  list  tab  ...........................................................................................................................................  14  
3.3.4  Conversation  tab  ................................................................................................................................  15  
3.3.5  Add  contacts  tab  .................................................................................................................................  16  
3.4  Android  application  tasks  ....................................................................................................  16  
3.5  Server  tasks  ...............................................................................................................................  17  
4.  Research  methods  ............................................................................................................  18  
4.1  Development  tools  ..................................................................................................................  18  
4.1.1  Android  studio  ....................................................................................................................................  18  
4.1.2  Linux  server  ..........................................................................................................................................  19  
4.1.3  Eclipse  Mars  .........................................................................................................................................  19  
4.1.4  MongoDB  ...............................................................................................................................................  19  
4.1.5  TeamViewer  .........................................................................................................................................  20  
4.2  Encryption  algorithm  implemented  .................................................................................  21  
5.  SafeTime  main  processes  ..............................................................................................  23  
5.1  Registration  process  ...............................................................................................................  23  
5.2  Login  process  ............................................................................................................................  27  
5.3  Add  contact  process  ................................................................................................................  31  
5.4  Encryption  process  .................................................................................................................  35  
5.5  Decryption  process  .................................................................................................................  38  
5.6  Message  send/receive  process  ...........................................................................................  41  
6.  SafeTime  tests  ...................................................................................................................  45  
6.1  Test  1:  Key  generation,  Encryption  and  Decryption  ....................................................  45  
6.2  Test  2:  TCP  socket  communication  ....................................................................................  48  
6.3  Test  3:  Encryption  and  decryption  of  plain  text  with  one  set  of  keys  ....................  49  
6.4  Test  4:  Encryption  and  decryption  of  plain  text  with  two  different  set  of  keys  .  51  
6.5  Test  5:  Encryption  and  decryption  of  images  with  one  set  of  keys  .........................  52  
6.6  Test  6:  Encryption  and  decryption  of  images  with  two  different  set  of  keys  ......  54  
7.  Discussion  ...........................................................................................................................  55  
7.1  Achievements  of  SafeTime  ...................................................................................................  55  
7.2  Limitations  and  upgrades  .....................................................................................................  56  
7.3  SafeTime’s  use  for  industry  ..................................................................................................  57  
8.  Conclusions  ........................................................................................................................  57  

 
 

9.  Bibliography  ......................................................................................................................  59  


Appendix  A:  Application  codes  ............................................................................................  i  
Appendix  B:  Server  codes  ..............................................................................................  xxvii  
Appendix  C:  Test  RSA  keys  ...................................................................................................  xl  
Appendix  D:  Encryption  algorithm  C  code  tests  ........................................................  xlii  
 
 

 
 

 
1. Introduction  
Cyber   security   is   a   term   that   has   been   sounding   very   loudly   lately.   All   of   us,  
smartphone  users,  have  heard  of  this  term  at  least  once,  but  are  we  sure  of  what  
that  means?  
As  taken  from  the  Oxford  English  dictionary:  “Cyber  security  is  the  state  of  being  
protected   against   criminal   or   unauthorized   use   of   electronic   data   or   the  
measures  to  achieve  this”.  It  considers  defending  against  attacks  to  all  kinds  of  
computer  systems  [1].  So  we  now  understand  the  importance  of  this.  Every  day  
we   as   individuals   keep   in   touch   with   our   loved   ones,   colleagues,   bosses   and  
other   people   through   instant   messaging   applications   sharing   personal  
information,  pictures  and  other  files  taking  the  risk  of  being  hacked.  It  will  not  
seem  that  much  of  a  big  deal  if  we  just  take  into  consideration  simple  messages  
and   conversations,   but   what   if   we   reveal   our   passwords   for   some   reason,   or  
credit   card   information,   or   bank   information,   and   that’s   only   speaking   about  
personal  use,  for  big  companies  that  kind  of  information  can  involve  thousands  
of   pounds.   With   this   project,   I’m   developing   a   way   to   communicate   in   a   secure  
way,  using  as  my  interface  an  Android  application.  But  the  principles  taken  from  
this   research   can   be   applicable   for   other   kind   of   communications   in   more  
delicate   fields   such   as   the   government   or   the   military.   This   way,   some   of   the  
latest   concerns   in   cyber   security   can   be   covered   in   both   civil   and   military  
applications.  
In   this   dissertation,   first   of   all,   the   theory   behind   the   application   will   be  
explained,   instant   messaging,   Android   and   Client/Server   communication,   so   that  
the  later  explanation  of  the  project  can  make  more  sense  and  finally,  the  process  
in   which   it   has   been   developed   along   with   their   achievements,   limitations   and  
conclusions.  
 
 
 

1    
 

2. Background  
2.1. Instant  messaging  
Messaging   applications   like   Whatsapp,   Facebook   messenger   and   Skype   are  
amongst  the  most  downloaded  and  used  applications  in  the  Google  market  [2].  
The   main   objective   of   these   applications   is   to   provide   the   user   with   a  
communication  service  between  themselves  and  other  users  with  an  account  in  
it.  In  general,  the  way  in  which  the  IM  communications  work  is  that,  users,  which  
are   the   clients   and   have   an   account   authenticated   by   the   server,   send   a   packet  
with   a   set   of   information   such   as:   its   own   client   ID,   the   client   ID   of   whom   the  
message  is  sent  to  and  the  message  itself.  That  packet  is  sent  through  internet  to  
a   main   server,   which   is   going   to   be   the   one   that   will   manage   the   connection  
between  the  two  clients,  like  the  post  service,  the  server  will  look   for  the  ID  of  
the   second   client,   confirm   it   is   actually   a   client   and   not   corrupt   data,   and   then  
send   the   packet   to   its   destination.   The   following   diagram   represents   this   basic  
communication:  
 

 
Figure  1:  Basic  point  to  point  communication  

 
In  this  model,  which  is  the  one  that  will  be  used  for  this  project,  represent  how  
the   clients   uniquely   communicate   with   the   server,   therefore,   it   works   as   a  
mediator   between   the   clients   [3].   In   order   to   make   this   model   possible,  
client/server   communication   is   needed.   This   communication   structure   will   be  
explained  in  detail  later  on.  

2    
 

 
2.2. Android  programming  
Android   is   a   mobile   operating   system   created   in   2003   by   Android   Inc.   In   2005  
Google   acquired   Android   Inc.   and   started   to   work   on   their   new   mobile  
development  branch.  In  2010,  Google  finally  released  their  phone  Nexus  with  the  
new   Linux   kernel   based   operating   system   Android   2.2   (Froyo).   From   the   on,  
Android  OS  has  positioned  itself  as  one  of  the  most  important  mobile  system  in  
the  last  few  years.  Because  of  its  Linux  roots  and  Google’s  open  source  mentality,  
it’s  one,  if  not  the  most,  accessible  and  affordable  OS  for  developers  worldwide,  
for  this  reason  Android  OS  has  been  chosen  as  the  platform  in  which  this  project  
will  be  worked.  
Android   development   is   based   in   the   object   oriented   programming   language  
Java,   designed   by   Oracle   Corporation,   and   its   structure   is   based   in   4   main   blocks  
and  5  main  features  at  the  developers  disposal  [4].    
 
Main  blocks:  
• Activities:  Is  the  building  block  of  the  user  interface,  the  main  window  in  
which  the  developer  will  be  programming  what  the  app  is  going  to  do.  
• Content  providers:  provides  a  level  of  abstraction  for  the  data  stored  by  
an  application.  By  having  this,  data  can  be  accessed  by  other  applications  
while  maintaining  complete  control  of  such  data.  
• Intents:   These   are   system   messages   in   the   device.   This   messages   can  
notify   an   app   of   various   events   which   could   be:   hardware   events,  
incoming  data  of  application  events.  
• Services:  Are  features  in  an  app  that  can  keep  running  even  though  the  
application  is  no  longer  operating.  Different  than  the  Activities,  Content  
providers   and   Intents,   which   are   short-­‐lived,   Services   can   stay   “alive”  
waiting   for   events   an   app   may   be   waiting,   for   example   waiting   for   a  
message  from  the  server.  
 

3    
 

Main  features:  
• Storage:   an   application’s   data   files   can   be   stored   either   in   the   phone’s  
internal  memory  or  an  external  memory  provided  by  the  user  (SD  card).  
• Network:   generally,   Android   apps   are   Internet   ready,   and   is   able   to  
access   it   in   order   to   load   or   send   data,   for   example,   Java   sockets   which  
will  be  widely  used  in  this  project.  
• Multimedia:  Depending  on  the  device,  an  app  can  access  video  and  audio  
recorders  and  players  and  also  camera  and  picture  galleries.  
• GPS:  With  this,  an  application  can  access  the  user’s  location  in  the  earth.  
• Phone   services:   applications   can   dial   calls   or   send   and   receive   SMS  
messages.  
For   an   application   to   be   able   to   use   these   services,   the   user   must   grant  
permission.   These   permissions   will   be   typically   asked   for   while   installing   an  
application.  
Various  software  can  be  used  to  develop  Android  applications.  The  two  that  are  
mainly  used  are  Eclipse  and  Android  Studio.  For  this  project,  I’ve  decided  to  use  
Android   Studio   because   it   simplicity   and   quick   installation   process,   also   taking  
into   account   that,   since   the   release   of   their   first   stable   version   in   December  
2014,   it   has   become   officially   the   principal   development   environment   for  
Android.  
 
2.3. Client/Server  communication  
Client/Server   is   an   information   sharing   mode   widely   used   in   information  
systems   [5].   Is   the   communication   between   three   main   components,   the   client,  
the  server  and  the  network  system.  
• Client:   the   workstation,   in   this   project’s   case,   the   application   that  
provides  the  user  with  a  friendly  interface  to  be  used.  
• Server:   the   one   that   holds   the   information.   A   database   server   provides  
the   clients   with   a   main   information   center   were   they   have   access   and   can  
also  share  new  information.  

4    
 

• Network   system:  is  the  link  between  client  and  server.  This  link  can  be  
done  through  LAN,  WAN  or  Internet.  
 
The  way  in  which  this  model  works  is  quite  simple.  The  client  will  send  a  request  
to  the  server,  once  the  server  processes  de  request  it  will  send  a  response  back  
to  the  client.  An  example  for  this  is  illustrated  as  follows:  

 
Figure  2:  Client/Server  model  

 
For  this  example,  I’m  considering  a  basic  instant  messaging  system  in  which  the  
server   may   act   as   an   intermediary   between   two   clients.   Client   1   is   sending   a  
message  to  another  client;  the  process  will  follow  these  steps:  
1. Client   1   assembles   a   data   packet   and   sends   the   request   to   the   server  
through  the  network.  
2. The  server  receives  the  packet  and  processes  the  request.  It  identifies  the  
client  to  whom  the  packet  must  be  sent.  
3. The  server  sends  the  packet  to  the  receiver  client  through  the  network.  
4. The  server  sends  an  acknowledgment  packet  to  Client  1  confirming  that  
the  packet  has  been  sent  to  the  destination  client.  
Once   understood   client/server   communication,   it’s   important   to   understand  
how   a   connection   between   client   and   server   must   be   established.   In   this  
project’s  case,  the  most  suitable  are  the  TCP/IP  Sockets.  
 

5    
 

2.4. TCP/IP  sockets  


TCP/IP:  
In   order   to   initiate   a   point-­‐to-­‐point   client/server   connection   a   communication  
protocol   must   be   used.   The   Transmission   Control   Protocol   is   one   of   the   most  
widely   used   because   of   its   reliability.   TCP   guarantees   the   delivery   of   data   it  
transmits  in  form  of  packets  to  its  final  destination.  If  a  packet  is  damaged,  TCP  
will  resend  the  data  until  the  packets  are  successfully  transmitted.  
 
Socket:  
A  socket  is  an  endpoint  of  the  two-­‐way  communication  link  used  to  send  packets  
between   server   and   client.   A   socket   is   established   by   a   combination   of   both   IP  
address  and  port  number,  because  of  this,  multiple  connections  can  be  initiated  
between  client  and  server  making  every  connection  unique.  
To   establish   a   connection,   both   client   and   server   must   bind   a   socket   to   their   end  
of   connection.   Once   that   is   done,   both   can   read   from   and   write   to   the   socket  
when  communicating.  
 
Establishing  a  connection:  
The   process   to   create   sockets   varies   depending   if   it’s   a   client   or   a   server.   A  
socket   created   in   the   server   is   called   a   “passive   socket”   since   it   waits   for   and  
responds   to   clients.   A   socket   created   for   clients   in   the   other   hand   are   called  
“active  sockets”  and  will  be  initiated  with  the  main  goal  of  sending  a  message  to  
the  server,  for  that,  the  client  must  know  the  IP  address  and  port  number  of  the  
server’s  socket  [6].  So  the  lifecycle  of  a  socket  can  be  represented  in  this  way:  
 

6    
 

 
Figure  3:  Client  and  Server  Sockets  

 
2.5. Encryption  algorithms  
This  projects  main  goal  is  to  achieve  secure  communication  between  two  clients.  
The   way   in   which   such   communication   will   be   possible   is   by   encrypting  
messages  so  that  no  one  can  understand  the  contents  of  a  packet  without  having  
the  key  to  decipher  it.  Many  encryption  algorithms  may  be  useful,  the  ones  that  I  
consider  more  relevant  and  for  this  project  are:  
 
• Data  Encryption  Standard  (DES)  
• Advanced  Encryption  Standard  (AES)  
• RSA  
 
Because  of  the  small  key  size  of  DES  algorithm  (56  bits)  and  considering  that  the  
National  Institute  of  Standards  and  Technology  withdrew  it  as  a  standard,  I  have  
neglected  DES  from  my  project.  
 

7    
 

2.5.1.  Advanced  Encryption  Standard  (AES)  algorithm  


Is   a   symmetric   block   cipher   based   on   Rijndael   Cypher,   and   designed   by  
Vincent  Rijmen  and  Joan  Daemen  in  1998.  A  symmetric  block  cipher  means  
that   its   key   is   also   symmetric,   meaning   that   the   same   key   can   be   used   for  
both  encrypting  and  decrypting  data.  
This   cipher   can   process   data   blocks   of   128   bits   using   different   sizes   of  
cryptographic   keys   of   128,   192   and   256   bits   [7].   In   2002   AES   became   a  
federal  government  standard  in  the  United  States  of  America.  
 
This   algorithm   works   in   a   4x4   matrix   of   bytes   named   “state”.   The   key   size  
defines  the  amount  of  transformations  from  the  input  are  done  to  convert  it  
on  the  output:  
   
Table  1:  Repetitions  for  key  sizes  

 
 
A  cycle  consists  of  four  main  steps:  
1. AddRoundKey:  using  bitwise  xor,  each  bite  is  combined  with  a  block  
of  the  round  key.  
2. SubBytes:   each   byte   is   replaced   with   another   using   a   lookup   table.  
(non-­‐linear).  
3. ShiftRows:   The   last   three   rows   of   the   state   are   shifted   a   number   of  
steps  (transposition).  
4. MixColumns:  it  combines  all  the  bytes  within  each  column  (mixing).  
 
How  the  cycles  work  is  demonstrated  by  the  following  diagram:  

8    
 

 
Figure  4:  AES  cycle  structure  

 
2.5.2. RSA  algorithm  
First  published  in  1977  by  Ron  Rivest,  Adi  Shamir  and  Leonard  Adleman,  RSA  
is  an  asymmetric  public-­‐key  cryptosystem.  It  works  with  two  keys:  a  public  
encryption  key  and  a  secret  decryption  key  [8].  
 
This   algorithm   work   by   3   main   steps:   key   generation,   encryption   and  
decryption.  
• Key   generation:   Two   different   prime   numbers   (p   and   q)   must   be  
selected,  and  multiplied  amongst  each  other  to  generate:  
n  =  p*q  
Now,  Euler’s  totient  function  has  to  be  used  to  get:  
φ(n)  =  n  –  (p  +  q  -­‐  1)  
Choose   an   integer   e   such   as   1   <   e   <   φ,   this   number   must   be   coprime  
with    φ(n).  Using  e,  d  can  be  calculated:  
d  ≡  e  –  1  (mod  φ(n))  

9    
 

Finally,  values  of  p  and  q  must  be  erased  and  the  keys  are  ready:  
o Public  key  =  (n,  e)  
o Private  key  =  (n,  d)  
• Encryption:   Client_1,   which   already   generated   its   keys,   sends   the  
public   key   to   Client_2   and   keeps   the   private   key.   With   the   acquired  
key,  Client_2  encrypts  a  message  M  using  the  following  steps:  
o Turn  M  into  an  integer  m  such  that  0  ≤  m  ≤  n  using  a  padding  
scheme.  
o Now  compute  cypher  text  c:  
c  ≡  me  (mod  n)  
o Client_2  transmits  c  to  Client_1.  
• Decryption:   Client_1   receives   the   ciphertext   c   from   Client_2   and   in  
order  to  recover  m  the  following  steps  must  be  done:  
o Calculate  m  using:  
m  ≡  cd  (mod  n)  
o Reversing  the  padding  scheme,  message  M  can  be  recovered.  
 
3. What  is  SafeTime?  
SafeTime  is  an  instant  messaging  application  programmed  in  Android  platform.  Its  
main  objective  is  to  guarantee  a  secure  communication  between  two  users,  not  by  
preventing   data   sent   by   users   to   be   intercepted   or   hacked,   but   by   preventing   that  
data  to  be  read.  The  way  to  do  this  is  by  encrypting  the  messages  sent  by  the  users  
using  an  encryption  algorithm  RSA  so  that  people  trying  to  intercept  those  messages  
either   via   an   sniffer   reading   packets   or   hacking   into   the   main   server.   For   this  
version   of   the   application,   encryption   of   plain   text   messages   and   images   has   been  
developed.  

 
 
 

 
10  
 

3.1. How  it  works?  


The   way   in   which   this   application   will   work   is   represented   in   the   following  
diagram:  

 
Figure  5:  SafeTime  communication  flow  

 
Based  on  the  figure  shown,  the  way  in  which  the  app  will  work  is  explained:  
1. User_1  writes  a  message  in  plain  text,  once  finished,  the  message  is  then  
sent  to  the  encryption  process.  
2. Here  the  message  will  be  encrypted  using  the  RSA  public  key,  the  packet  
with  the  user  IDs  and  the  cyphered  message  is  then  sent  to  the  server.  
3. Using  sockets,  configuring  the  correct  port  and  IP  address,  the  packet  will  
go  to  the  server.  
4. The   server   will   check   to   which   user   the   packet   must   be   sent   and   will  
configure  the  socket  that  will  be  used  for  communicate  with  that  user.  
5. The   encrypted   packet   will   be   sent   through   the   socket   to   the   receiving  
user.  
6. The   application   will   open   the   packet   and   with   its   RSA   private   key   will  
begin  the  process  of  decrypting  the  message.  

 
11  
 

7. Once   the   message   is   decrypted   to   plain   text   or   image   again,   it   will   be  


displayed  in  the  user  interface  of  both  end  users.  
 
3.2. Application  flow  diagram  
For  the  application,  the  following  flow  chart  represents  the  sequence  of  windows  
it  will  have:  

 
Figure  6:  SafeTime  design  flow  chart  

Five  different  screens  are  planned  for  the  basic  application:  


• Login   screen:   is   the   first   screen   to   be   shown   by   the   app.   If   the   user  
already  has  an  account,  it  will  be  able  to  insert  the  email  and  password  in  

 
12  
 

order   to   start   sending   messages   to   its   contacts.   If   not   registered,   a   button  


to  go  to  the  register  screen  is  provided.  
• Register  screen:   If   a   user   is   not   registered   to   the   app,   in   this   screen   with  
a  simple  form,  which  will  be  sent  to  authenticate.  
• Multi-­‐fragment   Tabhost:   This   view   consists   on   3   different   tabs   which  
will  fulfill  three  main  purposes:  
o User  list  tab:  Once  logged  into  the  app,  the  user  will  be  able  to  see  
the   list   of   its   contacts,   which   can   be   selected   in   order   to   open   a  
new  conversation.  
o Conversation  tab:  The  screen  in  which  the  user  will  be  able  to  see  
the   messages   received   from   other   user   and   in   which   it   will   be   able  
to  write  and  send  new  messages.  
o Add  contacts  tab:  In  this  last  screen,  the  user  will  be  able  to  add  a  
new   user   to   his   contacts   by   writing   its   email   and   requesting   it   to  
the  server.  
 
3.3. SafeTime  screen  by  screen  
3.3.1. Login  screen  
Login  screen  is  the  one  that  will  enable  a  user  to  log  
into   their   already   registered   account   of   SafeTime  
app.  This  screen  has  5  main  components:  
A. App  title:  This  is  a  field  dedicated  to  show  the  
name  of  the  app,  developer  and  supervisor  of  
the  app.  
B. Text  fields:   In   this   fields   the   user   will   be   able  
to  write  its  email  and  password  in  order  to  log  
into  the  application.  
Figure  7:  Login  screen  
C. Login  button:  Will  execute  the  login  action.  
D. Register  button:  Will  open  the  “Register  screen”.  
 

 
13  
 

3.3.2. Register  screen  


In  this  screen  the  user  will  be  able  to  register  a  new  
account  in  SafeTime.  Its  main  components  are:  
A. Text   fields:   In   this   fields,   the   basic  
information  of  the  user  can  be  filled.  
B. Generate   keys   and   register   button:   By  
pressing   this   button,   the   registration   process  
will  start.  
 
 
Figure  8:  Registration  
screen  

3.3.3. User  list  tab  


This   screen   is   part   of   the   Multi-­‐fragment   Tabhost  
along   with   the   “conversation”   and   “add   contacts”  
tabs.  Here,  a  list  with  the  contacts  added  by  the  user  
is  shown.  The  main  components  in  this  screen  are:  
A. Tabhost  manager:  Used  by  the  user  in  order  
to  switch  tabs.  
B. User   list:  Here  the  list  of  the  users  added  by  
the   user   is   displayed.   If   the   user   taps   in   one   of  
Figure  9:  User  list  tab  
the  items  in  the  list,  the  conversation  window  
for  that  user  will  be  opened.  
 
 
 
 
 
 
 
 

 
14  
 

 
3.3.4. Conversation  tab  
It’s   the   window   in   which   the   user   will   write  
messages   to   another   user   previously   added   to   the  
user   list.   Plain   text   and   images   can   be   sent   to   the  
other  user.  Its  main  components  are:  
A. Tabhost  manager:  Used  by  the  user  in  order  
to  switch  tabs.  
B. User’s   name:  This  is  the  name  of  the  user  to  
whom  the  message  will  be  sent.  
C. Conversation   field:   In   this   space,   the  
conversation   between   the   two   users   will   be   Figure  10:  Conversation  
tab  
displayed.   Messages   focused   on   the   right   side  
are  messages  sent  by  the  user  and  the  ones  focused  on  the  left  are  the  
ones  received.  
D. Text  field:  In  this  field,  the  user  can  write  a  text  message  to  be  sent.  
E. Send   button:   By   pressing   this   button,   the   message   written   in   the  
“Text  field”  will  be  sent.  
F. Image  button:  When  this  button  is  pressed,  the  
phone’s  gallery  will  be  opened  so  that  the  user  
can  select  an  image  to  be  sent.  Once  selected,  a  
pop-­‐up   will   appear   with   the   following  
components:  
a. Image:   This   is   a   sample   of   the   image   to  
be  sent.    
b. Send  picture  button:  Once  this  button  is  
pressed,  the  image  message  will  be  sent.    
Figure  11:  Image  
  selection  window  

 
 

 
15  
 

3.3.5. Add  contacts  tab  


In  this  tab,  the  user  can  add  a  new  contact  to  its  list.  
This  can  be  done  by  writing  the  other  user’s  email  
and  sending  the  request.  Its  main  components  are:  
A. Tabhost   manager:   Used   by   the   user   in   order  
to  switch  tabs.  
B. Text   field:   In   this   field,   the   user   will   write  
the  email  of  the  user  that  will  be  added.  
C. Add   contact   button:   Once   this   button   is  
pressed,  the  request  will  be  sent.  
  Figure  12:  Add  contacts  tab  

 
3.4. Android  application  tasks  
The  Android  application  is  the  interface  in  which  a  user  can  interact  with  other  
users   and   manage   its   own   account   in   SafeTime.   The   application   is   designed   so   it  
has  two  simultaneous  running  threads:  
o Main   thread:   This   thread   is   the   one   that   can   be   visualized   by   the   user  
and  hence  can  interact  with  it.  Here  is  were  the  user  can  use  the  screens  
shown   in   the   last   chapter   which   consists   on   the   main   functionalities   of  
the   app.   A   number   of   Android   simultaneous   tasks,   called   Asynctasks[9]  
are  executed  for  various  purposes  like  sending  text  and  image  messages,  
sending   contact   requests,   encrypting/   decrypting   processes,   login   task  
and   registration   task   which   will   be   running   in   the   background   until   the  
task  at  hand  is  done.  
o Listening   thread:   This   thread   is   always   running   in   the   background.   Its  
main   purpose   is   to   scan   for   a   socket   connection   with   the   server,  
whenever   a   connection   is   established   between   the   application   and   the  
server,   this   thread   gets   in   charge   of   managing   upcoming   tasks   from   the  
server  and  if  needed,  send  tasks  to  the  server  (messages  or  requests).  
 

 
16  
 

3.5. Server  tasks  


The   server   can   be   considered   the   “manager”   of   the   information   flowing   between  
users   of   SafeTime.   It   will   receive   every   request   or   message   from   the   different  
users   and   either   process   it   or   resend   it   depending   on   the   situation.   In   order   to  
manage   all   this   different   tasks,   7   different   threads   were   developed   and   can   be  
seen  in  the  Appendix  A.  These  threads  are  the  following:  
o socketServer:  This  is  the  main  thread,  it  will  manage  messages  between  
users   and   contact   requests.   This   task   will   loop   infinitely   creating   a   socket  
connection  with  the  ports  assigned  to  the  users,  this  way,  it  can  listen  and  
send  information  to  the  user  with  which  is  connected  at  its  turn.  When  a  
message  or  contact  request  is  received,  the  task  will  store  the  information  
received   into   a   “pending   task   stack”   which   will   be   read   every   time   it  
opens   a   new   connection   with   a   user,   at   that   moment   it   will   check   if   it   has  
something  to  send  to  that  particular  user  and  will  also  listen  to  that  user  
in  order  to  receive  new  information.  
o TimerThread:   The   port   scanning   done   by   the   “socketServer”   thread   is  
managed  by  time  in  case  that  it  finds  no  connection  with  a  user.  In  order  
to   do   so,   this   thread   is   executed   every   time   a   new   connection   is  
established  in  “socketServer”,  this  will  initialize  a  timer  that  will  serve  as  
a  process  timer,  when  the  timer  is  over,  a  signal  is  sent  to  the  main  thread  
so   it   can   terminate   the   actual   connection   and   proceed   to   scan   the   next  
port.  
o NewUserThread:   This   thread   keeps   a   socket   connection   open   at   port  
9003   so   that   any   application   that   sends   a   registration   request   can  
communicate   with   the   server.   This   task   will   receive   that   registration  
request  and  send  a  response  back  to  the  user  and  then  go  back  to  wait  for  
a  new  request.  
o LoginUserThread:   The   way   this   thread   works   is   about   the   same   as   the  
“NewUserThread”,   that   means,   it   will   wait   for   a   request,   when   it   is  
received,  it  is  solved,  send  a  response  back  to  the  app  and  return  to  wait  

 
17  
 

for  a  new  request.  This  thread  will  manage  all  the  login  requests  on  port  
9001.  
o UpdateKeyThread:   When   a   user   logs   into   the   application   on   a   new  
device,  a  new  set  of  encryption  keys  need  to  be  generated.  This  thread  is  
the  one  in  charge  of  receiving  and  updating  in  the  database  the  new  key  
for  a  given  user.  
o TestThread:   This   thread   is   the   one   in   charge   of   receiving   the   message  
data   sent   from   users.   For   this   process,   the   “socketServer”   thread   receives  
the   command   from   the   application   to   receive   a   new   message   and   then,  
this   thread   will   be   ready   for   listening   and   store   the   message   into   the  
“pending  task  stack”.  
o SendMessageTask:   This   thread   will   send   a   message   stored   in   the  
“pending   task   stack”   and   send   it   to   its   destination.   For   this   process,   the  
“socketServer”  will  send  a  command  to  the  application  so  it  can  be  ready  
to  listen  to  this  thread  sending  a  given  message.  
 

4. Research  methods  
4.1. Development  tools  
4.1.1. Android  studio  1.1.0  
The   latest   version   of   Google’s   software   for   Android   developers.   Once  
installed,   developers   are   already   provided   with   the   Android   SDK   and  
therefore   ready   to   develop   new   applications.   Java   is   the   programming  
language   used   to   program   most   of   the   application,   since   the   graphic   user  
interface  is  programmed  in  xml.  
 
Testing  device  
To   test   the   application,   two   different   devices   are   used:   an   Android   virtual  
device  provided  by  the  Android  Studio  IDE  and  a  Samsung  Galaxy  S3  phone.  
The  specifications  for  both  devices  are:  
• Android  virtual  device  (AVD):  

 
18  
 

o Running  Android  4.4  


o API  level  19  
o Adjustable  screen  
• Samsung  Galaxy  S3:  
o Running  Android  4.3.1  
o API  level  15  
o 4.8  inches  screen  
 
4.1.2. Linux  server  
A  CPU  Linux  box  with  is  used  as  the  server  for  SafeTime.  This  computer  has  
the  following  specifications:  
o Operating  system:  Ubuntu  14.04  LTS  –  32-­‐bit  
o Memory:  3.9  GiB  
o Processor:  Intel  Core  2  Quad  CPU  !8400  @  2.66GHz  x  4  
o Disk:  134.9  GiB  
 
4.1.3. Eclipse  Mars  
Eclipse   Mars   is   the   latest   version   of   the   Eclipse   integrated   development  
environment  (IDE).  This  is  a  computer  application  that  provide  programmers  
with   a   friendly   environment   to   develop   software   in   various   programming  
languages   [10].     This   IDE   is   widely   used   by   programmers   due   to   its  
practicality  and  the  number  of  tools  and  libraries  that  can  be  used  in  order  to  
develop   complex   projects.   For   SafeTime   project,   this   IDE   will   be   used   to  
develop   the   server   application.   For   this,   Eclise   Mars   linux   version   was  
downloaded  and  installed  using  the  Ubuntu  software  centre.  
 
4.1.4. MongoDB  
MongoDB  is  an  open  source  document  database.  It’s  a  high  performance  and  
salable  database  that  lets  a  developer  create,  manage  and  develop  databases  
for   any   type   of   applications.   One   of   the   main   reasons   this   database   was  

 
19  
 

chosen   to   be   used   for   this   application   is   because   of   its   practical   libraries   in  


Java.   With   a   few   simple   java   code   lines,   a   wide   range   of   commands   can   be  
done  such  as:  
o Initialize  MongoDB  client:  
MongoClient  mongo  =  null;    
mongo  =  new  MongoClient("localhost",  27017);  

o Get  or  create  a  new  database:  


//  if  database  doesn't  exists,  MongoDB  will  create  it  for  you    
DB  db  =  mongo.getDB("safetimedb");              
/****  Get  collection  /  table  from  'testdb'  ****/      
//  if  collection  doesn't  exists,  MongoDB  will  create  it  for  you    
  DBCollection  table  =  db.getCollection("users");  

o Create   search   queries   and   cursors   to   search   for   objects   in  


database:  
BasicDBObject  searchQuery  =  new  BasicDBObject();    
searchQuery.put("email",  toUser);  
DBCursor  cursor  =  table.find(searchQuery);  

 
4.1.5. TeamViewer  
This  is  a  software  with  which  a  user  can  be  able  to  access  and  control  another  
computer   or   device   remotely.   In   order   to   do   so,   a   user   can   create   a   free  
account  and  register  their  different  devices  on  it  so  it  can  be  easily  connected  
at  any  given  time  by  selecting  the  device  from  the  “My  Computers”  list:  

 
20  
 

 
Figure  13:  TeamViewer  main  window  

Once  a  device  is  selected,  a  window  will  open  displaying  its  desktop:  

 
Figure  14:  TeamViewer  shared  screen  window  

By   enabling   the   “Remote   control”   feature,   the   user   is   able   to   interact   with  
that  computer  and  all  its  components.  
 
4.2. Encryption  algorithm  implemented  
Two   different   encryption   algorithms   were   considered   and   explained   for   this  
project,  AES  and  RSA  algorithms.  In  order  to  understand  them  an  get  to  test  their  
functionality,  both  were  developed  first  in  a  basic  way  in  C  code  (Appendix  D).  

 
21  
 

Once  considering  the  programming  complexity  and  functionality  in  terms  of  the  
project’s   objectives,   it   was   concluded   that   the   RSA   algorithm   is   the   best   option  
for   encrypting   messages   in   this   proyect.   The   factors   taken   into   account   in   this  
consideration  were  the  following:  
o Programming  complexity:  Both  algorithms  were  developed  and  it  could  
be  concluded  that  AES  is,  by  not  too  far,  more  complex  to  develop.  AES  has  
in   fact   more   stages   to   follow   in   order   to   generate   the   key,   but   those  
individual  stages  are  not  so  difficult  to  program  and  can  be  executed  in  a  
loop.  RSA  is  simpler,  but  its  mathematical  calculations  are  more  complex  
and   a   library   called   “BigIntegers”   needed   to   be   imported   in   order   to   be  
able  to  handle  such  big  numbers.  This  was  not  a  crucial  factor  in  the  final  
consideration.  
o Key   management:  AES  algorithm  will  generate  a  key  of  128  bits  (or  192  
or  256  depending  on  the  complexity)  for  every  data  block  of  128  bits  [11],  
while   RSA   will   generate   two   bigger   keys   based   on   two   prime   numbers  
with   a   length   of   1024   that   can   cypher   a   block   of   up   to   256   bytes.   Since  
SafeTime   is   an   instant   messaging   application,   generating   a   key   for   every  
block   of   128   bits   (16   bytes)   that   has   to   be   sent   along   with   the   cyphered  
message  in  order  to  be  decrypted  represents  a  problem  in  terms  of  data  to  
be  sent,  since  practically  the  double  of  the  data  size  would  be  needed  to  be  
sent   (data+key),   which   means   data   consumption   for   the   user   and  
encryption/decryption  processing  times,  since  for  every  message  every  16  
byte  block  needed  to  be  encrypted  generating  the  key,  which  would  take  
considerable   amount   of   processing   time,   as   well   as   in   the   decryption  
processes.   On   the   other   side,   RSA   would   generate   at   the   moment   a   new  
user  registers  or  logs  in  a  new  set  of  keys  which  will  stay  the  same  until  
the   user   logs   into   another   device,   meaning   that   the   generation   process,  
which  does  takes  time  (about  1  second),  will  be  done  once,  from  then  on  
just   the   encryption   and   decryption   processes   will   be   done   every   time   a  
message  is  sent  or  received,  making  this  algorithm  more  practical  for  this  
application.  This  was  a  crucial  factor  in  the  final  consideration.  

 
22  
 

o Data   block   size:   As   it   was   mentioned   before,   AES   cyphers   blocks   of   16  


bytes.  In  terms  of  plain  text  that  means  16  letters,  so  a  plain  text  message  
bigger  than  that  will  require  to  cypher  multiple  blocks  generating  multiple  
keys.  The  RSA  algorithm  considered  for  this  app  permits  to  cypher  a  data  
block  of  256  bytes  not  needing  to  generate  new  keys.  This  was  a  relevant  
factor  in  the  final  consideration.  
o Algorithm   security:   AES   is   the   actual   official   encryption   algorithm   used  
by  various  government  and  military  branches  around  the  world  including  
the   US   government   [12],   so   it   has   been   proven   as   the   most   robust  
encryption   algorithm   nowadays.   Still,   RSA   is   almost   as   secure   as   AES   or   at  
least,   in   terms   of   this   project,   more   than   enough   considering   that   an  
attempt  on  factoring  a  public  key  of  500  characters  in  order  to  figure  out  
the  private  key  could  take  4.2  x  1025  years  [8],  and  for  this  application,  a  
key   can   have   approximately   617   characters   depending   on   the   prime  
numbers.  
 

5. SafeTime  main  processes  


5.1. Registration  process  
Registration   is   the   process   in   which   a   user   will   be   able   to   activate   an   account   on  
SafeTime.  In  order  to  do  so,  a  form  will  have  to  be  filled  by  the  user;  pressing  the  
“Register”  button  in  the  application’s  main  screen  can  do  this.  
 

 
23  
 

 
Figure  15:  Login  to  Registration  flow  

 
This   form   has   to   be   filled   with   basic   information   about   the   user   in   the  
application:  
• Name:   it   will   be   used   to   display   the   name   of   the   registered   user   in   the  
contact  list  of  other  users  that  has  been  added.  
• Phone:  not  used  in  this  version  of  the  application,  it  is  asked  in  order  to  
be  able  to  be  used  in  future  versions  (scalability  of  the  application).  
• E-­‐mail:  is  the  main  id  of  the  user  used  for  internal  processing.  There  can  
only  be  one  user  per  email  address.  
• Password:  is  the  password  designated  by  the  user  in  order  to  be  able  to  
log  back  into  the  app  in  any  other  device.  
• Repeat   password:   it   is   used   to   confirm   that   the   password   typed   in   the  
“Password”  section  and  this  section  is  the  same  and  hence,  the  password  
the  user  intended  to  type.  
 
Validations:  
For  this  screen,  two  validations  were  developed  in  order  to  be  able  to  start  the  
registration  process  with  the  server.  The  first  validation  is  to  make  sure  that  all  
the   fields   on   the   form   are   filled,   if   this   condition   is   not   met,   a   toast   with   the  
message   “Fields   are   not   complete”   will   be   shown.   The   second   validation   is   for  

 
24  
 

the   passwords,   if   both   password   fields   do   not   match,   a   toast   with   the   message  
“Passwords  does  not  match”  will  be  shown.  
 
Process:  
The  registration  process  will  require  a  communication  between  the  application  
and  the  server.  With  the  information  provided  by  the  application,  the  server  will  
register   the   new   user   in   the   database   and   assign   a   port   number   for   it   and   will  
send  it  back  to  the  user.  The  detailed  process  on  how  it  goes  is  the  following:  
1) Server:   The   “NewUserThread”,   which   is   the   registration   thread,   is   already  
running  in  the  server  with  a  socket  set  on  port  number  #9000.  
2) Application:   The   user   fills   the   registration   form   with   all   its   details   and   taps  
the  “Generate  keys  and  register”  button.  
3) Application:   The   form   is   checked   by   the   app   to   see   if   the   form   is   filled  
correctly,  if  not,  a  toast  is  shown  to  the  user  saying  what  is  the  problem  so  he  
can  correct  it.  
4) Application:   Once   the   information   is   correctly   filled,   the   RSA   keys   are  
generated.  
5) Application:   A   connection   is   established   with   the   server   by   initializing   a  
socket  in  the  port  #9000.  
6) Application:   A   string   array   “UserInfo”   with   the   user’s   information   and   the  
public  RSA  key  is  initialized  and  sent  through  a  socket  so  it  can  be  read  by  the  
server.  “UserInfo”  will  be  filled  with  the  following  information:  
 
Table  2:  Registration  variables  

Variable   Description  
usrName   The  name  of  the  user.  
usrPhone   The  phone  number  of  the  user.  
usrEmail   The  email  of  the  user.  
usrPass   The  password  set  by  the  user.  
usrPKey   The  RSA  public  key  generated  for  the  user.  

 
25  
 

 
7) Server:   The   server   successfully   receives   the   “UserInfo”   string   array   through  
the  socket.  
8) Server:   The   server   searches   in   it’s   database   for   the   “usrEmail”   to   check   if   it  
already  exists  and  will  assign  a  CODE  to  be  sent  to  the  application:  
 
Table  3:  Registration  server  CODEs  

CODE   Description  
1   usrEmail  is  not  registered  
2   usrEmail  is  registered  
 
9) Server:  If  the  usrEmail  is  not  registered,  a  port  number  is  designated  to  that  
user,   this   port   is   assigned   sequentially   considering   what   was   the   last   port  
assigned   before   (i.e.   the   last   user   registered   port   was   #9005,   so   the   port  
assigned   to   this   user   will   be   #9006).   The   port   number   and   the   UserInfo   is  
then   inserted   to   the   “User   Info   Table”   in   the   server’s   database.   Finally   the  
port  number  and  the  CODE  are  sent  to  the  application  through  the  socket.  If  
the   usrEmail   is   already   registered,   only   the   CODE   will   be   sent   to   the  
application.  After  this,  the  server  returns  to  a  listening  state  waiting  for  other  
registration  request.  
10)  Application:  The  CODE  sent  by  the  server  is  received.  If  CODE  is  equal  to  “1”  
the  port  number  is  read  from  the  socket  and  added  to  the  “User  Info  Table”  in  
the  device’s  database  and  an  Intent  to  the  main  application  window  is  done.  
If  CODE  is  equal  to  “2”,  then  a  toast  with  the  text:  “Email  already  registered”  
is  displayed  in  the  screen  and  no  further  action  is  taken.  
 
Once   this   process   has   been   done   successfully,   the   new   registered   user   is   now  
able  to  use  SafeTime  application’s  functions  and  also  log  into  other  devices.  
 

 
26  
 

 
Figure  16:  Registration  flow  chart  

 
5.2. Login  process  
Once   a   user   has   been   registered   in   the   server   and   hence   its   basic   information  
stored   in   the   server,   that   user   will   be   able   to   log   into   his   account   by   using   the  
email   address   provided   in   the   registration   process   and   the   password   also   set.  

 
27  
 

The  server  will  be  in  charge  of  authenticate  the  user  comparing  that  information  
with  the  one  stored  in  its  database.  
 
Process:  
The  login  process  will  require  communication  between  the  application  and  the  
server.   For   this   task,   the   server   has   an   individual   thread   waiting   for   a   login  
request  at  all  times  in  a  socket  set  on  port  #9001.  The  process  in  which  a  user  in  
logging  into  its  account  is  the  following:  
1) Server:  The  “LoginThread”  which  is  the  thread  in  charge  of  the  login  requests,  
is  already  running  in  the  server  with  a  socket  set  at  the  port  #9001.  
2) Application:  The  user  fills  the  fields  shown  in  the  main  screen  of  the  SafeTime  
application:  
a. Username:   The   user’s   email   address   provided   during   the   registration  
process.  
b. Password:   The   user’s   password   provided   during   the   registration  
process.  
Once  the  information  is  written,  the  user  taps  the  “Login”  button.  
3) Application:   The   fields   are   checked   by   the   app   to   make   sure   they   are   filled  
correctly,  if  not,  a  toast  with  the  message  “Fields  are  not  complete”  is  shown.  
4) Application:  Once  the  form  is  correctly  filled,  a  connection  is  established  with  
the  server  by  initializing  a  socket  in  port  #9001.  
5) Application:   A   string   array   “LoginInfo”   is   initialized   with   the   basic  
information  needed  to  perform  the  login  task:  
 
Table  4:  Login  variables  

Variable   Description  
usrName   The  email  of  the  user  intending  to  log  in.  
usrPass   The  password  corresponding  to  that  user.  
 

 
28  
 

6) Server:  The  server  successfully  receives  “LoginInfo”  string  array  through  the  
socket.  
7) Server:   The   server   checks   on   its   database   for   the   user   with   the   email  
provided,  if  not  found,  the  user  will  be  notified  that  such  user  doesn’t  exist.  If  
found,  its  password  is  retrieved  and  compared  with  the  one  received  in  the  
socket.   If   the   passwords   match,   the   main   information   of   the   user   is   retrieved  
from   the   database   and   is   prepared   to   be   sent   to   the   application.   Depending  
on  the  scenario,  a  CODE  is  sent  to  the  application:  
 
Table  5:  Login  server  CODEs  

CODE   Description  
1   usrName  is  not  registered.  
2   Correct  usrPass  for  usrName.  
3   Incorrect  usrPass  for  usrName.  
 
8) Server:   The   CODE   is   sent   to   the   application   through   the   socket.   If   the   usrPass  
matched   for   the   usrName,   the   information   already   retrieved   from   the  
database  is  also  sent  through  the  socket.  
9) Application:   The   CODE   sent   by   the   server   is   received   through   the   socket.   If  
the   CODE   is   “1”,   a   toast   displaying   the   message   “User   not   registered”   is  
shown.   If   the   CODE   signal   is   “3”,   a   toast   with   the   message   “Incorrect  
password”  is  displayed.  If  CODE  is  “2”,  then  the  user  information  also  sent  by  
the  server  is  received.  
10)  Application:   A   new   set   of   RSA   keys   is   generated   by   the   application.   This   is  
done  because,  since  the  previous  private  key  generated  at  the  registration  (or  
past  login)  is  already  erased  from  the  device’s  database.  Since  the  user  is  able  
to   login   at   any   device   with   SafeTime   app   installed,   this   is   the   way   in   which  
the   user   can   be   sure   that   encrypted   communication   will   work   only   in   one  
device,   since   the   private   key   is   never   shared   with   the   server   and   hence  
cannot  be  saved.  

 
29  
 

11)  Application:   Once   the   new   keys   are   generated,   the   user   info   received   from  
the   server   and   the   keys   are   saved   into   the   “User   Info   Table”   in   the   device’s  
database.  
12)  Application:   The   public   key   generated   is   sent   to   the   server   using   the   active  
socket  and  an  Intent  to  the  main  application  window  is  done.  
13)  Server:   The   public   key   received   through   the   socket   is   used   to   update   the   key  
field  in  the  server’s  database  for  the  user  with  usrName.  After  this,  the  server  
returns  to  a  listening  state  waiting  for  other  login  request.  
 
Once  this  process  is  done  successfully,  the  user  will  be  logged  on  its  account  in  
the  SafeTime  app.  
 

 
30  
 

 
Figure  17:  Login  flow  chart  

 
 
5.3. Add  contact  process  
This  process  is  the  one  that  actually  lets  a  user  add  another  user  to  his  contact  
list,   hence   allowing   communication   between   both   users.   For   this   version   of  
SafeTime  app,  only  the  email  of  a  user  is  needed  in  order  to  add  it  to  the  contacts  

 
31  
 

list.   The   process   to   do   so   is   the   following,   given   the   case   in   which   a   User_1   is  
adding  User_2  to  his  contact  list:  
 
Process:  
1) App  User_1:   User_1   writes   User_2’s   email   in   the   available   field   in   the   “+Add  
Contact”  tab  and  taps  the  “Add  Contact”  button.  
2) App  User_1:   The   add   contact   task   is   added   to   the   “task   stack”   waiting   for   a  
“receiving”  signal  from  the  server.  
3) Server:  The  server’s  main  thread  is  scanning  the  user  ports  and  arrives  to  the  
User_1  port  turn.  
4) Server:  Given  the  case  that  in  its  own  task  stack  it  has  nothing  to  send  User_1,  
the   server   sends   a   “receiving”   signal   through   the   socket   initialized   on  
User_1’s  port  and  waits  for  a  response.  
5) App   User_1:   “receiving”   signal   is   detected   from   the   socket.   And   sends   a  
TaskID  of  “10”  back  to  the  server.  
6) App   User_1:   The   task   with   the   message   that   includes   the   following  
information  is  sent  to  the  server  through  an  active  socket  on  port  #9003:  
 
Table  6:  Add  contact  variables  

Variable   Description  
usrToAdd   The  email  of  the  user  that  wants  to  be  added  (User_2).  
 
7) Server:   TaskID   of   “10”   is   received,   so   the   server   knows   that   a   message   is  
about   to   arrive.   The   TaskID’s   will   let   know   the   server   what   kind   of   task   is  
about  to  receive:  
Table  7:  Add  contact  TaskIDs  

TaskID   Description  
10   Add  contact  task.  
11   Message  task.  
 

 
32  
 

 
8) Server:   Listens   to   the   “AddContactTask”   that   has   a   socket   initialized   in   port  
#9003  and  receives  the  “usrToAdd”  sent  by  User_1.  
9) Server:   It   searches   for   “usrToAdd”   email   in   the   “Users”   table   in   the   server’s  
database.   If   the   user   is   not   found,   a   CODE   will   be   sent   to   the   user   notifying  
that   the   user   does   not   exist.   If   it   is   actually   found,   then   a   different   CODE  
confirming  the  existence  of  the  user  is  sent:  
 
Table  8:  Add  contact  server  CODEs  

CODE   Description  
1   User  exists  
2   User  not  found  
 
10)  Server:  CODE  signal  is  sent  to  User_1.  If  the  user  was  found,  the  information  
about  that  user  (in  this  case  User_2)  is  retrieved  from  the  server’s  database  
and  is  sent  to  User_1  through  the  port  #9003  socket.  
11)  Server:  Using  the  number  of  the  active  port  in  the  main  thread  (User_1’s  port  
in   this   case),   the   server   retrieves   the   information   of   the   User_1   and   creates   a  
new  task  to  send  the  User_1’s  information  to  User_2.  The  information  to  be  
sent  is  the  following:  
Table  9:  Add  contact  server  variables  

Variable   Description  
11   TaskID  for  “Add  contacts”.  
usrName   Name  of  the  user  to  be  added  to  contact  list.  
usrEmail   Email  of  the  user  to  be  added  to  contact  list.  
usrKey   Public  key  of  the  user  to  be  added  to  contact  list.  
 
12)  App  User_1:   User_1   receives   the   CODE   signal.   If   its   value   is   a   “2”,   a   toast   with  
the  message  “User  not  found”  is  displayed  in  the  screen  and  no  further  action  
is  taken.  If  the  CODE  was  “1”,  then  the  User_2’s  info  is  read  from  the  socket.  

 
33  
 

13)  App   User_1:   The   information   received   by   the   server   is   now   stored   in   the  
“contacts”  table  in  the  device’s  database.  
14)  App  User_1:  The  contact  list  window  is  refreshed.  
15)  Server:   The   server   scans   through   ports   until   it   reaches   User_2’s   port.   Since   it  
has   a   task   to   send   to   User_2,   it   sends   a   “listen”   signal   through   the   socket  
initialized  with  User_2’s  port  number.  
16)  App   User_2:   “ServerThread”   is   looping   until   it   receives   a   signal   from   the  
server.  In  this  case,  it  receives  a  “listen”  signal.  
17)  App  User_2:  Sends  “acknowledge”  signal  to  the  server.  
18)  Server:   Once   received   the   “acknowledge”   signal,   the   server   sends   the  
User_1’s  info  task  to  User_2.  
19)  App   User_2:   User_1’s   info   is   received   from   the   server   and   is   stored   in   the  
“contacts”  table  in  the  device’s  database.  
20)  App  User_2:  The  contact  list  window  is  refreshed.  
 
Is  important  to  point  out  that  in  this  version  of  SafeTime,  when  User_1  requests  
to   add   User_2   to   its   contact   list,   the   server   will   provide   User_1   with   User_2’s  
information  and  at  the  same  time  will  provide  User_2  with  User_1’s  information  
in  order  to  achieve  communitation  between  both  users.  
 

 
34  
 

 
Figure  18:  Add  contact  flow  diagram  

 
 
5.4. Encryption  process  
Encryption   is   the   core   and   most   important   part   of   SafeTime   application   (with  
Decryption).  This  process  is  the  responsible  of  using  the  RSA  public  key  assigned  
to  the  user  to  whom  the  message  is  going  to  be  sent  to  cypher  it  and  therefore  
protect   it   from   potential   intruders   or   sniffers   trying   to   read   them.   There   are   two  
possible   types   of   messages   developed   for   SafeTime,   plain   text   or   images.   For  

 
35  
 

both  cases  the  main  process  of  encryption  is  the  same,  but  the  way  in  which  the  
size  of  the  data  is  treated  is  different.  Given  that  the  amount  of  data  that  can  be  
encrypted  with  the  RSA  algorithm  is  256  bytes,  images  have  to  be  divided  into  
sets   of   bytes   in   order   to   be   able   to   encrypt   them   but   text   messages   (with   256  
characters   or   less)   can   be   encrypted   in   the   same   block.   Assuming   a   User_1   is  
sending  a  message  to  User_2,  the  process  to  do  so  is  the  following:  
 
Plain  text:  
1. User_1  writes  a  message  for  User_2  in  the  text  field  and  taps  “SEND”.  
2. The  string  is  read  from  the  text  field  and  is  converted  to  a  byte  array  by  
using  the  “getBytes()”  function  in  java.  
3. The  byte  array  obtained  is  used  to  initialize  a  new  BigInteger  “M”.  
4. By   using   “M”   and   the   public   key   of   User_2,   the   message   is   encrypted  
giving  as  a  result  the  cypher-­‐text  “C”.  
5. C   is   the   converted   to   a   byte   array   using   the   function   “toByteArray()”   in  
the  BigInteger  library.  
6. This  byte  array  is  now  ready  to  be  sent  to  the  SafeTime  server  and  hence,  
to  User_2.  
 
Image:  
1. User_1   selects   an   image   from   the   gallery   and   taps   “SEND   PICTURE”   in   the  
confirmation  window.  
2. The   image   is   taken   as   a   drawable,   which   will   be   converted   to   a   Bitmap  
“B”.  
3. B   is   then   compressed   in   a   JPEG   format   into   a   ByteArrayOutputStream  
“stream”.  
4. “stream”  is  now  converted  to  byte  array  “I”  by  using  the  “toByteArray()”  
function.  
5. Since   “I”   is   bigger   than   256,   the   whole   byte   array   is   divided   into   blocks   of  
255   bytes   (as   a   safe   size)   and   that   are   introduced   in   order   into   an  
ArrayList  “L”.  

 
36  
 

6. Each  byte  array  goes  through  the  encryption  process  individually:  


6.1.  Byte  array  is  used  to  initialize  a  new  BigInteger  “M”.  
6.2. If   “M”   is   negative,   it   is   multiplied   by   -­‐1   in   order   to   make   it   positive  
and  a  sign  variable  “s”  is  set  to  “1”.  If  “M”  is  positive,  it  is  left  as  it  is  
and   the   sign   variable   “s”   is   set   to   “2”.   This   is   done   because   the   RSA  
algorithms   permits   encryption   on   numeric   values   greater   than   zero  
and   less   than   the   “N”   value   of   the   key.   The   sign   variable   “s”   will   let  
User_2   know   if   the   BigInteger   value   obtained   after   the   decryption  
process   is   supposed   to   be   positive   or   negative,   so   it   can   do   the  
calculations  necessary  to  make  the  value  be  the  same  as  it  was  before  
encryption.  
6.3. By   using   “M”   and   the   public   key   of   User_2,   M   is   encrypted   giving   as   a  
result  a  cypher-­‐section  “C”.  
6.4. “C”   is   then   converted   to   a   byte   array   using   the   function  
“toByteArray()”  in  the  BigInteger  library.  
6.5. A  byte  with  the  value  “s”  is  added  at  the  end  of  the  byte  array.  
6.6. This  byte  array  is  then  replaced  in  the  ArrayList.  
7. Once  every  byte  array  in  the  ArrayList  is  encrypted,  the  cyphered  image  
is  ready  to  be  sent  to  the  server  and  hence,  to  User_2.  
The   encrypted   message   is   now   ready   to   be   sent   to   the   server,   so   the   following  
task  ArrayList  is  added  to  the  tasks  queue  in  the  SafeTime  main  thread:  
 
Table  10:  Encryption  task  ArrayList  

Field   Description  
“11”   Id  given  to  the  message  task.  
User_2  email   Email  of  the  user,  which  will  receive  the  
message.    
message   The  data  to  be  sent  to  the  receiving  user:  
• If  plain  text    -­‐>    byte  array.  
• If  Image                -­‐>    ArrayList  

 
37  
 

 
Figure  19:  Encryption  process  flow  diagram  

 
 
5.5. Decryption  process  
Decryption  is  the  process  by  which  a  user  decrypts  the  cypher-­‐text  or  cyphered  
image  received  from  another  user.  This  message,  as  explained  in  the  encryption  

 
38  
 

process,   can   be   either   plain   text   or   an   image.   The   type   can   be   identified  
depending  on  the  type  of  data  received,  a  byte  array  in  case  of  plain  text  or  an  
ArrayList  of  byte  arrays  in  case  of  an  image  and  both  types  are  treated  differenty  
due   to   the   amount   of   information   they   carry.   Continuing   with   the   scenario  
previously   explained   for   the   encryption   process,   a   User_2   is   receiving   a   message  
from  User_1:  
 
Plain  text:  
1. User_2  receives  a  cyphered  message  “M”  (byte  array)  from  the  server.  
2. A  BigInteger  “m”  is  initialized  with  the  byte  array  “M”.  
3. By  using  “m”  and  User_2’s  private  key,  the  message  is  decrypted  into  the  
BigInteger  number  “d”.  
4. “d”   is   now   converted   into   a   deciphered     byte   array   “D”   by   using   the  
“toByteArray()”  function  in  the  BigInteger  library.  
5. “D”   will   finally   be   used   to   initialize   a   new   String   that   will   be   the  
deciphered  message  as  the  User_1  wrote  it.  
6. The  conversation  window  with  User_1  is  now  refreshed.  
 
Image:  
1. User_2  receives  a  cyphered  message  “M”  (ArrayList)  from  the  server.  
2. Each   byte   array   in   the   ArrayList   goes   through   the   decryption   process  
individually:  
2.1. The   last   byte   of   the   byte   array   is   removed   and   set   into   the   variable  
“t”.   This   byte   will   determine   whether   the   BigInteger   obtained   after  
decryption  must  be  negative  or  not.  
2.2. A  BigInteger  “m”  is  initialized  using  the  rest  of  the  byte  array.  
2.3. By   using   “m”   and   User_2’s   private   key,   the   section   “m”   is   decrypted  
into  the  BigInteger  number  “D”.  
2.4. Depending   on   the   value   of   “t”,   “D”   will   change.   If   “t”   is   “1”,   then   “D”   is  
multiplied  by  -­‐1.  If  “t”  is  “2”,  then  “D”  is  left  as  it  is.  

 
39  
 

2.5. “D”  is  now  converted  into  a  byte  array  by  using  the  “toByteArray()”  
function   in   the   BigInteger   library.   At   this   point,   in   some   cases,   the  
byte   array   results   to   be   1   byte   shorter   than   what   it   should   be   (254  
bytes   instead   of   255).   This   happens   because   at   the   encryption  
process  made  by  User_1,  the  byte  array  that  was  converted  into  the  
BigInteger  that  was  encrypted  started  with  a  0  as  it  first  byte,  which  
resulted   in   a   BigInteger   number   with   a   leading   zero,   which   is  
neglected   by   the   initialization.   So   in   order   to   compensate   for   it,   every  
time  a  byte  array  falls  short  by  a  byte,  a  ‘0’  byte  is  added  as  the  first  
value  of  the  byte  array.  
2.6. This  byte  array  is  the  replaced  in  the  ArrayList.  
3. Once  all  the  sections  has  been  decrypted,  all  byte  arrays  are  padded  one  
next   to   the   other   in   one   big   byte   array.   This   is   the   byte   array  
corresponding  to  the  image  sent  by  User_1.  
4. This  big  byte  array  is  used  to  initialize  a  drawable.  
5. The  conversation  window  with  User_1  is  now  refreshed.  
 

 
40  
 

 
Figure  20:  Decryption  flow  diagram  

 
 
5.6. Message  send/receive  process  
Messaging   is   the   whole   point   of   SafeTime   app.   It   provides   a   communication  
between  two  users  of  the  application  in  a  secure  manner  by  using  each  other’s  
public  key  to  encrypt  and  their  own  private  key  to  decrypt  the  received  message.  
In  this  process,  the  server  works  as  a  conduit  for  the  two  users,  it  doesn’t  read  or  

 
41  
 

stores   the   message   received,   but   just   resends   it   to   the   intended   user.   For   this  
process,   because   of   the   density   of   information   that   can   be   sent   (in   the   case   of  
images)  two  different  ports  were  assigned  in  order  to  let  the  server  receive  (port  
#8999)   and   send   (port   #8998)   messages.   The   only   task   of   these   threads   is   to  
receive   or   send   messages   from   and   to   the   applications,   this   way,   a   potential  
problem  regarding  saturation  of  ports  is  prevented.  
 
Process:  
This  process  describes  the  communication  between  two  users,  User_1  is  sending  
a  message  to  User_2  like  the  example  below:  
 

 
Figure  21:  Message  send  flow  

 
1) App   User_1:   A   message   (text   or   image)   is   introduced   and   in   the   User_2  
conversation  window  and  the  “Send”  button  is  tapped.  
2) App  User_1:   The   message  goes  through  the  encryption  process  using  User_2’s  
public   key   and   a   message   task   is   added   to   the   “task   stack”   in   the   app   and  
waits   for   a   “receiving”   signal   from   the   server.   Also   the   sent   message   is  
displayed  on  the  conversation  window  with  User_2.  
3) Server:  The  server’s  main  thread  is  scanning  the  user  ports  and  arrives  to  the  
User_1  port  turn.  

 
42  
 

4) Server:  Given  the  case  that  in  its  own  task  stack  it  has  nothing  to  send  User_1,  
the   server   sends   a   “receiving”   signal   through   the   socket   initialized   on  
User_1’s  port  and  waits  for  a  response.  
5) App   User_1:   “receiving”   signal   is   detected   from   the   socket.   And   sends   a  
TaskID  of  “11”  back  to  the  server.  
6) App   User_1:   The   task   with   the   message   that   includes   the   following  
information  is  sent  to  the  server  through  an  active  socket  on  port  #8999:  
Table  11:  Message  sending  task  variables  

Variable   Description  
“M”  or  “I”   The  type  of  message  that  will  be  sent:  
M:  text  message.  
I:  image.  
encMessage   The  encrypted  message  to  be  sent.  
toUser   The  email  of  the  user  to  whom  the  message  is  destined  (User_2).  
fromUser   The  email  of  the  user  that  sends  the  message  (User_1)  
 
7) Server:   TaskID   of   “11”   is   received,   so   the   server   knows   that   a   message   is  
about   to   arrive.   The   TaskID’s   will   let   know   the   server   what   kind   of   task   is  
about  to  receive:  
Table  12:  Messaging  server  TaskID  

TaskID   Description  
10   Add  contact  task.  
11   Message  task.  
 
8) Server:   The   message   task   is   received   through   the   “receiveMessageTask”  
initialized   in   port   #8999   and   a   new   server   message   task   is   initialized   with  
the   port   number   of   the   User_2.   That   information   is   retrieved   from   the  
server’s  database.  Then  the  server  returns  to  the  “scanning  ports”  loop.  

 
43  
 

9) Server:   The   server   arrives   the   port   number   of   User_2.   It   finds   that   there   is  
one   pending   task   for   User_2   and   sends   through   the   socket   initialized   with  
User-­‐2’s  port  number  a  “listening”  signal.  
10)App   User_2:   User_2   is   constantly   scanning   its   port   for   an   active   connection  
with   the   server.   If   a   connection   is   not   found,   it   keeps   looping.   If   a   connection  
is  found,  it  reads  the  signal  sent  by  the  server:  
Table  13:  Message  receiving  task  variables  

Signal   Description  
“1”   “listening”  signal,  the  server  will  send  data  to  the  application  and  it  
must  be  ready  to  receive  it.  
“2”   “receiving”   signal,   the   server   has   nothing   to   send   and   will   wait   for  
the  application  to  send  a  task  if  there  is  one.  
No  signal   Nothing  happens,  the  server  will  continue  scanning  ports.  
 
11)  App   User_2:   “listening”   signal   is   received   from   the   server.   Initialized  
connection   with   socket   in   port   #8998   and   sends   an   “acknowledgement”  
signal  to  the  server  through  the  socket  initialized  with  User_2’s  port.  
12)  Server:   “acknowledgement”   signal   is   received   from   User_2.   Now   the   server  
will   start   transmitting   the   message   through   the   “sendMessageThread”  
initialized  in  port  #8998.  
13)  App   User_2:   Message   is   received   from   the   server   through   the   socket  
previously  initialized  in  port  #8998  with  the  information  of  from  whom  the  
message  was  sent  (User_1)  and  the  type  (image  or  plain  text).  
14)  App  User_2:  The  message  goes  through  the  decryption  process  using  User_2’s  
private  key.  
15)  App  User_2:  The  decrypted  message  is  displayed  in  the  conversation  window  
with  User_1.  
 

 
44  
 

 
Figure  22:  Message  send/receive  flow  diagram  

 
 
6. SafeTime  tests  
A   number   of   tests   were   made   in   order   to   ensure   the   functionality   of   the   application.  
Some   of   them   to   test   the   RSA   algorithm   for   encryption   and   decryption,   some   for   the  
fragmentation  and  rebuild  of  images  and  others  for  communication.  

 
6.1. Test  1:  Key  generation,  Encryption  and  Decryption  

 
45  
 

For   this   application,   RSA   keys   must   be   generated   in   order   to   ensure   secure  
communication   as   well   as   the   encryption   and   decryption   processes.   One   of   the  
most   notorious   concerns   is   the   time   it   takes   to   generate   such   keys,   encrypting  
and  decrypting  messages,  so  in  order  to  figure  that  out,  the  following  code  was  
used  to  generate  both  public  and  private  keys:  
//Generate  a  random  number  and  look  for  two  prime  numbers  of  "bitlength"  size  
               r  =  new  Random();  
               firstPrime  =  BigInteger.probablePrime(bitlength,  r);  
               secondPrime  =  BigInteger.probablePrime(bitlength,  r);  
 
               //First  we  need  to  obtain  the  number  N  =  firstPrime*secondPrime  
               N  =  firstPrime.multiply(secondPrime);  
 
               //use  Euler  totient  function  to  obtain  phi  (phi(N))  
               BigInteger  phi  =  N.subtract(firstPrime.add(secondPrime).subtract(BigInteger.ONE));  
 
               //Obtain  a  prime  number  between  0  and  N  (should  be  coprime  with  phi)  
               e  =  BigInteger.probablePrime(bitlength/2,  r);  
 
               //Making  sure  that  e  is  coprime  with  N  
               while  (phi.gcd(e).compareTo(BigInteger.ONE)  >  0  &&  e.compareTo(phi)  <  0  )  {  
                       e.add(BigInteger.ONE);  
               }  
 
               //Obtain  the  private  key  by  calculating  e  inverse  module  of  phi  
               d  =  e.modInverse(phi);  
 
               System.out.println("Finish  key  generation");  
               keys[0]  =  N;  
               keys[1]  =  e;  
               keys[2]  =  d;  
 
This   keys   were   obtained   by   generating   two   prime   numbers   with   a   bitlength   of  
1024.  
Encryption  of  a  standard  message  of  a  size  of  256  or  less  bytes  is  done  with  the  
following  code:  
public  byte[]  messageEncryption(byte[]  M){  
               BigInteger  N  =  new  BigInteger(key.split("-­‐")[0]);  
               BigInteger  e  =  new  BigInteger(key.split("-­‐")[1]);  
 
               BigInteger  encryptedMsg  =  new  BigInteger(M);  
               if  (encryptedMsg.signum()  !=  1){  
                       encryptedMsg  =  encryptedMsg.multiply(BigInteger.valueOf(-­‐1));  
                       encryptedMsg  =  encryptedMsg.modPow(e,  N);  
                       byte[]  encMsgBytestemp  =  encryptedMsg.toByteArray();  
                       byte[]  encMsgBytes  =  new  byte[encMsgBytestemp.length+1];  
                       for  (int  i  =  0;  i<encMsgBytes.length;  i++){  
                               if  (i  ==  encMsgBytes.length-­‐1){  
                                       encMsgBytes[i]  =  (byte)1;  
                               }else{  

 
46  
 

                                       encMsgBytes[i]  =  encMsgBytestemp[i];  
                               }  
                       }  
                       return  encMsgBytes;  
               }else{  
                       encryptedMsg  =  encryptedMsg.modPow(e,  N);  
                       byte[]  encMsgBytestemp  =  encryptedMsg.toByteArray();  
                       byte[]  encMsgBytes  =  new  byte[encMsgBytestemp.length+1];  
                       for  (int  i  =  0;  i<encMsgBytes.length;  i++){  
                               if  (i  ==  encMsgBytes.length-­‐1){  
                                       encMsgBytes[i]  =  (byte)2;  
                               }else{  
                                       encMsgBytes[i]  =  encMsgBytestemp[i];  
                               }  
                       }  
                       return  encMsgBytes;  
               }  
 
Decryption  of  a  standard  message  of  256  bytes  or  less  is  done  with  the  following  
code:  
public  byte[]  messageDecryption(byte[]  D){  
               byte[]  msgToDecrypt  =  new  byte[D.length-­‐1];  
               for  (int  i  =  0;  i<D.length-­‐1;  i++){  
                       msgToDecrypt[i]  =  D[i];  
               }  
               System.out.println(""+D[D.length-­‐1]);  
               BigInteger  encryptedMsg  =  new  BigInteger(msgToDecrypt);  
 
               encryptedMsg  =  encryptedMsg.modPow(d,  N);  
 
               if  (D[D.length-­‐1]  ==  (byte)1){  
                       encryptedMsg  =  encryptedMsg.multiply(BigInteger.valueOf(-­‐1));  
               }  
 
               return  encryptedMsg.toByteArray();  
               //return  (new  BigInteger(D)).modPow(d,  N).toByteArray();  
       }  
 
Result:   The   following   table   of   processing   times   was   obtained   by   running   this  
codes  on  the  Android  Studio  simulator:  
 
Table  14:  RSA  processing  times  

Process   Processing  time  (seconds)  


Key  generation   0.252  
Encryption  process   0.008  
Decryption  process   0.018  
 

 
47  
 

Given  the  results  on  this  table,  it  can  be  concluded  that  the  processes  are  done  in  
a  more  than  acceptable  time.  
 
6.2. Test  2:  TCP  socket  communication  
In   order   to   establish   communication   between   the   android   application   and   the  
server,   TCP   sockets   were   developer.   So   communication   between   two   points   was  
tested,   this   was   done   by   programming   a   Server   socket   and   a   Client   socket   as  
follows:  
• Server  socket:  
import java.io.*;
import java.net.*;

public class SOK_SERVER {

public static void main(String[] args) throws Exception{


SOK_SERVER SERVER = new SOK_SERVER();
SERVER.run();
}

public void run() throws Exception{


//create a ServerSocket for port 1500
ServerSocket srvrSocket = new ServerSocket(1500);
//open socket connection
Socket sock = srvrSocket.accept();
InputStreamReader IR = new InputStreamReader(sock.getInputStream());
BufferedReader BR = new BufferedReader(IR);

//check for messages received from the socket


String MESSAGE = BR.readLine();
System.out .println(MESSAGE);

if(MESSAGE != null){
//if a message is received, print in console
PrintStream PS = new PrintStream(sock.getOutputStream());
PS.println("MESSAGE recieved");
}
}

}  

 
• Client  socket:  
import java.io.*;
import java.net.*;

public class SOK_CLIENT {

public static void main(String[] args) throws Exception{


SOK_CLIENT CLIENT = new SOK_CLIENT();
CLIENT.run();
}

public void run() throws Exception{


//create a socket for port 1500 at the Localhost
Socket sock = new Socket("localhost", 1500);
//print a message to be sent to the server
PrintStream PS = new PrintStream(sock.getOutputStream());
PS.println("Hello! I am Client_1");

//initialize reading
InputStreamReader IR = new InputStreamReader(sock.getInputStream());
BufferedReader BR = new BufferedReader(IR);

 
48  
 

//look for messages that might be received by the server


String MESSAGE = BR.readLine();
System.out .println(MESSAGE);
}
}  

 
Result:   communication   was   successful   as   shown   in   the   logs   presented   on  
console.  
• ServerSocket  console:  

 
Figure  23:  ServerSocket  console  screen  

The  message  sent  by  the  Client  socket  was  received  by  the  server,  and  the  
server  sent  an  acknowledgment  message.  
• ClientSocket   console:  

 
Figure  24:  ClientSocket  console  screen  

Client   sent   the   message   “Hello!   I   am   Client_1”,   the   server   received   the  
message  and  sent  a  message  “MESSAGE  received”  in  response.  
6.3. Test  3:  Encryption  and  decryption  of  text  with  one  set  of  
keys  
This  test  consists  on  generating  a  set  of  keys  using  the  RSA  algorithm  in  order  to  
test   its   actual   functionality.   First   the   RSA   keys   “A”   in   the   Appendix   C   were  
generated.  
Now,  using  the  public  key  A,  the  message  “hello  bruce”  written  by  a  user  will  be  
encrypted  and  sent  to  the  server:  

 
49  
 

 
Figure  25:    Sender  text  message  

 
The   cyphered   message   received   by   the   server   represents   a   lot   of   characters   that  
makes  no  sense  as  shown  in  this  print  from  the  server’s  console:  

 
Figure  26:  Server  log  when  a  text  message  is  received  

 
Here,  the  information  about  the  sender  and  recipient  can  be  seen  as  well  as  the  
cyphered   message,   at   the   end   of   this   print,   it   can   be   seen   that   the   message   is  
being   sent   to   the   recipient,   who   will   receive   the   message   and   will   decrypt   it  
using  the  private  key  A.  

 
50  
 

 
Figure  27:  Received  decrypted  text  message  

 
Result:  The  message  encrypted  is  received  by  the  other  user  and  is  successfully  
decrypted  so  it  can  be  readable  again,  this  works  well  because  the  pair  of  keys  
generated  are  the  ones  that  are  used,  that  means,  that  the  public  key  generated  
will  have  only  one  way  to  decrypt  which  is  the  private  key.  
 
6.4. Test   4:   Encryption   and   decryption   of   text   with   two  
different  set  of  keys  
This   test   is   done   in   just   about   the   same   way   the   last   one   is   done,   but   its   main  
objective   is   to   show   what   will   happen   if   a   message   encrypted   with   one   public  
key  is  tried  to  be  decrypted  with  a  private  key  not  corresponding  to  it.  For  this,  
two  different  set  of  keys  in  the  Appendix  C  are  used.  
We   now   get   the   message   “hello   bruce”   just   like   it   was   done   in   Test   1.   The  
message  is  then  encrypted  using  the  Public  key  A  and  is  sent  to  the  server  and  
later  on  is  received  by  the  other  user.  At  this  point,  instead  of  using  the  Private  
key  A,  which  is  the  one  corresponding  to  the  public  key  used,  Private  key  B  will  
be  used  for  decryption  and  the  result  is  the  following:  

 
51  
 

 
Figure  28:  Received  decrypted  message  with  wrong  key  

 
Result:   As   it   can   be   seen,   the   message   was   not   successfully   decrypted.   This  
happens  because  the  both  public  and  private  keys  must  be  generated  in  the  same  
process   using   the   same   prime   numbers,   if   this   is   not   done   this   way   the  
calculation   done   at   the   decryption   process   will   return   a   wrong   number   and  
hence  a  wrong  set  of  bytes  that  will  end  up  in  a  group  of  characters  that  make  no  
sense  as  it  can  be  seen  in  Figure  28.  
 
6.5. Test   5:   Encryption   and   decryption   of   images   with   one  
set  of  keys  
The   objective   of   this   test   is   to   show   the   functionality   of   the   image   encryption  
process.   For   this,   the   same   set   of   keys   in   Test   1   is   going   to   be   used.   Using   the  
public  key,  the  image  chosen  to  be  sent  is  encrypted  and  sent  to  the  server:  

 
52  
 

 
Figure  29:  Sender  image  message  

Since   is   an   image,   a   number   of   different   encrypted   blocks   of   255   bytes   are   going  
to  be  sent  to  the  server  in  order  to  be  sent  to  the  receiving  user.    
 

 
Figure  30:  Server  log,  receiving  image  

Once   the   end   user   receives   those   packets,   they   go   through   the   decryption  
process  using  the  private  key  and  reassemble  of  the  image  to  finally  display  it  on  
the  conversation  window:  

 
53  
 

 
Figure  31:  Received  image  message  

Result:   The   image   sent   by   the   sending   user   was   received   successfully   by   the   end  
user,   which   means   that   both   processes   of   encryption   and   decryption   worked  
perfectly.   Also   the   process   of   segmentation   and   reassemble   of   the   image   was  
successful.  
 
6.6. Test   6:   Encryption   and   decryption   of   images   with   two  
different  set  of  keys  
Using  the  two  set  of  keys  in  Test  2,  the  same  process  as  in  Test  3  is  repeated,  but  
this   time   the   encryption   process   is   done   with   the   public   key   A   by   the   sending  
user  and  is  later  decrypted  by  the  end  user  using  the  private  key  B:  

 
54  
 

 
Figure  32:  Received  corrupted  image  

Result:   The   blank   space   at   the   bottom   of   the   list   in   Figure   31   shows   that   the  
image  was  not  successfully  displayed.  This  happened  because  at  the  moment  of  
decryption  a  private  key  not  corresponding  to  the  public  key  used  for  encryption  
was   used.   Because   of   that,   the   correct   pattern   of   bytes   for   the   image   at   the  
process   of   reassemble   was   not   obtained;   hence   the   drawable   could   not   be  
assembled  and  resulted  in  a  corrupted  file.  
 
7. Discussion  
7.1. Achievements  of  SafeTime  
At   the   beginning   of   this   project,   encryption   of   just   plain   text   messages   was  
considered.  Since  that  task  could  be  completed  promptly,  the  idea  of  encrypting  
files  like  images  was  considered.  Since  an  image  was  a  type  of  file  that  could  be  
considered  a  little  more  complex  than  text  files,  this  became  the  goal  from  then  
on.   After   some   time   working   on   the   processes   to   encrypt/decrypt   images  
explained   previously,   this   could   be   achieved   proving   that   encryption   of   images  
using  RSA  algorithm  based  on  the  fragmentation  of  an  image  was  possible.  This  
proves  that  also  files  can  be  encrypted  and  sent  in  a  secure  way  to  other  peers  
guaranteeing  confidentiality  of  files  while  they  are  transmitted.  

 
55  
 

Also,   with   the   success   of   this   application,   it   could   be   demonstrated   that  


encrypted  communication  can  be  fast  and  not  much  heavier  in  terms  of  data  size  
than   conventional   communication   which   will   be   appealing   for   the   actual   cyber  
security  concerns  [13].  
 
7.2. Limitations  and  upgrades  
In   this   version   of   SafeTime,   some   limitations   have   been   detected   in   terms   of  
communication,  development  and  design:  
o Amount   of   users   supported:   Because   of   its   port   based   socket  
communication,  SafeTime’s  server  has  a  limited  number  of  ports  for  its  ip  
address.   For   TCP   communication,   the   ports   in   a   range   from   32768   to  
65535  are  the  ones  considered  as  “Ephemeral  ports”  which  are  the  ports  
typically  used  for  client  communication.  This  port  connections  are  short  
lived   and   will   exist   as   long   as   the   client   needs   its   service   [14].   This   will  
leave  SafeTime  with  a  maximum  capacity  32,767  users.  
This   can   be   upgraded   by   changing   the   socket   communication   model   for   a  
more   scalable   model   that   can   permit   an   exponentially   bigger   amount   of  
users   to   register   and   send   requests   and   messages   to   the   server   without  
depending  on  a  single  port  connection.  
o Data  size:  Socket  communication  can  get  saturated  due  to  the  amount  of  
information  that  is  being  sent.  In  case  of  images,  which  are  substantially  
bigger   than   plain   text,   saturation   of   ports   in   the   middle   of   the  
transmission  is  possible,  truncating  communication  and  making  possible  
the  lost  of  data.  
This   can   be   fixed   with   the   same   solution   as   the   last   point,   by   using  
another  communication  model.  
o Limitation   of   file   types:   At   the   moment,   the   app   can   send   plain   text   and  
image  messages,  but  with  the  code  already  developed,  inclusion  of  other  
file  types  such  as  .txt,  .doc  or  even  .pdf  can  be  possible  in  a  way  similar  as  
the   images.   With   this   same   principle,   but   with   more   complex   features  

 
56  
 

developed   in   Android,   encrypted   half   duplex   communication   [15]   might  


be  possible.  Full  duplex  would  be  less  likely  due  to  the  processing  times  
for   encrypting   data   which   will   not   permit   a   real   simultaneous  
communication.  
o Application   design:   A   more   user   friendly   design   of   the   app   with   more  
appealing  user  interface  can  be  done  with  more  time  of  development.  
 
7.3. SafeTime’s  use  for  industry  
Companies   managing   and   working   on   projects   that   are   competing   with   others  
and  need  to  maintain  a  secure  communication  between  its  developers,  managers  
and   executives   in   order   to   prevent   a   potential   intruder   trying   to   read   their  
messages   while   they   are   being   transmitted   by   using   a   sniffer.   With   a   system  
using   the   same   type   of   communication   as   SafeTime   the   packages   read   by   this  
hypothetical  intruder  will  be  of  no  use  because  of  the  way  its  encrypted.  This  can  
ensure  full  disclosure  of  the  project  in  terms  of  internal  communication.  
 
Many   industries   today   are   getting   more   concerned   on   their   communication  
security.   For   example,   due   to   the   increasing   digitalization   of   aviation   systems  
because   of   the   “More   electric   aircraft   [16]”   tendency   and   the   centralization   of  
information   and   control   with   the   FMS   (Flight   management   system),   very  
sensitive   information   about   flights   is   transmitted   from   the   airplane   to   other  
peers   such   as   the   engine   providers,   airplane   assemblers   or   airline   companies.  
This   communications   can   be   vulnerable   without   the   proper   security   in   their  
transmissions,   this   can   be   managed   with   a   model   like   the   one   used   for   SafeTime  
which  can  be  fast  enough.  
 

8. Conclusions  
Developing  SafeTime  application  turned  out  to  be  as  complex  as  was  expected.  
Instant  messaging  represents  a  difficulty  while  developing  because  of  the  speed  
at   which   messages   are   expected   to   arrive,   and   that   expectation   has   been  

 
57  
 

guarantied   within   its   limitations.   Cyber   security   has   been   one   of   the   most  
important   topics   lately   regarding   digitalization   of   information,   many   scandals  
regarding   this   can   be   seen   more   and   more   in   the   media   this   past   few   years.  
Whether  it  is  in  how  the  information  is  stored,  or  how  is  transmitted  and  even  
on   how   easy   can   be   for   a   skilled   hacker   to   access   remotely   to   systems   and   be  
able  to  obtain  confidential  information,  work  in  this  field  concerning  security  has  
been   increasing.   The   main   purpose   of   developing   this   application   is   to  
demonstrate   how   encryption   algorithms   (in   this   case   RSA)   can   be   used   in  
something  as  delicate  as  the  transmission  of  data.  It  could  be  demonstrated  that  
various  types  of  files  can  be  encrypted  in  a  relatively  fast  way  and  be  transmitted  
without  the  fear  of  getting  that  information  stolen  since,  while  been  transmitted,  
it   is   actually   nonsense   without   a   private   key   to   decrypt   it.   I   believe   this   same  
model   can   be   used   in   other   security   sensitive   systems   based   on   the   model  
described   in   this   paper.   For   this   purpose   I’ve   taken   as   one   of   my   examples   the  
digital   security   in   actual   civil   aviation,   which   is   known   for   its   flight   management  
systems   that   function   as   a   central   computer   controlling   the   airplane,   managing  
transmissions   and   sending   signals   to   actuators.   In   April   2015,   a   professional  
security  researcher  managed  to  hack  an  airplane  inflight  in  the  United  States  and  
was  able  to  modify  its  flight  path  slightly  of  course  [17].  The  fact  that  this  could  
be   done   indicates   how   vulnerable   these   systems   actually   are.   I   believe   that   by  
using  encrypted  commands  transmitted  to  the  systems,  this  kind  of  issues  can  be  
prevented   and   hence   guarantee   more   inflight   security   considering   the   estimated  
times  for  breaking  RSA  keys  is  substantially  less  than  the  time  an  airplane  stays  
in  the  air.  
This  is  just  an  example  of  how  a  model  like  the  one  used  on  SafeTime  can  help  
enhance   security   not   only   in   the   aviation   industry,   but   also   in   any   other   that  
depends  on  digital  technologies  management  systems.    
 
 
 

 
58  
 

9. Bibliography  

[1]   J.  Pindar  and  J.  Rigelsford,  “Cybersecurity  and  Information  Assurance,”  2011.  

[2]   “Top  Apps  –  Android  Apps  on  Google  Play.”  [Online].  Available:  
https://play.google.com/store/apps/collection/topselling_free?hl=en_GB.  
[Accessed:  30-­‐Apr-­‐2015].  

[3]   M.  Mannan  and  P.  C.  Van  Oorschot,  “Secure  Public  Instant  Messaging :  A  
Survey,”  Proc.  2nd  Annu.  Conf.  Privacy,  Secur.  Trust.,  pp.  69–77,  2004.  

[4]   M.  L.  Murphy,  Beginning  Android.  New  York,  2009.  

[5]   M.  Xue  and  C.  Zhu,  “The  socket  programming  and  software  design  for  
communication  based  on  client/server,”  Proc.  2009  Pacific-­‐Asia  Conf.  Circuits,  
Commun.  Syst.  PACCS  2009,  pp.  775–777,  2009.  

[6]   K.  L.  Calvert,  “TCP  /  IP  Sockets  in  C :  Practical  Guide  for  Programmers.”  

[7]   M.  Y.  Rhee,  Advanced  Encryption  Standard  and  Elliptic  Curve  Cryptosystems.  
2009.  

[8]   E.  Milanov,  “The  RSA  Algorithm,”  no.  June,  pp.  1–11,  2009.  

[9]   A.  Porter,  “Programming  the  Android  Platform  -­‐  Threads,  Asynctasks  &  
Handlers.”  [Online].  Available:  
http://www.cs.umd.edu/class/fall2011/cmsc436/CMSC436/Lectures_Labs_f
iles/ThreadsAndMessaging.pdf.  [Accessed:  21-­‐Aug-­‐2015].  

[10]   “Eclipse  Platform  Technical  Overview,”  2006.  

[11]   “Advanced  Encryption  Standard,”  National  Institute  of  Standards  and  


Technology.  [Online].  Available:  
http://csrc.nist.gov/publications/fips/fips197/fips-­‐197.pdf.  [Accessed:  22-­‐
Aug-­‐2015].  

[12]   “National  Policy  on  the  Use  of  the  Advanced  Encryption  Standard  (AES)  to  
Protect  National  Security  Systems  and  National  Security  Information,”  
National  Institute  of  Standards  and  Technology.  [Online].  Available:  
http://csrc.nist.gov/groups/ST/toolkit/documents/aes/CNSS15FS.pdf.  
[Accessed:  22-­‐Aug-­‐2015].  

[13]   “Special  Eurobarometer  423  ‘Cyber  security,’”  European  Commission.  [Online].  


Available:  http://ec.europa.eu/public_opinion/archives/ebs/ebs_423_en.pdf.  
[Accessed:  22-­‐Aug-­‐2015].  

 
59  
 

[14]   P.  Schneider,  “TCP/IP  Traffic  Classification  Based  on  Port  Numbers,”  


Schneidergrinch,  pp.  2–7,  1992.  

[15]   “Simplex,  Half  Duplex,  Full  Duplex  Communication  Channel.”  [Online].  


Available:  http://www.idc-­‐
online.com/technical_references/pdfs/electronic_engineering/Simplex.pdf.  
[Accessed:  22-­‐Aug-­‐2015].  

[16]   a  a  Abdelhafez  and  a  J.  Forsyth,  “A  Review  of  More-­‐Electric  Aircraft,”  Aerosp.  
Sci.  Aviat.  Technol.,  pp.  1–13,  2009.  

[17]   M.  Hurley,  “Warrant  for  Chris  Robberts,”  pp.  1–22,  2015.    

 
60  
 

Appendix  A:  Application  codes  


 
Ø SplashScreenActivity.java
package                  }else{  
com.example.ricardoviteri.safetimeapp;                          /**  RUN  SAFETIME'S  MAIN  LOGIN  
  WINDOW  **/  
import  android.content.Intent;                          Intent  intent  =  new  Intent(this,  
import   LoginActivity.class);  
android.support.v7.app.ActionBarActivity;                          startActivity(intent);  
import  android.os.Bundle;                          this.finish();  
import  android.view.Menu;                  }  
import  android.view.MenuItem;    
         }  
import  java.util.ArrayList;    
   
         @Override  
public  class  SplashScreenActivity  extends          public  boolean  onCreateOptionsMenu(Menu  
ActionBarActivity  {   menu)  {  
                 //  Inflate  the  menu;  this  adds  items  to  the  
       private  DBHelper  myDataBase;   action  bar  if  it  is  present.  
       public  ArrayList<String>  myUser;                  
  getMenuInflater().inflate(R.menu.menu_splash
  _screen,  menu);  
       @Override                  return  true;  
       protected  void  onCreate(Bundle          }  
savedInstanceState)  {    
               super.onCreate(savedInstanceState);          @Override  
                       public  boolean  
setContentView(R.layout.activity_splash_scree onOptionsItemSelected(MenuItem  item)  {  
n);                  int  id  =  item.getItemId();  
               myDataBase  =  new  DBHelper(this);    
               if  (myDataBase.numberOfRowsUser()  !=                  if  (id  ==  R.id.action_settings)  {  
0){                          return  true;  
                       /**  LOAD  THE  USER'S  INFO  AND                  }  
CONTACTS  **/    
                       Intent  intent  =  new  Intent(this,                  return  
ContactsTabActivity.class);   super.onOptionsItemSelected(item);  
                       startActivity(intent);          }  
                       this.finish();   }  
 
Ø DBHelper.java  
package          public  static  final  String  DATABASE_NAME  =  
com.example.ricardoviteri.safetimeapp;   "MyDBName.db";  
         /*******  CONTACTS  TABLE  ***********/  
/**          public  static  final  String  
 *  Created  by  ricardoviteri  on  6/18/15.   CONTACTS_TABLE_NAME  =  "contacts";  
 */          public  static  final  String  
import  java.util.ArrayList;   CONTACTS_COLUMN_ID  =  "id";  
import  java.util.Arrays;          public  static  final  String  
import  java.util.HashMap;   CONTACTS_COLUMN_NAME  =  "name";  
import  java.util.Hashtable;          public  static  final  String  
import  android.content.ContentValues;   CONTACTS_COLUMN_EMAIL  =  "email";  
import  android.content.Context;          public  static  final  String  
import  android.database.Cursor;   CONTACTS_COLUMN_KEY  =  "key";  
import  android.database.DatabaseUtils;          
import   /*********************************************/  
android.database.sqlite.SQLiteOpenHelper;    
import          /*******  USER  INFO  TABLE  ***********/  
android.database.sqlite.SQLiteDatabase;          public  static  final  String  USER_TABLE_NAME  
  =  "user";  
public  class  DBHelper  extends          public  static  final  String  USER_COLUMN_ID  =  
SQLiteOpenHelper  {   "id";  
         public  static  final  String  
USER_COLUMN_NAME  =  "name";  

ii    
 

       public  static  final  String                  Cursor  res  =    db.rawQuery(  "select  *  from  


USER_COLUMN_PHONE  =  "phone";   contacts  where  name="+name+"",  null  );  
       public  static  final  String                  System.out.println(res);  
USER_COLUMN_EMAIL  =  "email";                  return  res;  
       public  static  final  String          }  
USER_COLUMN_PRIVATE  =  "privateKey";    
       public  static  final  String          public  int  numberOfRowsContacts(){  
USER_COLUMN_PUBLIC  =  "publicKey";                  SQLiteDatabase  db  =  
       public  static  final  String   this.getReadableDatabase();  
USER_COLUMN_PORT  =  "port";                  int  numRows  =  (int)  
        DatabaseUtils.queryNumEntries(db,  
/********************************************/   CONTACTS_TABLE_NAME);  
                 return  numRows;  
       private  HashMap  hp;          }  
   
       public  DBHelper(Context  context)          public  boolean  updateContact  (Integer  id,  
       {   String  name,  String  email,  String  key)  
               super(context,  DATABASE_NAME  ,  null,  1);          {  
       }                  SQLiteDatabase  db  =  
  this.getWritableDatabase();  
       @Override                  ContentValues  contentValues  =  new  
       public  void  onCreate(SQLiteDatabase  db)  {   ContentValues();  
               //  TODO  Auto-­‐generated  method  stub                  contentValues.put("name",  name);  
               db.execSQL(                  contentValues.put("email",  email);  
                               "create  table  contacts  "  +                  contentValues.put("key",  key);  
                                               "(id  integer  primary  key,  name                  db.update("contacts",  contentValues,  "id  =  
text,email  text,  key  text)"   ?  ",  new  String[]  {  Integer.toString(id)  }  );  
               );                  return  true;  
         }  
               db.execSQL(    
                               "create  table  user  "  +          public  Integer  deleteContact  (Integer  id)  
                                               "(id  integer  primary  key,  name          {  
text,  phone  text,  email  text,  privateKey  text,                  SQLiteDatabase  db  =  
publicKey  text,  port  text)"   this.getWritableDatabase();  
               );                  return  db.delete("contacts",  
       }                                  "id  =  ?  ",  
                                 new  String[]  {  Integer.toString(id)  });  
       @Override          }  
       public  void  onUpgrade(SQLiteDatabase  db,    
int  oldVersion,  int  newVersion)  {          public  ArrayList<String>  getAllCotacts()  
               //  TODO  Auto-­‐generated  method  stub          {  
               db.execSQL("DROP  TABLE  IF  EXISTS                  ArrayList<String>  array_list  =  new  
contacts");   ArrayList<String>();  
               db.execSQL("DROP  TABLE  IF  EXISTS    
user");                  //hp  =  new  HashMap();  
               onCreate(db);                  SQLiteDatabase  db  =  
       }   this.getReadableDatabase();  
                 Cursor  res  =    db.rawQuery(  "select  *  from  
       /*********  CONTACTS  TABLE  **********/   contacts",  null  );  
                 res.moveToFirst();  
       public  boolean  insertContact    (String  name,    
String  email,  String  key)                  while(res.isAfterLast()  ==  false){  
       {                          
               SQLiteDatabase  db  =   array_list.add(res.getString(res.getColumnInde
this.getWritableDatabase();   x(CONTACTS_COLUMN_EMAIL)));  
               ContentValues  contentValues  =  new                          res.moveToNext();  
ContentValues();                  }  
               contentValues.put("name",  name);                  return  array_list;  
               contentValues.put("email",  email);          }  
               contentValues.put("key",  key);    
               db.insert("contacts",  null,  contentValues);          public  ArrayList<String[]>  
               return  true;   getAllCotactsWithInfo()  
       }          {  
                 ArrayList<String[]>  array_list  =  new  
       public  Cursor  getDataContact(String  name){   ArrayList<String[]>();  
               SQLiteDatabase  db  =    
this.getReadableDatabase();                  //hp  =  new  HashMap();  

 
iii  
 

               SQLiteDatabase  db  =    
this.getReadableDatabase();    
               Cursor  res  =    db.rawQuery(  "select  *  from    
contacts",  null  );          /************  USER  INFO  TABLE  ***********/  
               res.moveToFirst();    
         public  boolean  insertUser    (String  name,  
               while(res.isAfterLast()  ==  false){   String  phone,  String  email,  String  privateKey,  
                       String[]  contact  =  new  String[4];   String  publicKey,  String  port)  
                       contact[0]  =          {  
res.getString(res.getColumnIndex(CONTACTS_                SQLiteDatabase  db  =  
COLUMN_ID));   this.getWritableDatabase();  
                       contact[1]  =                  ContentValues  contentValues  =  new  
res.getString(res.getColumnIndex(CONTACTS_ ContentValues();  
COLUMN_NAME));                  contentValues.put("name",  name);  
                       contact[2]  =                  contentValues.put("phone",  phone);  
res.getString(res.getColumnIndex(CONTACTS_                contentValues.put("email",  email);  
COLUMN_EMAIL));                  contentValues.put("privateKey",  
                       contact[3]  =   privateKey);  
res.getString(res.getColumnIndex(CONTACTS_                contentValues.put("publicKey",  
COLUMN_KEY));   publicKey);  
                 contentValues.put("port",  port);  
                       ArrayList<String>  cosa  =  new                  db.insert("user",  null,  contentValues);  
ArrayList<String>(Arrays.asList(contact));                  return  true;  
         }  
                       array_list.add(contact);    
                       res.moveToNext();          public  Cursor  getDataUser(int  id){  
               }                  SQLiteDatabase  db  =  
               return  array_list;   this.getReadableDatabase();  
       }                  Cursor  res  =    db.rawQuery(  "select  *  from  
  user  where  id="+id+"",  null  );  
       public  ArrayList<ArrayList<Object>>                  return  res;  
getAllCotactsWithInfoAsList()          }  
       {    
               ArrayList<ArrayList<Object>>  array_list  =          public  int  numberOfRowsUser(){  
new  ArrayList<ArrayList<Object>>();                  SQLiteDatabase  db  =  
  this.getReadableDatabase();  
               //hp  =  new  HashMap();                  int  numRows  =  (int)  
               SQLiteDatabase  db  =   DatabaseUtils.queryNumEntries(db,  
this.getReadableDatabase();   USER_TABLE_NAME);  
               Cursor  res  =    db.rawQuery(  "select  *  from                  return  numRows;  
contacts",  null  );          }  
               res.moveToFirst();    
         public  boolean  updateUser  (Integer  id,  String  
               while(res.isAfterLast()  ==  false){   name,  String  phone,  String  email,  String  
                       String[]  contact  =  new  String[4];   privateKey,  String  publicKey,  String  port)  
                       contact[0]  =          {  
res.getString(res.getColumnIndex(CONTACTS_                SQLiteDatabase  db  =  
COLUMN_ID));   this.getWritableDatabase();  
                       contact[1]  =                  ContentValues  contentValues  =  new  
res.getString(res.getColumnIndex(CONTACTS_ ContentValues();  
COLUMN_NAME));                  contentValues.put("name",  name);  
                       contact[2]  =                  contentValues.put("phone",  phone);  
res.getString(res.getColumnIndex(CONTACTS_                contentValues.put("email",  email);  
COLUMN_EMAIL));                  contentValues.put("street",  privateKey);  
                       contact[3]  =                  contentValues.put("place",  publicKey);  
res.getString(res.getColumnIndex(CONTACTS_                db.update("user",  contentValues,  "id  =  ?  ",  
COLUMN_KEY));   new  String[]  {  Integer.toString(id)  }  );  
                 return  true;  
                       ArrayList<Object>  contactList  =  new          }  
ArrayList<Object>(Arrays.asList(contact));    
         public  Integer  deleteUser  (Integer  id)  
                       array_list.add(contactList);          {  
                       res.moveToNext();                  SQLiteDatabase  db  =  
               }   this.getWritableDatabase();  
               return  array_list;                  return  db.delete("user",  
       }                                  "id  =  ?  ",  
                                       new  String[]  {  Integer.toString(id)  });  
/*********************************************/          }  
 

 
iv  
 

       public  ArrayList<String>  getUser()                  


       {   array_list.add(res.getString(res.getColumnInde
               ArrayList<String>  array_list  =  new   x(USER_COLUMN_EMAIL)));  
ArrayList<String>();                  
  array_list.add(res.getString(res.getColumnInde
               //hp  =  new  HashMap();   x(USER_COLUMN_PRIVATE)));  
               SQLiteDatabase  db  =                  
this.getReadableDatabase();   array_list.add(res.getString(res.getColumnInde
               Cursor  res  =    db.rawQuery(  "select  *  from   x(USER_COLUMN_PUBLIC)));  
user",  null  );                  
               res.moveToFirst();   array_list.add(res.getString(res.getColumnInde
  x(USER_COLUMN_PORT)));  
                 
array_list.add(res.getString(res.getColumnInde                return  array_list;  
x(USER_COLUMN_ID)));          }  
                       
array_list.add(res.getString(res.getColumnInde /********************************************/  
x(USER_COLUMN_NAME)));   }  
               
array_list.add(res.getString(res.getColumnInde
x(USER_COLUMN_PHONE)));  
 
Ø ContactsTabActivity.java  
package                  contacts  =  db.getAllCotactsWithInfo();  
com.example.ricardoviteri.safetimeapp;                  contacts2  =  
  db.getAllCotactsWithInfoAsList();  
import  android.content.Context;                  tasksToDo  =  new  
import  android.content.Intent;   ArrayList<ArrayList<Object>>();  
import  android.net.Uri;                  Port  =  
import  android.os.Bundle;   Integer.parseInt(db.getUser().get(6));  
import  android.support.annotation.NonNull;    
import                  thisUser  =  db.getUser().get(3);  
android.support.v4.app.FragmentActivity;                  N  =  new  
import   BigInteger(db.getUser().get(4).split("-­‐")[0]);  
android.support.v4.app.FragmentTabHost;                  d  =  new  
import  android.util.AttributeSet;   BigInteger(db.getUser().get(4).split("-­‐")[1]);  
import  android.view.View;    
import  android.widget.Toast;                  mTabHost  =  
  (FragmentTabHost)findViewById(android.R.id.
import  java.lang.reflect.Array;   tabhost);  
import  java.math.BigInteger;                  mTabHost.setup(this,  
import  java.util.ArrayList;   getSupportFragmentManager(),  
import  java.util.Arrays;   R.id.realtabcontent);  
   
/**    
 *  Created  by  ricardoviteri  on  7/2/15.                  
 */   mTabHost.addTab(mTabHost.newTabSpec("ta
  b1").setIndicator("Contacts"),  
public  class  ContactsTabActivity  extends                                  ContactListTab.class,  null);  
FragmentActivity{                  
  mTabHost.addTab(mTabHost.newTabSpec("ta
       public  FragmentTabHost  mTabHost;   b2").setIndicator("Conv."),  
       ArrayList<String[]>  contacts;                                  ConversationListTab.class,  null);  
       ArrayList<ArrayList<Object>>  contacts2;                  
       ArrayList<ArrayList<Object>>  tasksToDo;   mTabHost.addTab(mTabHost.newTabSpec("ta
       String  thisUser;   b3").setIndicator("+Add  contact"),  
       int  Port;                                  AddContactTab.class,  null);  
       BigInteger  N,  d;                  mTabHost.setCurrentTab(1);  
   
       @Override    
       protected  void  onCreate(Bundle          }  
savedInstanceState)  {    
         @Override  
               super.onCreate(savedInstanceState);          protected  void  onStart()  {  
               setContentView(R.layout.contacts_layout);                  super.onStart();  
                 ServerThread  listeningThread  =  new  
               DBHelper  db  =  new  DBHelper(this);   ServerThread(this,  thisUser);  

v    
 

               listeningThread.start();                          if  (contacts.get(i)[2].equals(fromUser)){  


       }                                  contactsId  =  i;  
                         }  
       @Override                  }  
       public  void  onActivityResult(int    
requestCode,  int  resultCode,  Intent  data)  {    
               super.onActivityResult(requestCode,                  ArrayList<Object>  userInfo  =  
resultCode,  data);   contacts2.get(contactsId);  
               System.out.println("In  Activity");    
               ConversationListTab  activeConv  =                  Object  info  =  null;  
(ConversationListTab)this.getSupportFragmen                if  (message  instanceof  byte[]){  
tManager().findFragmentByTag("tab2");                          System.out.println("Actual  message:  
               Uri  selectedImageUri  =  data.getData();   "+new  String((byte[])message));  
               String  selectedImagePath  =                          System.out.println("Actual  fromUser:  
activeConv.getPath(selectedImageUri);   "+fromUser);  
                 
activeConv.image.setImageURI(selectedImage                        info  =  new  String[]{"1",  new  
Uri);   String(messageDecryption((byte[])  
                message))};  
activeConv.layoutImage.setVisibility(View.VISI                }else{  
BLE);                          info  =  new  ArrayList<Object>();  
                         ((ArrayList)info).add("1");  
       }                          ((ArrayList)info).add(message);  
                 }  
       public  void  switchTabTo(int  index){    
               mTabHost.setCurrentTab(index);                  ArrayList<Object>  savedConversation;  
       }                  if  (userInfo.size()  ==  4){  
                         savedConversation  =  new  
       public  void  openConversation(int  contact){   ArrayList<Object>();  
               ConversationListTab  activeConv  =                          savedConversation.add(info);  
(ConversationListTab)this.getSupportFragmen                        
tManager().findFragmentByTag("tab2");   contacts2.get(contactsId).add(savedConversati
               activeConv.activeContact  =  contact;   on);  
               activeConv.key  =  (String)                  }else{  
contacts2.get(contact).get(3);                          
               mTabHost.setCurrentTab(1);   ((ArrayList<Object>)contacts2.get(contactsId).
       }   get(4)).add(info);  
                 }  
       public  void  addContact(String[]                  ConversationListTab  activeConv  =  
newContact){   (ConversationListTab)this.getSupportFragmen
               System.out.println(newContact[0]);   tManager().findFragmentByTag("tab2");  
               System.out.println(newContact[1]);    
               System.out.println(newContact[2]);                  if  (contactsId  ==  
               DBHelper  db  =  new  DBHelper(this);   activeConv.activeContact){  
               db.insertContact(newContact[0],                          activeConv.postNewMessage();  
newContact[1],  newContact[2]);                  }  
               refreshContacts();          }  
       }    
         public  byte[]  messageDecryption(byte[]  D){  
       public  void  contactNotFound(String                  byte[]  msgToDecrypt  =  new  byte[D.length-­‐
contact){   1];  
               Toast  toast  =  Toast.makeText(this,  "User                  for  (int  i  =  0;  i<D.length-­‐1;  i++){  
"+contact+"  not  found",                          msgToDecrypt[i]  =  D[i];  
Toast.LENGTH_SHORT);                  }  
               toast.show();                  System.out.println(""+D[D.length-­‐1]);  
       }                  BigInteger  encryptedMsg  =  new  
  BigInteger(msgToDecrypt);  
       public  void  refreshContacts(){    
               DBHelper  db  =  new  DBHelper(this);                  encryptedMsg  =  encryptedMsg.modPow(d,  
               contacts  =  db.getAllCotactsWithInfo();   N);  
               contacts2  =    
db.getAllCotactsWithInfoAsList();                  if  (D[D.length-­‐1]  ==  (byte)1){  
       }                          encryptedMsg  =  
  encryptedMsg.multiply(BigInteger.valueOf(-­‐
       public  void  addToConversation(String   1));  
fromUser,  Object  message){                  }  
               int  contactsId  =  0;    
               for  (int  i  =  0;  i  <  contacts.size();  i++){  

 
vi  
 

               ConversationListTab  activeConv  =                  //return  (new  BigInteger(D)).modPow(d,  


(ConversationListTab)this.getSupportFragmen N).toByteArray();  
tManager().findFragmentByTag("tab2");          }  
  }  
               return  encryptedMsg.toByteArray();  
 
Ø ContactListTab.java  
package                  //  Inflate  the  layout  for  this  fragment  
com.example.ricardoviteri.safetimeapp;                  View  V  =  
  inflater.inflate(R.layout.contact_list_tab,  
import  android.os.Bundle;   container,  false);  
import  android.support.v4.app.Fragment;    
import  android.view.LayoutInflater;                  contactList  =  
import  android.view.View;   (ListView)V.findViewById(R.id.listView);  
import  android.view.ViewGroup;    
import  android.widget.AdapterView;                  ContactListAdapter  adapter  =  new  
import  android.widget.ListView;   ContactListAdapter(this.getActivity(),  1,  
  ((ContactsTabActivity)this.getActivity()).conta
import  java.util.ArrayList;   cts2.toArray());  
                 contactList.setAdapter(adapter);  
/**                  contactList.setOnItemClickListener(this);  
 *  Created  by  ricardoviteri  on  7/2/15.                  return  V;  
 */          }  
public  class  ContactListTab  extends  Fragment    
implements          @Override  
AdapterView.OnItemClickListener{          public  void  onItemClick(AdapterView<?>  
  parent,  View  view,  int  position,  long  id)  {  
       ListView  contactList;                  System.out.println(""+position);  
                 
       @Override   ((ContactsTabActivity)this.getActivity()).openC
       public  View  onCreateView(LayoutInflater   onversation(position);  
inflater,  ViewGroup  container,          }  
                                                         Bundle  savedInstanceState)  {   }  
 
Ø ContactListAdapter.java  
package                  context  =  ctx;  
com.example.ricardoviteri.safetimeapp;          }  
   
import  android.app.Fragment;    
import  android.content.Context;          @Override  
import          public  View  getView(int  position,  View  
android.support.v4.app.FragmentActivity;   convertView,  ViewGroup  parent)  {  
import  android.view.LayoutInflater;    
import  android.view.View;                  if(convertView==null){  
import  android.view.ViewGroup;                          //  inflate  the  layout  
import  android.widget.ArrayAdapter;                          LayoutInflater  inflater  =  
import  android.widget.TextView;   ((FragmentActivity)context).getLayoutInflater(
  );  
import  java.util.ArrayList;                          convertView  =  
import  java.util.Objects;   inflater.inflate(R.layout.contact_cell,  parent,  
  false);  
/**                  }  
 *  Created  by  ricardoviteri  on  7/19/15.    
 */                  TextView  name  =  
public  class  ContactListAdapter  extends   (TextView)convertView.findViewById(R.id.text
ArrayAdapter  {   View15);  
                 ArrayList  contact  =  (ArrayList)  
       Object[]  contacts;   contacts[position];  
       Context  context;                  name.setText(contact.get(1).toString());  
   
       public  ContactListAdapter(Context  ctx,  int    
resource,  Object[]  objects)  {                  return  convertView;  
               super(ctx,  resource,  objects);          }  
               contacts  =  objects;   }  
 

 
vii  
 

Ø ConversationListTab.java  
package                  View  V  =  
com.example.ricardoviteri.safetimeapp;   inflater.inflate(R.layout.conversation_tab,  
  container,  false);  
import  android.content.Intent;                  txtUser  =  
import  android.database.Cursor;   (TextView)V.findViewById(R.id.textView16);  
import  android.graphics.Bitmap;                  message  =  
import   (EditText)V.findViewById(R.id.editText10);  
android.graphics.drawable.BitmapDrawable;                  conversation  =  
import  android.graphics.drawable.Drawable;   (ListView)V.findViewById(R.id.listView2);  
import  android.net.Uri;                  sendMessage  =  
import  android.os.Bundle;   (Button)V.findViewById(R.id.button7);  
import  android.os.Parcelable;                  loadImg  =  
import  android.provider.MediaStore;   (Button)V.findViewById(R.id.button8);  
import  android.support.v4.app.Fragment;                  sendImage  =  
import  android.util.Log;   (Button)V.findViewById(R.id.button9);  
import  android.view.LayoutInflater;                  image  =  
import  android.view.View;   (ImageView)V.findViewById(R.id.imageView3)
import  android.view.ViewGroup;   ;  
import  android.widget.Button;                  layoutImage  =  
import  android.widget.EditText;   (RelativeLayout)V.findViewById(R.id.imageLay
import  android.widget.ImageView;   out);  
import  android.widget.ListView;    
import  android.widget.RelativeLayout;                  
import  android.widget.TextView;   if((((ContactsTabActivity)this.getActivity()).co
import  android.widget.Toast;   ntacts2).size()  !=  0){  
                         userInfo  =  
import  java.io.ByteArrayOutputStream;   ((ContactsTabActivity)this.getActivity()).conta
import  java.io.IOException;   cts2.get(activeContact);  
import  java.math.BigInteger;                          key  =  (String)  userInfo.get(3);  
import  java.util.ArrayList;                          if  (userInfo.size()  ==  4){  
                                 savedConversation  =  new  
/**   ArrayList<Object>();  
 *  Created  by  ricardoviteri  on  7/7/15.                                  userInfo.add(savedConversation);  
 */                          }else{  
public  class  ConversationListTab  extends                                  savedConversation  =  
Fragment  implements  View.OnClickListener  {   (ArrayList<Object>)  userInfo.get(4);  
       int  activeContact  =  0;                          }  
       TextView  txtUser;    
       EditText  message;                          
       ListView  conversation;   txtUser.setText(userInfo.get(1).toString());  
       Button  sendMessage,  loadImg,  sendImage;    
       ImageView  image;                          sendMessage.setOnClickListener(this);  
       RelativeLayout  layoutImage;                          loadImg.setOnClickListener(this);  
       ArrayList<Object>  userInfo;                          sendImage.setOnClickListener(this);  
       ArrayList<Object>  savedConversation;    
       String  key;                          ConversationAdapter  adapter  =  new  
  ConversationAdapter(this.getActivity(),  1,  
       @Override   savedConversation.toArray());  
       public  void  onCreate(Bundle                          conversation.setAdapter(adapter);  
savedInstanceState)  {                          
               super.onCreate(savedInstanceState);   conversation.setSelection(savedConversation.s
               System.out.println("Conversation  tab   ize()-­‐1);  
"+activeContact);                  }else{  
               if                          txtUser.setText("No  contacts");  
(((ContactsTabActivity)this.getActivity()).mTa                }  
bHost  !=  null){    
                         
((ContactsTabActivity)this.getActivity()).switc  
hTabTo(0);    
               }                  return  V;  
       }          }  
   
       @Override          @Override  
       public  View  onCreateView(LayoutInflater          public  void  onClick(View  v)  {  
inflater,  ViewGroup  container,                  switch  (v.getId()){  
                                                         Bundle  savedInstanceState)  {                          case  R.id.button7:  
               //  Inflate  the  layout  for  this  fragment  

8    
 

                               if                                  
(message.getText().toString().length()>0){   bitmap.compress(Bitmap.CompressFormat.JPE
                                       String[]  info  =  {"0",   G,  100,  stream);  
message.getText().toString()};                                  byte[]  bitmapdata  =  
                                       ArrayList<Object>  task  =  new   stream.toByteArray();  
ArrayList<Object>();    
                                       task.add("11");                                  new  
                                       task.add(userInfo.get(2));   EncryptPictureTask(this.getActivity(),  new  
                                        BigInteger(key.split("-­‐")[0]),  new  
task.add(messageEncryption((message.getText BigInteger(key.split("-­‐")[1]),  
().toString()).getBytes()));   (String)userInfo.get(2)).execute(bitmapdata);  
                                                                       break;  
((ContactsTabActivity)this.getActivity()).tasks                }  
ToDo.add(task);    
                                       /*SOK_CLIENT_BASIC  cosa  =  new          }  
SOK_CLIENT_BASIC((message.getText().toStrin  
g()).getBytes());          public  void  
                                       try  {   addPictureTask(ArrayList<Object>  task){  
                                           cosa.run();                  
                                       }  catch  (Exception  e)  {   ((ContactsTabActivity)this.getActivity()).tasks
                                           e.printStackTrace();   ToDo.add(task);  
                                       }*/          }  
                                       savedConversation.add(info);    
                                       ConversationAdapter  adapter  =  new          public  String  getPath(Uri  uri)  {  
ConversationAdapter(this.getActivity(),  1,    
savedConversation.toArray());                  //  just  some  safety  built  in  
                                       conversation.setAdapter(adapter);                  if(  uri  ==  null  )  {  
                                       message.setText("");                          //  perform  some  logging  or  show  user  
                                        feedback  
conversation.setSelection(savedConversation.s                        Toast.makeText(this.getActivity(),  
ize()-­‐1);   "Loading  picture  failed",  
  Toast.LENGTH_LONG).show();  
                               }                          return  null;  
                               break;                  }  
                       case  R.id.button8:    
                               Intent  intent  =  new  Intent();                  //  try  to  retrieve  the  image  from  the  media  
                               intent.setType("image/*");   store  first  
                                               //  this  will  only  work  for  images  selected  
intent.setAction(Intent.ACTION_GET_CONTEN from  gallery  
T);                  String[]  projection  =  {  
                                MediaStore.Images.Media.DATA  };  
this.getActivity().startActivityForResult(Intent.                Cursor  cursor  =  
createChooser(intent,"Select  Picture"),  101);   this.getActivity().managedQuery(uri,  
                               break;   projection,  null,  null,  null);  
                       case  R.id.button9:                  if(  cursor  !=  null  ){  
                               ArrayList<Object>  info  =  new                          int  column_index  =  cursor  
ArrayList<Object>();                                          
                               info.add("0");   .getColumnIndexOrThrow(MediaStore.Images.
                               info.add(image.getDrawable());   Media.DATA);  
                               savedConversation.add(info);                          cursor.moveToFirst();  
                               ConversationAdapter  adapter  =  new                          return  cursor.getString(column_index);  
ConversationAdapter(this.getActivity(),  1,                  }  
savedConversation.toArray());                  //  this  is  our  fallback  here,  thanks  to  the  
                               conversation.setAdapter(adapter);   answer  from  @mad  indicating  this  is  needed  
                               message.setText("");   for  
                                               //  working  code  based  on  images  selected  
conversation.setSelection(savedConversation.s using  other  file  managers  
ize()-­‐1);                  return  uri.getPath();  
                                       }  
layoutImage.setVisibility(View.INVISIBLE);    
         public  void  postNewMessage(){  
                               Bitmap  bitmap  =                  ConversationAdapter  adapter  =  new  
((BitmapDrawable)image.getDrawable()).getBi ConversationAdapter(this.getActivity(),  1,  
tmap();   savedConversation.toArray());  
                               ByteArrayOutputStream  stream  =  new                  conversation.setAdapter(adapter);  
ByteArrayOutputStream();                  message.setText("");  
               
conversation.setSelection(savedConversation.s
ize()-­‐1);  

 
ix  
 

       }                                  }  
                         }  
       public  byte[]  messageEncryption(byte[]  M){                          return  encMsgBytes;  
               BigInteger  N  =  new  BigInteger(key.split("-­‐                }else{  
")[0]);                          encryptedMsg  =  
               BigInteger  e  =  new  BigInteger(key.split("-­‐ encryptedMsg.modPow(e,  N);  
")[1]);                          byte[]  encMsgBytestemp  =  
  encryptedMsg.toByteArray();  
               BigInteger  encryptedMsg  =  new                          byte[]  encMsgBytes  =  new  
BigInteger(M);   byte[encMsgBytestemp.length+1];  
               if  (encryptedMsg.signum()  !=  1){                          for  (int  i  =  0;  i<encMsgBytes.length;  i++){  
                       encryptedMsg  =                                  if  (i  ==  encMsgBytes.length-­‐1){  
encryptedMsg.multiply(BigInteger.valueOf(-­‐                                        encMsgBytes[i]  =  (byte)2;  
1));                                  }else{  
                       encryptedMsg  =                                          encMsgBytes[i]  =  
encryptedMsg.modPow(e,  N);   encMsgBytestemp[i];  
                       byte[]  encMsgBytestemp  =                                  }  
encryptedMsg.toByteArray();                          }  
                       byte[]  encMsgBytes  =  new                          return  encMsgBytes;  
byte[encMsgBytestemp.length+1];                  }  
                       for  (int  i  =  0;  i<encMsgBytes.length;  i++){                  //return  encryptedMsg.toByteArray();  
                               if  (i  ==  encMsgBytes.length-­‐1){                  //return  (new  BigInteger(M)).modPow(e,  
                                       encMsgBytes[i]  =  (byte)1;   N).toByteArray();  
                               }else{          }  
                                       encMsgBytes[i]  =   }  
encMsgBytestemp[i];  
 
Ø ConversationAdapter.java  
package                  LayoutInflater  inflater  =  
com.example.ricardoviteri.safetimeapp;   ((FragmentActivity)context).getLayoutInflater(
  );  
import  android.content.Context;                  if  (conversation[position]  instanceof  
import  android.graphics.drawable.Drawable;   String[]){  
import                          convertView  =  
android.support.v4.app.FragmentActivity;   inflater.inflate(R.layout.conversation_cell,  
import  android.view.Gravity;   parent,  false);  
import  android.view.LayoutInflater;    
import  android.view.View;                          TextView  name;  
import  android.view.ViewGroup;    
import  android.widget.ArrayAdapter;                          if  
import  android.widget.ImageView;   (Integer.parseInt(((String[])conversation[posit
import  android.widget.TextView;   ion])[0])  ==  0){  
                                 name  =  
import  java.util.ArrayList;   (TextView)convertView.findViewById(R.id.text
  View18);  
/**                          }else{  
 *  Created  by  ricardoviteri  on  7/20/15.                                  name  =  
 */   (TextView)convertView.findViewById(R.id.text
public  class  ConversationAdapter  extends   View17);  
ArrayAdapter  {                          }  
                         
       Object[]  conversation;   name.setText(((String[])conversation[position
       Context  context;   ])[1]);  
                 }else{  
       public  ConversationAdapter(Context  ctx,  int                          convertView  =  
resource,  Object[]  objects)  {   inflater.inflate(R.layout.conversation_image_cel
               super(ctx,  resource,  objects);   l,  parent,  false);  
               conversation  =  objects;                          ImageView  image;  
               context  =  ctx;    
       }                          if  (Integer.parseInt((String)  
  ((ArrayList<Object>)conversation[position]).g
       @Override   et(0))  ==  0){  
       public  View  getView(int  position,  View                                  image  =  
convertView,  ViewGroup  parent)  {   (ImageView)convertView.findViewById(R.id.i
  mageView5);  
               //  inflate  the  layout                          }else{  

x    
 

                               image  =    
(ImageView)convertView.findViewById(R.id.i                }  
mageView4);    
                       }    
                       image.setImageDrawable((Drawable)                  return  convertView;  
((ArrayList<Object>)conversation[position]).g        }  
et(1));   }  
 
Ø AddContactTab.java  
package                                  String  mail  =  
com.example.ricardoviteri.safetimeapp;   userEdt.getText().toString();  
                                 for  (int  i  =  0;  i  <  contacts.size();  i++){  
import  android.content.DialogInterface;                                          if  (contacts.get(i).equals(mail)){  
import  android.database.Cursor;                                                  userExists  =  true;  
import  android.os.Bundle;                                                  break;  
import  android.support.v4.app.Fragment;                                          }  
import  android.view.LayoutInflater;                                  }  
import  android.view.View;                                  if  (userExists){  
import  android.view.ViewGroup;                                          Toast  toast  =  
import  android.widget.Button;   Toast.makeText(this.getActivity(),  "Contact  
import  android.widget.EditText;   already  added",  Toast.LENGTH_SHORT);  
import  android.widget.RelativeLayout;                                          toast.show();  
import  android.widget.Toast;                                  }else{  
                                         //new  AddContactTask(this,  
import  java.util.ArrayList;   userEdt.getText().toString()).execute();  
                                         ArrayList<Object>  addUser  =  new  
/**   ArrayList<Object>();  
 *  Created  by  ricardoviteri  on  7/7/15.                                          addUser.add("10");  
 */                                          
public  class  AddContactTab  extends  Fragment   addUser.add(userEdt.getText().toString());  
implements  View.OnClickListener  {                                          ((ContactsTabActivity)  
  this.getActivity()).tasksToDo.add(addUser);  
       public  EditText  userEdt;                                  }  
       public  Button  btnAdd;                          }else{  
       public  RelativeLayout  loadingLayout;                                  //new  AddContactTask(this,  
  userEdt.getText().toString()).execute();  
       @Override                                  ArrayList<Object>  addUser  =  new  
       public  View  onCreateView(LayoutInflater   ArrayList<Object>();  
inflater,  ViewGroup  container,                                  addUser.add("10");  
                                                         Bundle  savedInstanceState)  {                                  
               //  Inflate  the  layout  for  this  fragment   addUser.add(userEdt.getText().toString());  
               View  V  =                                  ((ContactsTabActivity)  
inflater.inflate(R.layout.add_contact_tab,   this.getActivity()).tasksToDo.add(addUser);  
container,  false);                          }  
               userEdt  =  (EditText)    
V.findViewById(R.id.editText9);    
               btnAdd  =  (Button)                  }  
V.findViewById(R.id.button6);          }  
               loadingLayout  =  (RelativeLayout)    
V.findViewById(R.id.loadingLayout);          public  void  addContact(String[]  
  newContact){  
               btnAdd.setOnClickListener(this);                  System.out.println(newContact[0]);  
                 System.out.println(newContact[1]);  
               return  V;                  System.out.println(newContact[2]);  
       }                  DBHelper  db  =  new  
  DBHelper(this.getActivity());  
       @Override                  db.insertContact(newContact[0],  
       public  void  onClick(View  v)  {   newContact[1],  newContact[2]);  
               if  (userEdt.getText().toString().length()  >                  
0){   ((ContactsTabActivity)this.getActivity()).refres
                       DBHelper  db  =  new   hContacts();  
DBHelper(this.getActivity());          }  
                       ArrayList<String>  contacts  =    
db.getAllCotacts();          public  void  contactNotFound(){  
                       boolean  userExists  =  false;                  Toast  toast  =  
                       if  (contacts.size()  >  0){   Toast.makeText(this.getActivity(),  "User  not  
found",  Toast.LENGTH_SHORT);  

 
xi  
 

               toast.show();   }  
       }  
 
Ø LoginActivity.java  
package                                  if  (isComplete){  
com.example.ricardoviteri.safetimeapp;                                          
  loadingView.setVisibility(View.VISIBLE);  
import  android.app.Activity;                                          new  LoginTask(this,  
import  android.content.Intent;   txtUsername.getText().toString(),  
import  android.os.Bundle;   txtPassword.getText().toString()).execute();  
import  android.view.View;                                  }else{  
import  android.widget.Button;                                          Toast  toast  =  Toast.makeText(this,  
import  android.widget.EditText;   "Fields  are  not  complete",  
import  android.widget.RelativeLayout;   Toast.LENGTH_SHORT);  
import  android.widget.Switch;                                          toast.show();  
import  android.widget.Toast;                                  }  
                                 break;  
import  java.math.BigInteger;                          case  R.id.button3:  
import  java.util.ArrayList;                                  Intent  intent  =  new  Intent(this,  
  RegisterActivity.class);  
/**                                  startActivity(intent);  
 *  Created  by  ricardoviteri  on  6/28/15.                                  //this.finish();  
 */                                  break;  
public  class  LoginActivity  extends  Activity                  }  
implements  View.OnClickListener{          }  
       EditText  txtUsername,  txtPassword;    
       Button  btnRegister,  btnLogin;          public  void  loginAction(int  code,  String[]  
       BigInteger  N,  e,  d;   user){  
       String[]  userInfo  =  new  String[3];                  /**  
       RelativeLayout  loadingView;                    *  1:  User  not  found  
                   *  2:  Correct  password  
       @Override                    *  3:  Incorrect  password  
       protected  void  onCreate(Bundle                    *  4:  Info  not  received  
savedInstanceState)  {                  **/  
               super.onCreate(savedInstanceState);    
               setContentView(R.layout.activity_login);                  switch  (code){  
                         case  1:  
               txtUsername  =  (EditText)                                  executeToast("User  not  registered");  
findViewById(R.id.editText5);                                  break;  
               txtPassword  =  (EditText)                          case  2:  
findViewById(R.id.editText6);                                  System.out.println(user[0]);  
                                 System.out.println(user[1]);  
               loadingView  =  (RelativeLayout)                                  System.out.println(user[2]);  
findViewById(R.id.loadingLayout);                                  System.out.println(user[3]);  
                                 userInfo  =  user;  
               btnLogin  =  (Button)                                  new  
findViewById(R.id.button2);   KeyGenerationTask(this).execute();  
               btnRegister  =  (Button)                                  break;  
findViewById(R.id.button3);                          case  3:  
                                 executeToast("Incorrect  password");  
               btnLogin.setOnClickListener(this);                                  break;  
               btnRegister.setOnClickListener(this);                          default:  
                                 executeToast("Connection  error");  
                 }  
       }    
         }  
       @Override    
       public  void  onClick(View  v)  {          public  void  keysGenerated(BigInteger[]  
               switch  (v.getId()){   keys){  
                       case  R.id.button2:                  N  =  keys[0];  
                               boolean  isComplete  =  true;                  e  =  keys[1];  
                               if                  d  =  keys[2];  
(txtUsername.getText().toString().length()  ==    
0  ||  txtPassword.getText().toString().length()                  new  UpdateKeyTask(this,  ""+N+"-­‐"+e,  
==  0){   userInfo[2]).execute();  
                                       isComplete  =  false;          }  
                               }    

 
xii  
 

       public  void    keysUpdated(String  str){                  executeToast(str);  


               DBHelper  db  =  new  DBHelper(this);    
               db.insertUser(userInfo[0],  userInfo[1],                  Intent  intent  =  new  Intent(this,  
userInfo[2],  ""+N+"-­‐"+d,  ""+N+"-­‐"+e,   ContactsTabActivity.class);  
userInfo[3]);                  startActivity(intent);  
               System.out.println("User  saved  in  DB");                  this.finish();  
               ArrayList<String>  userSaved  =          }  
db.getUser();    
                       public  void  executeToast(String  msg){  
System.out.println(""+userSaved.get(0)+"\n"+                Toast  toast  =  Toast.makeText(this,  msg,  
userSaved.get(1)+"\n"+userSaved.get(2)+"\n" Toast.LENGTH_SHORT);  
+userSaved.get(3)+"\n"+userSaved.get(4)+"\n                toast.show();  
"+userSaved.get(5)+"\n"+userSaved.get(6)+"\        }  
n");   }  
 
 
Ø RegisterActivity.java  
package                  setContentView(R.layout.activity_register);  
com.example.ricardoviteri.safetimeapp;    
                 txtName  =  (EditText)  
import  java.io.ByteArrayInputStream;   findViewById(R.id.editText);  
import  java.io.ByteArrayOutputStream;                  txtPhone  =  (EditText)  
import  java.lang.reflect.Array;   findViewById(R.id.editText7);  
import  java.math.BigInteger;                  txtEmail  =  (EditText)  
import  java.util.ArrayList;   findViewById(R.id.editText2);  
import  java.util.List;                  txtPass  =  (EditText)  
import  java.util.Random;   findViewById(R.id.editText3);  
import  android.app.Activity;                  txtRepPass  =  (EditText)  
import  android.content.Intent;   findViewById(R.id.editText4);  
import  android.graphics.Bitmap;                  btnRegister  =  (Button)  
import   findViewById(R.id.button);  
android.graphics.drawable.BitmapDrawable;                  imgTest  =  (ImageView)  
import  android.graphics.drawable.Drawable;   findViewById(R.id.imageView);  
import  android.os.Bundle;                  txtProgress  =  (TextView)  
import  android.view.View;   findViewById(R.id.textView13);  
import  android.widget.Button;                  progBar  =  (ProgressBar)  
import  android.widget.EditText;   findViewById(R.id.progressBar2);  
import  android.widget.ImageView;                  loadingView  =  (RelativeLayout)  
import  android.widget.ProgressBar;   findViewById(R.id.loadingLayout);  
import  android.widget.RelativeLayout;    
import  android.widget.TextView;                  btnRegister.setOnClickListener(this);  
import  android.widget.Toast;          }  
import  java.util.Arrays;    
         @Override  
/**          public  void  onClick(View  v)  {  
 *  Created  by  ricardoviteri  on  6/18/15.                  loadingView.setVisibility(View.VISIBLE);  
 */                  boolean  isComplete  =  true,  passMatch  =  
public  class  RegisterActivity  extends  Activity   true;  
implements  View.OnClickListener{                  System.out.println("Button  pushed!");  
                 if  (txtName.getText().toString().length()  >  
       EditText  txtName,  txtEmail,  txtPass,   0){  
txtRepPass,  txtPhone;                          name  =  txtName.getText().toString();  
       ImageView  imgTest;                  }else{  
       TextView  txtProgress;                          isComplete  =  false;  
       ProgressBar  progBar;                  }  
       RelativeLayout  loadingView;    
       Button  btnRegister;                  if  (txtPhone.getText().toString().length()  >  
       BigInteger  firstPrime,  secondPrime,  N,  e,  d;   0){  
       String  name,  email,  password,  phone;                          phone  =  txtPhone.getText().toString();  
       byte[]  encrypted,  decrypted;                  }else{  
       int  bitlength  =  1024;                          isComplete  =  false;  
       Random  r;                  }  
   
       @Override                  if  (txtEmail.getText().toString().length()  >  
       protected  void  onCreate(Bundle   0){  
savedInstanceState)  {                          email  =  txtEmail.getText().toString();  
               super.onCreate(savedInstanceState);                  }else{  

 
xiii  
 

                       isComplete  =  false;    
               }                  //Making  sure  that  e  is  coprime  with  N  
                 while  
               if  (txtPass.getText().toString().length()  >   (phi.gcd(e).compareTo(BigInteger.ONE)  >  0  
0){   &&  e.compareTo(phi)  <  0  )  {  
                       password  =  txtPass.getText().toString();                          e.add(BigInteger.ONE);  
               }else{                  }  
                       isComplete  =  false;    
               }                  //Obtain  the  private  key  by  calculating  e  
  inverse  module  of  phi  
               if  (txtRepPass.getText().toString().length()                  d  =  e.modInverse(phi);  
>  0){    
                       if                  System.out.println("Finish  key  
(!txtRepPass.getText().toString().equals(passw generation");  
ord)){    
                               passMatch  =  false;                  /*  
                       }                  Drawable  d  =  
               }else{   getResources().getDrawable(R.drawable.shefu
                       isComplete  =  false;   ni);  
               }                  Bitmap  bitmap  =  
  ((BitmapDrawable)d).getBitmap();  
               if  (isComplete){                  ByteArrayOutputStream  stream  =  new  
                       if  (passMatch){   ByteArrayOutputStream();  
                               System.out.println("Register                  
Successful");   bitmap.compress(Bitmap.CompressFormat.JPE
                               //keyGeneration();   G,  100,  stream);  
                 byte[]  bitmapdata  =  stream.toByteArray();  
                               new    
KeyGenerationTask(this).execute();                  Drawable  d2  =  
  getResources().getDrawable(R.drawable.banan
                       }else{   a);  
                               Toast  toast  =  Toast.makeText(this,                  Bitmap  bitmap2  =  
"Passwords  does  not  match",   ((BitmapDrawable)d2).getBitmap();  
Toast.LENGTH_SHORT);                  ByteArrayOutputStream  stream2  =  new  
                               toast.show();   ByteArrayOutputStream();  
                       }                  
               }else{   bitmap2.compress(Bitmap.CompressFormat.JP
                       Toast  toast  =  Toast.makeText(this,   EG,  100,  stream2);  
"Fields  are  not  complete",                  byte[]  bitmapdata2  =  
Toast.LENGTH_SHORT);   stream2.toByteArray();  
                       toast.show();    
               }                  int  counter  =  0;  
               //keyGeneration();                  for  (int  i  =  0;  i  <  (bitmapdata.length  <  
       }   bitmapdata2.length  ?  bitmapdata.length  :  
  bitmapdata2.length);  i++){  
       public  void  keyGeneration(){                          if  ((int)bitmapdata[i]  ==  
               //Generate  a  random  number  and  look  for   (int)bitmapdata2[i]){  
two  prime  numbers  of  "bitlength"  size                                  counter++;  
               r  =  new  Random();                          }else{  
               firstPrime  =                                  break;  
BigInteger.probablePrime(bitlength,  r);                          }  
               secondPrime  =                  }  
BigInteger.probablePrime(bitlength,  r);    
                 //163  header  
               //First  we  need  to  obtain  the  number  N  =    
firstPrime*secondPrime                  System.out.println("Size  of  picture  1  is:  
               N  =  firstPrime.multiply(secondPrime);   "+bitmapdata.length+"  bytes");  
                 System.out.println("Size  of  picture  2  is:  
               //use  Euler  totient  function  to  obtain  phi   "+bitmapdata2.length+"  bytes");  
(phi(N))                  System.out.println("Header  size  of  pictures  
               BigInteger  phi  =   is:  "+counter+"  bytes");  
N.subtract(firstPrime.add(secondPrime).subtr  
act(BigInteger.ONE));    
   
               //Obtain  a  prime  number  between  0  and  N                  new  
(should  be  coprime  with  phi)   EncryptPictureTask(this).execute(bitmapdata)
               e  =  BigInteger.probablePrime(bitlength/2,   ;  
r);                  txtProgress.setText("Encrypting...");  
               txtProgress.setVisibility(View.VISIBLE);  

 
xiv  
 

               progBar.setVisibility(View.VISIBLE);                          encryptedMsg  =  
               */   encryptedMsg.modPow(e,  N);  
       }                          byte[]  encMsgBytestemp  =  
  encryptedMsg.toByteArray();  
       public  void  keysGenerated(BigInteger[]                          byte[]  encMsgBytes  =  new  
keys){   byte[encMsgBytestemp.length+1];  
               N  =  keys[0];                          for  (int  i  =  0;  i<encMsgBytes.length;  i++){  
               e  =  keys[1];                                  if  (i  ==  encMsgBytes.length-­‐1){  
               d  =  keys[2];                                          encMsgBytes[i]  =  (byte)1;  
                                 }else{  
               new  RegisterUserTask(this,  name,  phone,                                          encMsgBytes[i]  =  
email,  password,  ""+N+"-­‐"+e).execute();   encMsgBytestemp[i];  
       }                                  }  
                         }  
       public  void  startApp(int  result,  String  port){                          return  encMsgBytes;  
               loadingView.setVisibility(View.INVISIBLE);                  }else{  
               /**                          encryptedMsg  =  
                 *  1:  Successfully  added   encryptedMsg.modPow(e,  N);  
                 *  2:  Email  already  registered                          byte[]  encMsgBytestemp  =  
                 *  3:  User  not  received   encryptedMsg.toByteArray();  
               **/                          byte[]  encMsgBytes  =  new  
               switch(result){   byte[encMsgBytestemp.length+1];  
                       case  1:                          for  (int  i  =  0;  i<encMsgBytes.length;  i++){  
                               DBHelper  db  =  new  DBHelper(this);                                  if  (i  ==  encMsgBytes.length-­‐1){  
                               db.insertUser(name,  phone,  email,                                          encMsgBytes[i]  =  (byte)2;  
""+N+"-­‐"+d,  ""+N+"-­‐"+e,  port);                                  }else{  
                               System.out.println("User  saved  in                                          encMsgBytes[i]  =  
DB");   encMsgBytestemp[i];  
                               ArrayList<String>  userSaved  =                                  }  
db.getUser();                          }  
                                                       return  encMsgBytes;  
System.out.println(""+userSaved.get(0)+"\n"+                }  
userSaved.get(1)+"\n"+userSaved.get(2)+"\n"                //return  encryptedMsg.toByteArray();  
+userSaved.get(3)+"\n"+userSaved.get(4)+"\n                //return  (new  BigInteger(M)).modPow(e,  
"+userSaved.get(5)+"\n"+userSaved.get(6)+"\ N).toByteArray();  
n");          }  
   
         public  byte[]  messageDecryption(byte[]  D){  
                               Intent  intent  =  new  Intent(this,                  byte[]  msgToDecrypt  =  new  byte[D.length-­‐
ContactsTabActivity.class);   1];  
                               startActivity(intent);                  for  (int  i  =  0;  i<D.length-­‐1;  i++){  
                               this.finish();                          msgToDecrypt[i]  =  D[i];  
                               break;                  }  
                       case  2:                  System.out.println(""+D[D.length-­‐1]);  
                               executeToast("Email  already                  BigInteger  encryptedMsg  =  new  
registered");   BigInteger(msgToDecrypt);  
                               break;    
                       default:                  encryptedMsg  =  encryptedMsg.modPow(d,  
                               executeToast("Connection  error");   N);  
               }    
                 if  (D[D.length-­‐1]  ==  (byte)1){  
       }                          encryptedMsg  =  
  encryptedMsg.multiply(BigInteger.valueOf(-­‐
       public  void  executeToast(String  msg){   1));  
               Toast  toast  =  Toast.makeText(this,  msg,                  }  
Toast.LENGTH_SHORT);    
               toast.show();                  return  encryptedMsg.toByteArray();  
       }                  //return  (new  BigInteger(D)).modPow(d,  
  N).toByteArray();  
       /*          }  
       public  byte[]  messageEncryption(byte[]  M){    
               BigInteger  encryptedMsg  =  new          private  static  String  bytesToString(byte[]  
BigInteger(M);   encrypted)  {  
               if  (encryptedMsg.signum()  !=  1){                  String  test  =  "";  
                       encryptedMsg  =                  for  (byte  b  :  encrypted)  {  
encryptedMsg.multiply(BigInteger.valueOf(-­‐                        test  +=  Byte.toString(b);  
1));                  }  
               return  test;  
       }  

 
xv  
 

         public  void  
       public  static  boolean  isPrime(long  n)  {   imageWasEncrypted(ArrayList<byte[]>  
               if  (n  <=  3)  {   encImg){  
                       return  n  >  1;                  new  DecryptPictureTask(this,  
               }  else  if  (n  %  2  ==  0  ||  n  %  3  ==  0)  {   "").execute(encImg);  
                       return  false;                  txtProgress.setText("Decrypting...");  
               }  else  {          }  
                       for  (int  i  =  5;  i  *  i  <=  n;  i  +=  6)  {    
                               if  (n  %  i  ==  0  ||  n  %  (i  +  2)  ==  0)  {          public  void  displayDecriptedImg(Drawable  
                                       return  false;   img){  
                               }                  imgTest.setImageDrawable(img);  
                       }                  txtProgress.setText("Done!!");  
                       return  true;                  progBar.setVisibility(View.INVISIBLE);  
               }          }  
       }   }  
       */  
 
Ø ServerThread.java  
package                                  }  catch  (IOException  e)  {  
com.example.ricardoviteri.safetimeapp;                                          e.printStackTrace();  
                                 }  
import  android.widget.Toast;                                  //TODO:  sent  this  depending  on  if  
  there  is  something  to  send  or  not  
import  java.io.BufferedReader;                                  if  (parent.tasksToDo.size()  >  0){  
import  java.io.DataInputStream;                                          PS.println("1");  
import  java.io.DataOutputStream;                                  }else{  
import  java.io.IOException;                                          PS.println("0");  
import  java.io.InputStream;                                  }  
import  java.io.InputStreamReader;    
import  java.io.OutputStream;    
import  java.io.PrintStream;    
import  java.net.ServerSocket;                                  //initialize  reading  
import  java.net.Socket;                                  InputStreamReader  IR  =  null;  
import  java.util.ArrayList;                                  try  {  
                                         IR  =  new  
/**   InputStreamReader(sock.getInputStream());  
 *  Created  by  ricardoviteri  on  7/20/15.                                  }  catch  (IOException  e)  {  
 */                                          e.printStackTrace();  
public  class  ServerThread  extends  Thread  {                                  }  
                                 BufferedReader  BR  =  new  
       ContactsTabActivity  parent;   BufferedReader(IR);  
       String  thisUser;                                  //look  for  messages  that  might  be  
  received  by  the  server  
       public  ServerThread(ContactsTabActivity                                  String  MESSAGE  =  null;  
context,  String  user)  {                                  try  {  
               parent  =  context;                                          MESSAGE  =  BR.readLine();  
               thisUser  =  user;                                          if  (MESSAGE  ==  null){  
       }                                                  MESSAGE  =  "20";  
                                         }  
       public  void  run(){                                          //System.out.println(MESSAGE);  
                                 }  catch  (Exception  e)  {  
               while(true){                                          e.printStackTrace();  
                                         MESSAGE  =  "20";  
                       Socket  sock  =  null;                                  }  
                       try  {    
                               sock  =  new  Socket("192.168.1.103",                                  /**  
parent.Port);                                    *  1:  Listen  
                       }  catch  (IOException  e)  {                                    *  2:  Send  data  
                               //System.out.println("No                                  **/  
connection");                                  if  (Integer.parseInt(MESSAGE)  ==  1){  
                       }                                          System.out.println("Recieving  
  something  from  server");  
                       if  (sock  !=  null){                                          try  {  
                               PrintStream  PS  =  null;                                                  MESSAGE  =  BR.readLine();  
                               try  {                                                  //System.out.println(MESSAGE);  
                                       PS  =  new                                          }  catch  (Exception  e)  {  
PrintStream(sock.getOutputStream());                                                  e.printStackTrace();  

 
xvi  
 

                                               MESSAGE  =  "20";                                                  try  {  


                                       }                                                          IR  =  new  
                                       int  idTask  =   InputStreamReader(sock.getInputStream());  
Integer.parseInt(MESSAGE);                                                  }  catch  (IOException  e)  {  
                                                         e.printStackTrace();  
                                       if  (idTask  ==  10){                                                  }  
                                               try  {                                                  BR  =  new  BufferedReader(IR);  
                                                       String[]  userInfo  =  new                                                  //look  for  messages  that  might  be  
String[3];   received  by  the  server  
                                                       userInfo[0]  =  BR.readLine();                                                  MESSAGE  =  null;  
                                                       userInfo[1]  =  BR.readLine();                                                  try  {  
                                                       userInfo[2]  =  BR.readLine();                                                          MESSAGE  =  BR.readLine();  
                                                         System.out.println("command  
                                                       parent.addContact(userInfo);   received  "+MESSAGE);  
                                                                                                       }  catch  (IOException  e)  {  
//System.out.println(MESSAGE);                                                          e.printStackTrace();  
                                               }  catch  (Exception  e)  {                                                  }  
                                                       e.printStackTrace();    
                                                       MESSAGE  =  "20";                                                  /**  
                                               }                                                    *  1:  User  found  
                                       }                                                    *  2:  User  not  found  
                                                   **/  
                                       if  (idTask  ==  11){                                                  if  (Integer.parseInt(MESSAGE)  ==  
                                               System.out.println("READING   1){  
MESSAGE");                                                          System.out.println("Found  
                                               new   user");  
RecieveMessageTask(parent).execute();                                                          String[]  userInfo  =  new  
                                               /*byte[]  encMessage  =  new   String[3];  
byte[257];                                                          try  {  
                                               try  {                                                                  userInfo[0]  =  BR.readLine();  
                                                       BR.read(encMessage);                                                                  userInfo[1]  =  BR.readLine();  
                                                                                                                       userInfo[2]  =  BR.readLine();  
//System.out.println(MESSAGE);                                                                  parent.addContact(userInfo);  
                                               }  catch  (Exception  e)  {                                                          }  catch  (IOException  e)  {  
                                                       e.printStackTrace();                                                                  e.printStackTrace();  
                                                       MESSAGE  =  "20";                                                          }  
                                               }*/                                                          if  (parent.tasksToDo.size()  >  0){  
                                                                 parent.tasksToDo.remove(0);  
                                                         }  
                                       }    
                               }                                                  }else{  
                                                         System.out.println("Not  found");  
                               if  (Integer.parseInt(MESSAGE)  ==  2){                                                          parent.runOnUiThread(new  
                                       final  ArrayList<Object>  task  =   Runnable()  {  
parent.tasksToDo.get(0);                                                                  public  void  run()  {  
                                                                         //Toast.makeText(parent,  
                                       int  idTask  =   "Hello",  Toast.LENGTH_SHORT).show();  
Integer.parseInt(task.get(0).toString());                                                                          
                                       /**   parent.contactNotFound(task.get(1).toString()
                                         *  ***********  idTask  ****************   );  
                                         *            10:  Add  Contact    
                                         *            11:  Send  Message                                                                  }  
                                         */                                                          });  
                                       if  (idTask  ==  10){                                                          parent.tasksToDo.remove(0);  
                                               PS  =  null;                                                  }  
                                               try  {                                          }  
                                                       PS  =  new    
PrintStream(sock.getOutputStream());                                          if  (idTask  ==  11){  
                                               }  catch  (IOException  e)  {                                                  PS  =  null;  
                                                       e.printStackTrace();                                                  try  {  
                                               }                                                          PS  =  new  
                                               PS.println("1");   PrintStream(sock.getOutputStream());  
                                               PS.println(task.get(1).toString());                                                  }  catch  (IOException  e)  {  
                                               System.out.println("Request                                                          e.printStackTrace();  
sent");                                                  }  
                                                 PS.println("2");  
                                               //initialize  reading                                                  
                                               IR  =  null;   //PS.println(task.get(1).toString());  
 

 
xvii  
 

                                               SOK_CLIENT_BASIC  cosa  =  new                                                                  e.printStackTrace();  


SOK_CLIENT_BASIC(task.get(2),                                                          }  
task.get(1).toString(),  thisUser);                                                  }  
                                               try  {    
                                                       cosa.run();                                                  //initialize  reading  
                                               }  catch  (Exception  e)  {                                                  IR  =  null;  
                                                       e.printStackTrace();                                                  try  {  
                                               }                                                          IR  =  new  
  InputStreamReader(sock.getInputStream());  
                                                 }  catch  (IOException  e)  {  
                                               /*                                                          e.printStackTrace();  
                                               //Send  de  message  byte[]                                                  }  
                                               byte[]  encMessage  =  (byte[])                                                  BR  =  new  BufferedReader(IR);  
task.get(2);                                                  //look  for  messages  that  might  be  
                                               System.out.println(new   received  by  the  server  
String(encMessage));                                                  MESSAGE  =  null;  
                                               OutputStream  out  =  null;                                                  try  {  
                                               try  {                                                          MESSAGE  =  BR.readLine();  
                                                       out  =  sock.getOutputStream();                                                  }  catch  (IOException  e)  {  
                                               }  catch  (IOException  e)  {                                                          e.printStackTrace();  
                                                       e.printStackTrace();                                                  }  
                                               }                                                  System.out.println(MESSAGE);  
                                               DataOutputStream  dos  =  new                                                  */  
DataOutputStream(out);    
                                                 parent.tasksToDo.remove(0);  
                                               try  {                                                  System.out.println("Erased");  
                                                         
dos.writeInt(encMessage.length);    
                                               }  catch  (IOException  e)  {                                          }  
                                                       e.printStackTrace();    
                                               }    
                                               if  (encMessage.length  >  0)  {                                  }  
                                                       try  {                          }  
                                                               dos.write(encMessage,  0,    
encMessage.length);                  }  
                                                                 
System.out.println("Sending...");          }  
                                                       }  catch  (IOException  e)  {   }  
 
Ø AddContactTask.java  
package          }  
com.example.ricardoviteri.safetimeapp;    
         @Override  
import  android.content.Context;          protected  String[]  doInBackground(String...  
import  android.os.AsyncTask;   params)  {  
   
import  java.io.BufferedReader;                  Socket  sock  =  null;  
import  java.io.IOException;                  try  {  
import  java.io.InputStreamReader;                          DBHelper  db  =  new  
import  java.io.PrintStream;   DBHelper(context.getActivity());  
import  java.net.Socket;                          ArrayList<String>  userSaved  =  
import  java.util.ArrayList;   db.getUser();  
                         sock  =  new  Socket("192.168.1.103",  
/**   9003);//Integer.parseInt(userSaved.get(6)));/
 *  Created  by  ricardoviteri  on  7/19/15.   /userSaved.get(6)));  
 */                  }  catch  (IOException  e)  {  
public  class  AddContactTask  extends                          e.printStackTrace();  
AsyncTask<String,  Integer,  String[]>  {                  }  
   
       AddContactTab  context;                  PrintStream  PS  =  null;  
       String  usrToAdd;                  try  {  
       String[]  userInfo  =  new  String[3];                          PS  =  new  
  PrintStream(sock.getOutputStream());  
       public  AddContactTask(AddContactTab  ctx,                  }  catch  (IOException  e)  {  
String  user)  {                          e.printStackTrace();  
               context  =  ctx;                  }  
               usrToAdd  =  user;                  PS.println("1");  

 
xviii  
 

               PS.println(usrToAdd);                                  userInfo[2]  =  BR.readLine();  


                         }  catch  (IOException  e)  {  
               //initialize  reading                                  e.printStackTrace();  
               InputStreamReader  IR  =  null;                          }  
               try  {    
                       IR  =  new                  }else{  
InputStreamReader(sock.getInputStream());                          this.cancel(true);  
               }  catch  (IOException  e)  {                  }  
                       e.printStackTrace();    
               }                  return  userInfo;  
               BufferedReader  BR  =  new          }  
BufferedReader(IR);    
               //look  for  messages  that  might  be  received          @Override  
by  the  server          protected  void  onPostExecute(String[]  
               String  MESSAGE  =  null;   strings)  {  
               try  {                  super.onPostExecute(strings);  
                       MESSAGE  =  BR.readLine();                  context.addContact(strings);  
                       System.out.println(MESSAGE);          }  
               }  catch  (IOException  e)  {    
                       e.printStackTrace();          @Override  
               }          protected  void  onCancelled()  {  
                 super.onCancelled();  
               /**                  context.contactNotFound();  
                 *  1:  User  found    
                 *  2:  User  not  found          }  
               **/    
               if  (Integer.parseInt(MESSAGE)  ==  1){          @Override  
         protected  void  onPreExecute()  {  
                       try  {                  super.onPreExecute();  
                               userInfo[0]  =  BR.readLine();          }  
                               userInfo[1]  =  BR.readLine();   }  
 
Ø LoginTask.java  
package          protected  Integer  doInBackground(String...  
com.example.ricardoviteri.safetimeapp;   params)  {  
                 String[]  user  =  new  String[2];  
import  android.content.Context;                  user[0]  =  usr;  
import  android.os.AsyncTask;                  user[1]  =  pass;  
   
import  java.io.BufferedReader;                  Socket  sock  =  null;  
import  java.io.IOException;                  try  {  
import  java.io.InputStream;                          sock  =  new  Socket("192.168.1.103",  
import  java.io.InputStreamReader;   9001);  
import  java.io.ObjectInputStream;                  }  catch  (IOException  e)  {  
import  java.io.ObjectOutputStream;                          e.printStackTrace();  
import  java.io.PrintStream;                  }  
import  java.net.Socket;    
   
/**                  ObjectOutputStream  out  =  null;  
 *  Created  by  ricardoviteri  on  7/16/15.                  try  {  
 */                          out  =  new  
public  class  LoginTask  extends   ObjectOutputStream(sock.getOutputStream());  
AsyncTask<String,  Integer,  Integer>  {                  }  catch  (IOException  e)  {  
                         e.printStackTrace();  
       Context  context;                  }  
       String  usr,  pass;                  try  {  
       String[]  userInfo  =  new  String[4];                          out.writeObject(user);  
                 }  catch  (IOException  e)  {  
       public  LoginTask(Context  ctx,  String  user,                          e.printStackTrace();  
String  password)  {                  }  
               context  =  ctx;    
               usr  =  user;    
               pass  =  password;                  //initialize  reading  
       }                  InputStreamReader  IR  =  null;  
                 try  {  
       @Override                          IR  =  new  
InputStreamReader(sock.getInputStream());  

 
xix  
 

               }  catch  (IOException  e)  {                          }  


                       e.printStackTrace();                  }  
               }    
               BufferedReader  BR  =  new    
BufferedReader(IR);                  return  Integer.parseInt(MESSAGE);  
               //look  for  messages  that  might  be  received          }  
by  the  server    
               String  MESSAGE  =  null;          @Override  
               try  {          protected  void  onPreExecute()  {  
                       MESSAGE  =  BR.readLine();                  super.onPreExecute();  
                       System.out.println(MESSAGE);          }  
               }  catch  (IOException  e)  {    
                       e.printStackTrace();          @Override  
               }          protected  void  onPostExecute(Integer  
  integer)  {  
               if  (Integer.parseInt(MESSAGE)  ==  2){                  super.onPostExecute(integer);  
                 
                       try  {   ((LoginActivity)context).loginAction(integer,  
                               userInfo[0]  =  BR.readLine();   userInfo);  
                               userInfo[1]  =  BR.readLine();          }  
                               userInfo[2]  =  BR.readLine();    
                               userInfo[3]  =  BR.readLine();          @Override  
                       }  catch  (IOException  e)  {          protected  void  onProgressUpdate(Integer...  
                               e.printStackTrace();   values)  {  
                       }                  super.onProgressUpdate(values);  
         }  
                       PrintStream  PS  =  null;    
                       try  {          @Override  
                               PS  =  new          protected  void  onCancelled(Integer  integer)  
PrintStream(sock.getOutputStream());   {  
                               PS.println("UserInfo  received");                  super.onCancelled(integer);  
                       }  catch  (IOException  e)  {          }  
                               e.printStackTrace();   }  
 
Ø RegisterUserTask.java  
package                  context  =  ctx;  
com.example.ricardoviteri.safetimeapp;          }  
   
import  android.content.Context;          @Override  
import  android.os.AsyncTask;          protected  Integer  doInBackground(String...  
  params)  {  
import  java.io.BufferedReader;    
import  java.io.DataOutputStream;                  String[]  user  =  new  String[5];  
import  java.io.IOException;                  user[0]  =  usrName;  
import  java.io.InputStreamReader;                  user[1]  =  usrPhone;  
import  java.io.ObjectOutputStream;                  user[2]  =  usrEmail;  
import  java.io.OutputStream;                  user[3]  =  usrPass;  
import  java.net.Socket;                  user[4]  =  usrPKey;  
   
/**                  Socket  sock  =  null;  
 *  Created  by  ricardoviteri  on  7/14/15.                  try  {  
 */                          sock  =  new  Socket("192.168.1.103",  
public  class  RegisterUserTask  extends   9000);  
AsyncTask<String,  Integer,  Integer>{                  }  catch  (IOException  e)  {  
                         e.printStackTrace();  
       String  usrName,  usrPhone,  usrEmail,                  }  
usrPass,  usrPKey,  port;    
       Context  context;    
                 ObjectOutputStream  out  =  null;  
       public  RegisterUserTask(Context  ctx,  String                  try  {  
name,  String  phone,  String  email,  String  pass,                          out  =  new  
String  pKey)  {   ObjectOutputStream(sock.getOutputStream());  
               usrName  =  name;                  }  catch  (IOException  e)  {  
               usrPhone  =  phone;                          e.printStackTrace();  
               usrEmail  =  email;                  }  
               usrPass  =  pass;                  try  {  
               usrPKey  =  pKey;                          out.writeObject(user);  

 
xx  
 

               }  catch  (IOException  e)  {                  return  Integer.parseInt(MESSAGE);  


                       e.printStackTrace();          }  
               }    
         @Override  
         protected  void  onPreExecute()  {  
               //initialize  reading                  super.onPreExecute();  
               InputStreamReader  IR  =  null;          }  
               try  {    
                       IR  =  new          @Override  
InputStreamReader(sock.getInputStream());          protected  void  onProgressUpdate(Integer...  
               }  catch  (IOException  e)  {   values)  {  
                       e.printStackTrace();                  super.onProgressUpdate(values);  
               }          }  
               BufferedReader  BR  =  new    
BufferedReader(IR);          @Override  
               //look  for  messages  that  might  be  received          protected  void  onPostExecute(Integer  code)  
by  the  server   {  
               String  MESSAGE  =  null;                  super.onPostExecute(code);  
               try  {                  ((RegisterActivity)context).startApp(code,  
                       MESSAGE  =  BR.readLine();   port);  
                       System.out.println(MESSAGE);          }  
                       if  (Integer.parseInt(MESSAGE)  ==  1){    
                               port  =  BR.readLine();          @Override  
                       }          protected  void  onCancelled()  {  
               }  catch  (IOException  e)  {                  super.onCancelled();  
                       e.printStackTrace();          }  
               }   }  
 
 
Ø KeyGenerationTask.java  
package                  //First  we  need  to  obtain  the  number  N  =  
com.example.ricardoviteri.safetimeapp;   firstPrime*secondPrime  
                 N  =  firstPrime.multiply(secondPrime);  
import  android.content.Context;    
import  android.os.AsyncTask;                  //use  Euler  totient  function  to  obtain  phi  
  (phi(N))  
import  java.math.BigInteger;                  BigInteger  phi  =  
import  java.util.Random;   N.subtract(firstPrime.add(secondPrime).subtr
  act(BigInteger.ONE));  
/**    
 *  Created  by  ricardoviteri  on  7/16/15.                  //Obtain  a  prime  number  between  0  and  N  
 */   (should  be  coprime  with  phi)  
public  class  KeyGenerationTask  extends                  e  =  BigInteger.probablePrime(bitlength/2,  
AsyncTask<String,  Integer,  BigInteger[]>  {   r);  
   
       BigInteger  firstPrime,  secondPrime,  N,  e,  d;                  //Making  sure  that  e  is  coprime  with  N  
       Random  r;                  while  
       int  bitlength  =  1024;   (phi.gcd(e).compareTo(BigInteger.ONE)  >  0  
       BigInteger[]  keys  =  new  BigInteger[3];   &&  e.compareTo(phi)  <  0  )  {  
       Context  context;                          e.add(BigInteger.ONE);  
                 }  
       public  KeyGenerationTask(Context  ctx)  {    
               context  =  ctx;                  //Obtain  the  private  key  by  calculating  e  
       }   inverse  module  of  phi  
                 d  =  e.modInverse(phi);  
       @Override    
       protected  BigInteger[]                  System.out.println("Finish  key  
doInBackground(String...  params)  {   generation");  
               //Generate  a  random  number  and  look  for                  keys[0]  =  N;  
two  prime  numbers  of  "bitlength"  size                  keys[1]  =  e;  
               r  =  new  Random();                  keys[2]  =  d;  
               firstPrime  =    
BigInteger.probablePrime(bitlength,  r);                  return  keys;  
               secondPrime  =          }  
BigInteger.probablePrime(bitlength,  r);    
         @Override  

 
xxi  
 

       protected  void  onPostExecute(BigInteger[]                  }else{  


bigIntegers)  {                          ((LoginActivity)  
               super.onPostExecute(bigIntegers);   context).keysGenerated(bigIntegers);  
               if  (context  instanceof  RegisterActivity)  {                  }  
                       ((RegisterActivity)          }  
context).keysGenerated(bigIntegers);   }  
 
Ø EncryptionPictureTask.java  
package                          cosa.add(contents);  
com.example.ricardoviteri.safetimeapp;    
                 }  
import  android.content.Context;                  System.out.println("Finish  Padding  
import  android.os.AsyncTask;   "+cosa.get(cosa.size()-­‐1).length);  
   
import  java.math.BigInteger;                  int  listSize  =  cosa.size();  
import  java.util.ArrayList;                  for  (int  i  =  0;  i<listSize;  i++){  
                         byte[]  temp  =  cosa.get(i);  
/**                          byte[]  temp2  =  
 *  Created  by  ricardoviteri  on  7/2/15.   messageEncryption(temp);  
 */                          cosa.remove(i);  
public  class  EncryptPictureTask  extends                          cosa.add(i,  temp2);  
AsyncTask<byte[],  Integer,  ArrayList<byte[]>>                          //System.out.println("Encrypted  "+i);  
{                  }  
                 return  cosa;  
       BigInteger  N,  e;          }  
       Context  context;    
       String  whoToSend;          @Override  
         protected  void  onPreExecute()  {  
       public  EncryptPictureTask(Context  ctx,                  super.onPreExecute();  
BigInteger  iN,  BigInteger  ie,  String  user)  {          }  
               context  =  ctx;    
               N  =  iN;          @Override  
               e  =  ie;          protected  void  
               whoToSend  =  user;   onPostExecute(ArrayList<byte[]>  bytes)  {  
       }                  super.onPostExecute(bytes);  
                 System.out.println("Encryption  done!!");  
       @Override                  ArrayList<Object>  task  =  new  
       protected  ArrayList<byte[]>   ArrayList<Object>();  
doInBackground(byte[]...  params)  {                  task.add("11");  
               //DBHelper  db  =  new  DBHelper(context);                  task.add(whoToSend);  
               //ArrayList<String>  user  =  db.getUser();                  task.add(bytes);  
               byte[]  bitmapdata  =  params[0];    
                 
               /*   ((ContactsTabActivity)context).tasksToDo.add(
               N  =  BigInteger.valueOf(0);   task);  
               e  =  BigInteger.valueOf(0);          }  
   
               N  =  N.add(new          @Override  
BigInteger((user.get(5).split("-­‐"))[0]));          protected  void  onProgressUpdate(Integer...  
               e  =  e.add(new   values)  {  
BigInteger((user.get(5).split("-­‐"))[1]));                  super.onProgressUpdate(values);  
               */          }  
   
               int  rounds  =  (int)          @Override  
Math.ceil((float)bitmapdata.length  /  255.0);          protected  void  onCancelled()  {  
               ArrayList<byte[]>  cosa  =  new                  super.onCancelled();  
ArrayList<byte[]>();          }  
   
               for  (int  i  =  0;  i<rounds;  i++){          public  byte[]  messageEncryption(byte[]  M){  
                       byte[]  contents  =  new                  BigInteger  encryptedMsg  =  new  
byte[(bitmapdata.length-­‐(255*i)<255  ?   BigInteger(M);  
bitmapdata.length-­‐(255*i)  :  255)];                  if  (encryptedMsg.signum()  !=  1){  
                       for  (int  j  =  0;  j<(bitmapdata.length-­‐                        encryptedMsg  =  
(255*i)<255  ?  bitmapdata.length-­‐(255*i)  :   encryptedMsg.multiply(BigInteger.valueOf(-­‐
255);  j++){   1));  
                               contents[j]  =  bitmapdata[i*255+j];                          encryptedMsg  =  
                       }   encryptedMsg.modPow(e,  N);  

 
xxii  
 

                       byte[]  encMsgBytestemp  =                          byte[]  encMsgBytes  =  new  


encryptedMsg.toByteArray();   byte[encMsgBytestemp.length+1];  
                       byte[]  encMsgBytes  =  new                          for  (int  i  =  0;  i<encMsgBytes.length;  i++){  
byte[encMsgBytestemp.length+1];                                  if  (i  ==  encMsgBytes.length-­‐1){  
                       for  (int  i  =  0;  i<encMsgBytes.length;  i++){                                          encMsgBytes[i]  =  (byte)2;  
                               if  (i  ==  encMsgBytes.length-­‐1){                                  }else{  
                                       encMsgBytes[i]  =  (byte)1;                                          encMsgBytes[i]  =  
                               }else{   encMsgBytestemp[i];  
                                       encMsgBytes[i]  =                                  }  
encMsgBytestemp[i];                          }  
                               }                          return  encMsgBytes;  
                       }                  }  
                       return  encMsgBytes;                  //return  encryptedMsg.toByteArray();  
               }else{                  //return  (new  BigInteger(M)).modPow(e,  
                       encryptedMsg  =   N).toByteArray();  
encryptedMsg.modPow(e,  N);          }  
                       byte[]  encMsgBytestemp  =   }  
encryptedMsg.toByteArray();  
 
Ø DecryptPictureTask.java  
package    
com.example.ricardoviteri.safetimeapp;                  for  (int  i  =  0;  i<listSize;  i++){  
                         byte[]  temp  =  
import  android.content.Context;   messageDecryption(imgBytesEnc.get(i));  
import  android.graphics.drawable.Drawable;                          imgBytesEnc.remove(i);  
import  android.os.AsyncTask;                          imgBytesEnc.add(i,  temp);  
                         //System.out.println("Decrypted  "+i);  
import  java.io.ByteArrayInputStream;                  }  
import  java.math.BigInteger;    
import  java.util.ArrayList;                  System.out.println("Decrypted  ");  
   
/**                  int  counter  =  0;  
 *  Created  by  ricardoviteri  on  7/2/15.                  for(int  i  =  0;  i  <  imgBytesEnc.size();  i++){  
 */                          counter  +=  imgBytesEnc.get(i).length;  
public  class  DecryptPictureTask  extends                          if  (imgBytesEnc.get(i).length  <  255  &&  i  
AsyncTask<ArrayList<byte[]>,  Integer,   !=  imgBytesEnc.size()-­‐1){  
Drawable>  {                                  counter++;  
                         }  
       Context  context;                  }  
       BigInteger  N,  d;    
       String  fromUser;                  byte[]  newBitmapData  =  new  
  byte[counter];  
       public  DecryptPictureTask(Context  context,                  int  newCounter  =  0;  
String  user)  {                  for  (int  i  =  0;  i  <  imgBytesEnc.size();  i++){  
               this.context  =  context;                          for  (int  j  =  0;  j  <  
               fromUser  =  user;   imgBytesEnc.get(i).length;  j++){  
       }                                  if  (imgBytesEnc.get(i).length  <  255  &&  
  j==0  &&  i  !=  imgBytesEnc.size()-­‐1){  
       @Override                                          newBitmapData[newCounter]  =  (i  
       protected  Drawable   ==  0  ?  (byte)-­‐1  :  (byte)0);  
doInBackground(ArrayList<byte[]>...  params)                                          newCounter++;  
{                                  }  
               DBHelper  db  =  new  DBHelper(context);                                  newBitmapData[newCounter]  =  
               ArrayList<String>  user  =  db.getUser();   imgBytesEnc.get(i)[j];  
                                 newCounter++;  
               N  =  BigInteger.valueOf(0);                          }  
               d  =  BigInteger.valueOf(0);                  }  
   
               N  =  N.add(new                  System.out.println("Reassembled  ");  
BigInteger((user.get(5).split("-­‐"))[0]));                  ByteArrayInputStream  is  =  new  
               d  =  d.add(new   ByteArrayInputStream(newBitmapData);  
BigInteger((user.get(4).split("-­‐"))[1]));    
                 Drawable  drw  =  
               ArrayList<byte[]>  imgBytesEnc  =   Drawable.createFromStream(is,  
params[0];   "articleImage");  
   
               int  listSize  =  imgBytesEnc.size();    

 
xxiii  
 

               return  drw;                  super.onCancelled(drawable);  


       }          }  
   
       @Override          public  byte[]  messageDecryption(byte[]  D){  
       protected  void  onPreExecute()  {                  byte[]  msgToDecrypt  =  new  byte[D.length-­‐
               super.onPreExecute();   1];  
       }                  for  (int  i  =  0;  i<D.length-­‐1;  i++){  
                         msgToDecrypt[i]  =  D[i];  
       @Override                  }  
       protected  void  onPostExecute(Drawable                  System.out.println(""+D[D.length-­‐1]);  
drawable)  {                  BigInteger  encryptedMsg  =  new  
               super.onPostExecute(drawable);   BigInteger(msgToDecrypt);  
                 
((ContactsTabActivity)context).addToConversa                encryptedMsg  =  encryptedMsg.modPow(d,  
tion(fromUser,  drawable);   N);  
   
       }                  if  (D[D.length-­‐1]  ==  (byte)1){  
                         encryptedMsg  =  
       @Override   encryptedMsg.multiply(BigInteger.valueOf(-­‐
       protected  void  onProgressUpdate(Integer...   1));  
values)  {                  }  
               super.onProgressUpdate(values);    
       }                  return  encryptedMsg.toByteArray();  
                 //return  (new  BigInteger(D)).modPow(d,  
       @Override   N).toByteArray();  
       protected  void  onCancelled(Drawable          }  
drawable)  {   }  
 
Ø ReceiveMessageTask.java  
package                          sock  =  new  Socket("192.168.1.103",  
com.example.ricardoviteri.safetimeapp;   8998);  
                 }  catch  (IOException  e)  {  
import  android.content.Context;                          e.printStackTrace();  
import  android.os.AsyncTask;                  }  
   
import  java.io.BufferedReader;                  OutputStream  out  =  null;  
import  java.io.DataInputStream;                  try  {  
import  java.io.DataOutputStream;                          out  =  sock.getOutputStream();  
import  java.io.IOException;                          DataOutputStream  dos  =  new  
import  java.io.InputStream;   DataOutputStream(out);  
import  java.io.InputStreamReader;                          dos.writeChar('E');  
import  java.io.OutputStream;                  }  catch  (IOException  e)  {  
import  java.net.Socket;                          e.printStackTrace();  
import  java.util.ArrayList;                  }  
   
/**    
 *  Created  by  ricardoviteri  on  7/22/15.                  InputStream  in  =  null;  
 */                  try  {  
public  class  RecieveMessageTask  extends                          in  =  sock.getInputStream();  
AsyncTask<ArrayList<Object>,  Integer,                          DataInputStream  dis  =  new  
Integer>  {   DataInputStream(in);  
                         //dis.wait(1000);  
       Context  context;    
       String  fromUser;                          char  type  =  dis.readChar();  
       Object  message;                          if  (type  ==  'M'){  
                                 int  len  =  dis.readInt();  
       public  RecieveMessageTask(Context  ctx){                                  System.out.println("size:  "+len);  
               context  =  ctx;                                  byte[]  data  =  new  byte[len];  
       }                                  if  (len  >  0){  
                                         dis.readFully(data);  
       @Override                                  }  
       protected  Integer                                  System.out.println("message:  "+new  
doInBackground(ArrayList<Object>...  params)   String(data));  
{                                  message  =  data;  
                         }else{  
               Socket  sock  =  null;                                  int  imgLen  =  dis.readInt();  
               try  {                                  System.out.println("size:  "+imgLen);  

 
xxiv  
 

                 //look  for  messages  that  might  be  received  


                               ArrayList<byte[]>  image  =  new   by  the  server  
ArrayList<byte[]>();    
                 try  {  
                               for  (int  i  =  0;  i  <  imgLen;  i++){                          fromUser  =  BR.readLine();  
                                       System.out.println("Receiving");                          System.out.println("from:  "+fromUser);  
                                       int  len  =  dis.readInt();                          //System.out.println(MESSAGE);  
                                       byte[]  data  =  new  byte[len];                  }  catch  (Exception  e)  {  
                                       if  (len  >  0){                          e.printStackTrace();  
                                               dis.readFully(data);                  }  
                                       }                  try  {  
                                       image.add(data);                          sock.close();  
                                       System.out.println("Received  #"+i);                  }  catch  (IOException  e)  {  
                               }                          e.printStackTrace();  
                               System.out.println("Info  received:                  }  
"+image.size());                  return  null;  
                               message  =  image;          }  
                       }    
         @Override  
               }  catch  (IOException  e)  {          protected  void  onPostExecute(Integer  
                       e.printStackTrace();   integer)  {  
               }                  super.onPostExecute(integer);  
                 if  (message  instanceof  byte[]){  
                         
  ((ContactsTabActivity)context).addToConversa
               //initialize  reading   tion(fromUser,  message);  
               InputStreamReader  IR  =  null;                  }else{  
               try  {                          new  DecryptPictureTask(context,  
                       IR  =  new   fromUser).execute((ArrayList<byte[]>)messag
InputStreamReader(sock.getInputStream());   e);  
               }  catch  (IOException  e)  {                  }  
                       e.printStackTrace();    
               }          }  
               BufferedReader  BR  =  new   }  
BufferedReader(IR);  
 
Ø UpdateKeyTask.java  
package          @Override  
com.example.ricardoviteri.safetimeapp;          protected  String  doInBackground(String...  
  params)  {  
import  android.content.Context;                  String[]  user  =  new  String[2];  
import  android.os.AsyncTask;                  user[0]  =  email;  
                 user[1]  =  key;  
import  java.io.BufferedReader;    
import  java.io.IOException;                  Socket  sock  =  null;  
import  java.io.InputStreamReader;                  try  {  
import  java.io.ObjectOutputStream;                          sock  =  new  Socket("192.168.1.103",  
import  java.io.PrintStream;   9002);  
import  java.net.Socket;                  }  catch  (IOException  e)  {  
                         e.printStackTrace();  
/**                  }  
 *  Created  by  ricardoviteri  on  7/16/15.    
 */    
public  class  UpdateKeyTask  extends                  ObjectOutputStream  out  =  null;  
AsyncTask<String,  Integer,  String>  {                  try  {  
                         out  =  new  
       Context  context;   ObjectOutputStream(sock.getOutputStream());  
       String  key,  email;                  }  catch  (IOException  e)  {  
       String[]  userInfo  =  new  String[3];                          e.printStackTrace();  
                 }  
       public  UpdateKeyTask(Context  ctx,  String                  try  {  
publicKey,  String  mail)  {                          out.writeObject(user);  
               context  =  ctx;                  }  catch  (IOException  e)  {  
               key  =  publicKey;                          e.printStackTrace();  
               email  =  mail;                  }  
       }    
   

 
xxv  
 

               //initialize  reading    
               InputStreamReader  IR  =  null;          @Override  
               try  {          protected  void  onPreExecute()  {  
                       IR  =  new                  super.onPreExecute();  
InputStreamReader(sock.getInputStream());          }  
               }  catch  (IOException  e)  {    
                       e.printStackTrace();          @Override  
               }          protected  void  onPostExecute(String  string)  
               BufferedReader  BR  =  new   {  
BufferedReader(IR);                  super.onPostExecute(string);  
               //look  for  messages  that  might  be  received                  
by  the  server   ((LoginActivity)context).keysUpdated(string);  
               String  MESSAGE  =  null;          }  
               try  {    
                       MESSAGE  =  BR.readLine();          @Override  
                       System.out.println(MESSAGE);          protected  void  onProgressUpdate(Integer...  
               }  catch  (IOException  e)  {   values)  {  
                       e.printStackTrace();                  super.onProgressUpdate(values);  
               }          }  
   
               return  MESSAGE;   }  
       }  
 
Ø SOK_CLIENT.java  
package                                  sock  =  new  Socket("192.168.1.103",  
com.example.ricardoviteri.safetimeapp;   9000);  
import  android.os.AsyncTask;                          }  catch  (IOException  e)  {  
                                 e.printStackTrace();  
import  java.io.*;                          }  
import  java.net.*;                          //print  a  message  to  be  sent  to  the  
  server  
/**                          PrintStream  PS  =  null;  
 *  Created  by  ricardoviteri  on  7/7/15.                          try  {  
 */                                  PS  =  new  
public  class  SOK_CLIENT  {   PrintStream(sock.getOutputStream());  
       byte[]  encMessage;                          }  catch  (IOException  e)  {  
       String  key;                                  e.printStackTrace();  
                         }  
       public  SOK_CLIENT(byte[]  msg,  String  key)  {                          PS.println(key);  
               encMessage  =  msg;    
               this.key  =  key;    
       }                          OutputStream  out  =  null;  
                         try  {  
       public  void  run()  throws  Exception{                                  out  =  sock.getOutputStream();  
               new  MyAsyncTask().execute();                          }  catch  (IOException  e)  {  
       }                                  e.printStackTrace();  
                         }  
       private  class  MyAsyncTask  extends                          DataOutputStream  dos  =  new  
AsyncTask<Void,  Void,  Void>   DataOutputStream(out);  
       {    
               @Override                          try  {  
               protected  void  onPostExecute(Void  result)                                  dos.writeInt(encMessage.length);  
{                          }  catch  (IOException  e)  {  
                       //Task  you  want  to  do  on  UIThread  after                                  e.printStackTrace();  
completing  Network  operation                          }  
                       //onPostExecute  is  called  after                          if  (encMessage.length  >  0)  {  
doInBackground  finishes  its  task.                                  try  {  
               }                                          dos.write(encMessage,  0,  
  encMessage.length);  
               @Override                                  }  catch  (IOException  e)  {  
               protected  Void  doInBackground(Void...                                          e.printStackTrace();  
params)  {                                  }  
                       //Do  your  network  operation  here                          }  
                       //create  a  socket  for  port  1500  at  the    
Localhost    
                       Socket  sock  =  null;                          //initialize  reading  
                       try  {                          InputStreamReader  IR  =  null;  

 
xxvi  
 

                       try  {  
                               IR  =  new  
InputStreamReader(sock.getInputStream());  
                       }  catch  (IOException  e)  {  
                               e.printStackTrace();  
                       }  
                       BufferedReader  BR  =  new  
BufferedReader(IR);  
                       //look  for  messages  that  might  be  
received  by  the  server  
                       String  MESSAGE  =  null;  
                       try  {  
                               MESSAGE  =  BR.readLine();  
                       }  catch  (IOException  e)  {  
                               e.printStackTrace();  
                       }  
                       System.out.println(MESSAGE);  
                       return  null;  
               }  
       }  
 
}  
 

 
xxvii  
 

Appendix  B:  Server  codes  


Ø socketServer.java  
package  saveTimeServer;   exists,  MongoDB  will  create  it  for  you  
import  java.io.*;       DB  db  =  
import  java.net.*;   mongo.getDB("safetimedb");  
import  java.util.ArrayList;        
import  java.util.Date;       actualPort  =  9003;  
import  java.util.List;        
       
import  com.mongodb.BasicDBObject;                  while(true){  
import  com.mongodb.DB;                     //System.out.println("TaskPending:  
import  com.mongodb.DBCollection;   "+tasksToDo.size());  
import  com.mongodb.DBCursor;                     //System.out.println("TaskForCycle:  
import  com.mongodb.DBObject;   "+tasksForCycle.size());  
import  com.mongodb.MongoClient;                     while(tasksForCycle.size()  >  0){  
                   
import  socketThreads.LoginUserThread;     tasksToDo.add(tasksForCycle.get(0))
import  socketThreads.NewUserThread;   ;  
import  socketThreads.SendMessageThread;                       tasksForCycle.remove(0);  
import  socketThreads.TestThread;                     }  
import  socketThreads.TimerThread;                     for(int  i  =  0;  i  <  tasksToDo.size();  
import  socketThreads.UpdateKeyThread;   i++){  
                   
import  java.math.BigInteger;     if(Integer.parseInt((String)  
  tasksToDo.get(i).get(0))  ==  actualPort){  
public  class  socketServer  {                      
    tasksForCycle.add(tasksToDo.get(i));  
  static  BigInteger  d;                      
  static  BigInteger  N;     tasksToDo.remove(i);  
  static  boolean  keepLoop  =  true;                         i-­‐-­‐;  
  static  boolean  receivingMsg  =  true;                       }  
  static  int  actualPort;                     }  
  static  ArrayList<ArrayList<Object>>                     //System.out.println("TaskPending:  
tasksToDo  =  new   "+tasksToDo.size());  
ArrayList<ArrayList<Object>>();                     //System.out.println("TaskForCycle:  
  static  ArrayList<ArrayList<Object>>   "+tasksForCycle.size());  
tasksForCycle  =  new                      
ArrayList<ArrayList<Object>>();                     keepLoop  =  true;  
                      TimerThread  timer  =  new  
  public  static  void  main(String[]   TimerThread(SERVER);  
args)  throws  Exception{                     timer.start();  
    socketServer  SERVER  =                     ServerSocket  srvrSocket  =  new  
new  socketServer();   ServerSocket();;  
    N  =  BigInteger.valueOf(0);                     try{  
               d  =  BigInteger.valueOf(0);                    
               NewUserThread  newUserThread  =  new     SERVER.mainUsersCycle(actualPort,  
NewUserThread();   srvrSocket,  timer);  
               newUserThread.start();                     }catch(Exception  e){  
               UpdateKeyThread  updateKeyThread  =                       //e.printStackTrace();  
new  UpdateKeyThread();                       timer.stop();  
               updateKeyThread.start();                       srvrSocket.close();  
               LoginUserThread  loginUserThread  =  new                     }  
LoginUserThread();                     //srvrSocket.close();  
               loginUserThread.start();                      
               TestThread  test  =  new                     DBCollection  table  =  
TestThread(SERVER);   db.getCollection("users");  
               test.start();                     int  numUsers  =  (int)  table.count();  
                                     
                    actualPort  =  (actualPort  ==  
  //SERVER.runKeyDecryption();   9003+numUsers-­‐1  ?  9003  :  actualPort+1);  
                                    //System.out.println("yo  ya  estoy!  -­‐-­‐
               MongoClient  mongo  =  new   -­‐>  "+actualPort);  
MongoClient("localhost",  27017);                     timer  =  null;  
                       }          
    /****  Get  database  ****/        
    //  if  database  doesn't     }  

 
xxviii  
 

    if(tasksForCycle.size()  !=  0){  


         
  public  void  mainUsersCycle(int     Ps.println("1");  
Port,  ServerSocket  srvrSocket,  TimerThread        
timer)  throws  Exception{     System.out.println("Send  stuff  to  
      app");  
          /**  
  //System.out.println("MainUsersCyc          *  10:  
le:  "+"Main  socket  open");   SOMEONE  ADDED  AS  CONTACT  
               *  11:  
    //create  a  ServerSocket   SOMEONE  SENT  A  MESSAGE  
for  Port            */  
           
  srvrSocket.setReuseAddress(true);        
    srvrSocket.bind(new     ArrayList<Object>  task  =  
InetSocketAddress(Port));   tasksForCycle.get(0);  
               
       
  srvrSocket.setSoTimeout(21000);     if(Integer.parseInt((String)  
    Socket  sock;   task.get(1))  ==  10){  
             
    while(keepLoop){     /**  
      //open  socket          
connection      *  ***********  Add  contact  task  list  
        **************  
               
      sock  =      *       0:  Port  
srvrSocket.accept();          
       *       1:  taskId  
  sock.setSoTimeout(21000);          
       *       2:  name  
  //sock.setKeepAlive(true);          
       *       3:  email  
  InputStreamReader  ir  =  new          
InputStreamReader(sock.getInputStream());      *       4:  key  
               
       */  
  BufferedReader  br  =  new          
BufferedReader(ir);      
               
      String     Ps.println("10");  
MESSAGE  =  br.readLine();          
           
      PrintStream  Ps          
=  new  PrintStream(sock.getOutputStream());     System.out.println("Sending  
        contact!!!");  
      /**          
       *  0:  Nothing  to     Ps.println(task.get(2));  
do          
       *  1:  Make  app     Ps.println(task.get(3));  
listen          
       *  2:  Make  app     Ps.println(task.get(4));  
send  data           }  
      **/            
         
  if(Integer.parseInt(MESSAGE)  ==  0     if(Integer.parseInt((String)  
&&  tasksForCycle.size()  ==  0){   task.get(1))  ==  11){  
             
  //System.out.println("Nothing  to  do     /**  
with  "+Port);          
         *  ***********  Send  message  task  list  
  keepLoop  =  false;   **************  
             
  timer.stop();      *       0:  Port  
                    srvrSocket.close();          
         *       1:  taskId  
  Ps.println("0");          
      }else      *       2:  from  who  
       

 
xxix  
 

   *       3:  message   ADD  CONTACT  


                 *  2:  
   */   MESSAGE  
                **/  
  SendMessageThread        
loginUserThread  =  new     //ADD  CONTACT  PROCESS  
SendMessageThread(this,  task.get(3),  (String)        
task.get(2));     if(Integer.parseInt(MESSAGE)  ==  1){  
                             
loginUserThread.start();     String  user  =  br.readLine();  
               
       
               
  Ps.println("11");     MongoClient  mongo  =  new  
        MongoClient("localhost",  27017);  
           
             
  System.out.println("Sending          
message!!!");     /****  Get  database  ****/  
               
      //  if  database  doesn't  exists,  
        MongoDB  will  create  it  for  you  
  /*byte[]  encMessage  =  (byte[])          
task.get(3);     DB  db  =  
        mongo.getDB("safetimedb");  
  //Ps.println(""+encMessage.length);              
               
      /****  Get  collection  /  table  from  
        'testdb'  ****/  
  Ps.println(encMessage);          
          //  if  collection  doesn't  exists,  
    MongoDB  will  create  it  for  you  
               
  OutputStream  out  =     DBCollection  table  =  
sock.getOutputStream();   db.getCollection("users");  
               
  DataOutputStream  dos  =  new      
DataOutputStream(out);          
          /****  Find  and  display  ****/  
           
          BasicDBObject  searchQuery  =  new  
  dos.write(encMessage);   BasicDBObject();  
               
      searchQuery.put("email",  user);  
                   
  if(encMessage.length  >  0){          
          DBCursor  cursor  =  
    dos.write(encMessage,  0,   table.find(searchQuery);  
encMessage.length);              
               
  }     /**    
               
  */      *  1:  User  found  
        }          
             *  2:  User  not  found  
             
  tasksForCycle.remove(0);     **/  
             
  //TODO:  Send  stuff  to  app!     List<DBObject>  csrList  =  
      }else{   cursor.toArray();  
             
  Ps.println("2");     PrintStream  PS  =  new  
          PrintStream(sock.getOutputStream());  
             
  MESSAGE  =  br.readLine();     if  (csrList.size()  >  0)  {  
                 
        /**    
         *  1:     System.out.println("MainUsersCycle

 
xxx  
 

/AddContact:  User  found");    


          task.add(csrList2.get(0).get("email")
      .toString());  
               
    PS.println("1");    
          task.add(csrList2.get(0).get("key").t
  oString());  
  PS.println(csrList.get(0).get("name"        
).toString());        
               
      tasksToDo.add(task);  
  PS.println(csrList.get(0).get("email"        
).toString());        
               
       
  PS.println(csrList.get(0).get("key").t        
oString());     }else{  
               
       
          System.out.println("MainUsersCycle
    /**   /AddContact:  User  not  found");  
               
     *  ***********  Add  contact       PS.println("2");  
task  list  **************          
          }  
     *       0:          
Port      
                }  
     *       1:            
taskId        
          if(Integer.parseInt(MESSAGE)  ==  2){  
     *       2:          
name      
               
     *       3:     while(receivingMsg){  
email          
         
     *       4:     //System.out.println("waiting");  
key          
          }  
     */          
          System.out.println("finished  
    BasicDBObject   waiting");  
searchQuery2  =  new  BasicDBObject();          
          receivingMsg  =  true;    
    searchQuery.put("port",           }  
Port);            
                 
            }  
               
    DBCursor  cursor2  =          
table.find(searchQuery2);          
                         sock.close();  
    List<DBObject>  csrList2  =          
cursor2.toArray();       }  
            srvrSocket.close();  
    ArrayList<Object>  task  =        
new  ArrayList<Object>();     }  
           
    public  void  changeStopLoop(){  
  task.add(csrList.get(0).get("port").to     keepLoop  =  false;  
String());     }  
           
    task.add("10");     public  void  stopReceiving(){  
            receivingMsg  =  false;  
    }  
  task.add(csrList2.get(0).get("name")    
.toString());     public  void  
        stopReceivingMsg(Object  msg,  String  toUser,  

 
xxxi  
 

String  fromUser){       System.out.println("Send  


    //int  thisPort  =   message  task  list  port:  "+endUserPort);  
actualPort;        
    receivingMsg  =  false;       /*BasicDBObject  
    if(msg  instanceof   searchQuery2  =  new  BasicDBObject();  
byte[]){    
      System.out.println("thisPort"+thisP
  System.out.println(new   ort);  
String((byte[])msg));       searchQuery2.put("port",  
    }else{   thisPort);  
         
  System.out.println("Is  an  image");       DBCursor  cursor2  =  
    }   table.find(searchQuery);  
      List<DBObject>  csrList2  =  
  System.out.println(toUser);   cursor2.toArray();  
    ArrayList<Object>  task  =       String  thisUser  =  
new  ArrayList<Object>();   csrList2.get(0).get("email").toString();  
    /**       */  
     *  ***********  Send       System.out.println("Send  
message  task  list  **************   message  task  list  user:  "+fromUser);  
     *       0:        
Port       task.add(endUserPort);  
     *       1:       task.add("11");  
taskId       task.add(fromUser);  
     *       2:       task.add(msg);  
from  who        
     *       3:       tasksToDo.add(task);  
message     }  
     */      
        public  void  runKeyDecryption()  
    MongoClient  mongo  =   throws  Exception{  
null;        
    try  {       //create  a  ServerSocket  
      mongo  =  new   for  port  8080  
MongoClient("localhost",  27017);       ServerSocket  srvrSocket  =  
    }  catch   new  ServerSocket(9003);  
(UnknownHostException  e)  {    
      //  TODO  Auto-­‐   srvrSocket.setReuseAddress(true);  
generated  catch  block       Socket  sock;  
         
  e.printStackTrace();       while(true){  
    }         //open  socket  
        connection  
    /****  Get  database  ****/         sock  =  
    //  if  database  doesn't   srvrSocket.accept();  
exists,  MongoDB  will  create  it  for  you      
    DB  db  =     //sock.setKeepAlive(true);  
mongo.getDB("safetimedb");      
        System.out.println("Checkpoint  1");  
    /****  Get  collection  /      
table  from  'testdb'  ****/      
    //  if  collection  doesn't     InputStreamReader  IR  =  new  
exists,  MongoDB  will  create  it  for  you   InputStreamReader(sock.getInputStream());  
    DBCollection  table  =      
db.getCollection("users");     BufferedReader  BR  =  new  
      BufferedReader(IR);  
    /****  Find  and  display        
****/         //check  for  
    BasicDBObject   messages  received  from  the  socket  
searchQuery  =  new  BasicDBObject();         String  
    searchQuery.put("email",   MESSAGE  =  BR.readLine();  
toUser);        
            N  =  N.add(new  
    DBCursor  cursor  =   BigInteger((MESSAGE.split("-­‐"))[0]));  
table.find(searchQuery);         d  =  d.add(new  
    List<DBObject>  csrList  =   BigInteger((MESSAGE.split("-­‐"))[1]));  
cursor.toArray();                    
    String  endUserPort  =      
csrList.get(0).get("port").toString();     System.out.println(""+N);  

 
xxxii  
 

         
  System.out.println(""+d);     PrintStream  PS  =  new  
        PrintStream(sock.getOutputStream());  
         
  System.out.println("Checkpoint  2");     PS.println("MESSAGE  recieved");  
            }  
      MESSAGE  =          
"now  the  message...";      
          System.out.println("Checkpoint  5");  
      InputStream  in          
=  sock.getInputStream();         /*byte[]  
    decMessage  =  messageDecryption(data);  
  DataInputStream  dis  =  new      
DataInputStream(in);     System.out.println(new  
  String(decMessage));  
      int  len  =         N  =  
dis.readInt();   BigInteger.valueOf(0);  
                     d  =  BigInteger.valueOf(0);  
  System.out.println("size:  "+len);                    */  
                         data  =  null;  
                     sock.close();  
  System.out.println("Checkpoint  3");       }  
             
      byte[]  data  =     }  
new  byte[len];      
      if  (len  >  0)  {      
        public  byte[]  
  dis.readFully(data);   messageDecryption(byte[]  D){  
      }                  BigInteger  encryptedMsg  =  new  
            BigInteger(D);  
                   encryptedMsg  =  encryptedMsg.modPow(d,  
  System.out.println("Checkpoint  4");   N);  
                   return  encryptedMsg.toByteArray();  
  System.out.println(new                  //return  (new  BigInteger(D)).modPow(d,  
String(data));   N).toByteArray();  
                   }  
      if(data.length    
!=  0){      
        //if   }  
a  message  is  received,  print  in  console  
 
Ø LoginUserThread.java  
package  socketThreads;       }  catch  (Exception  e)  {  
        //  TODO  Auto-­‐
import  java.io.BufferedReader;   generated  catch  block  
import  java.io.InputStream;      
import  java.io.InputStreamReader;     e.printStackTrace();  
import  java.io.ObjectInputStream;       }  
import  java.io.PrintStream;     }  
import  java.net.ServerSocket;      
import  java.net.Socket;     public  void  loginUserTask()  throws  
import  java.util.List;   Exception{  
       
import  com.mongodb.BasicDBObject;       //create  a  ServerSocket  
import  com.mongodb.DB;   for  port  8080  
import  com.mongodb.DBCollection;       ServerSocket  srvrSocket  =  
import  com.mongodb.DBCursor;   new  ServerSocket(9001);  
import  com.mongodb.DBObject;    
import  com.mongodb.MongoClient;     srvrSocket.setReuseAddress(true);  
      Socket  sock;  
public  class  LoginUserThread    extends  Thread        
{    
    System.out.println("LoginUserThrea
  public  void  run(){   d:  "+"Login  socket  open");  
    try  {        
        while(true){  
  loginUserTask();         //open  socket  

 
xxxiii  
 

connection            *  3:  
      sock  =   Incorrect  password  
srvrSocket.accept();            *  4:  
        Info  not  received  
      InputStream  in           **/  
=  sock.getInputStream();        
      List<DBObject>  csrList  =  
  ObjectInputStream  dis  =  new   cursor.toArray();  
ObjectInputStream(in);            
                if  
      String[]  user  =   (csrList.size()  >  0)  {  
new  String[2];          
        String  pass  =  
      user  =   csrList.get(0).get("password").toString();  
(String[])  dis.readObject();          
              System.out.println(pass);  
      if(user.length          
!=  0){     if(pass.equals(user[1])){  
        //if          
a  message  is  received,  print  in  console       PrintStream  PS  =  new  
      PrintStream(sock.getOutputStream());  
  System.out.println("LoginUserThrea        
d:  "+""+user[0]);       PS.println("2");  
             
  System.out.println("LoginUserThrea  
d:  "+""+user[1]);     PS.println(csrList.get(0).get("name"
          ).toString());  
             
  //TODO:  Add  user  to  DataBase!  send    
a  unique  port  number  to  user.     PS.println(csrList.get(0).get("phone"
          ).toString());  
             
  MongoClient  mongo  =  new    
MongoClient("localhost",  27017);     PS.println(csrList.get(0).get("email"
            ).toString());  
        /****          
Get  database  ****/    
        //  if     PS.println(csrList.get(0).get("port").
database  doesn't  exists,  MongoDB  will  create  it   toString());  
for  you          
        DB        
db  =  mongo.getDB("safetimedb");          
              InputStreamReader  IR  =  
        /****   new  
Get  collection  /  table  from  'testdb'  ****/   InputStreamReader(sock.getInputStream());  
        //  if          
collection  doesn't  exists,  MongoDB  will  create       BufferedReader  BR  =  new  
it  for  you   BufferedReader(IR);  
             
  DBCollection  table  =      
db.getCollection("users");          
              //check  for  messages  
        /****   received  from  the  socket  
Find  and  display  ****/          
          String  MESSAGE  =  
  BasicDBObject  searchQuery  =  new   BR.readLine();  
BasicDBObject();          
       
  searchQuery.put("email",  user[0]);     System.out.println(MESSAGE);  
                 
           
  DBCursor  cursor  =          
table.find(searchQuery);     }else{  
                 
        /**         PrintStream  PS  =  new  
         *  1:   PrintStream(sock.getOutputStream());  
User  not  found          
         *  2:       PS.println("3");  
Correct  password          

 
xxxiv  
 

  }        
          PrintStream  PS  =  new  
    PrintStream(sock.getOutputStream());  
           
  }else{     PS.println("4");  
              }  
  PrintStream  PS  =  new          
PrintStream(sock.getOutputStream());               sock.close();  
            }  
  PS.println("1");     }  
        }   }  
 
      }else{  
 
 
Ø NewUserThread.java  
package  socketThreads;     ObjectInputStream  dis  =  new  
  ObjectInputStream(in);  
import  java.io.InputStream;          
import  java.io.ObjectInputStream;         String[]  user  =  
import  java.io.PrintStream;   new  String[5];  
import  java.net.ServerSocket;        
import  java.net.Socket;         user  =  
  (String[])  dis.readObject();  
import  com.mongodb.BasicDBObject;              
import  com.mongodb.DB;         if(user.length  
import  com.mongodb.DBCollection;   !=  0){  
import  com.mongodb.DBCursor;           //if  
import  com.mongodb.MongoClient;   a  message  is  received,  print  in  console  
       
public  class  NewUserThread  extends  Thread  {     System.out.println("NewUserThread
    :  "+""+user[0]);  
  public  void  run(){        
    try  {     System.out.println("NewUserThread
    :  "+""+user[1]);  
  runNewUserTask();        
    }  catch  (Exception  e)  {     System.out.println("NewUserThread
      //  TODO  Auto-­‐ :  "+""+user[2]);  
generated  catch  block        
      System.out.println("NewUserThread
  e.printStackTrace();   :  "+""+user[3]);  
    }        
  }     System.out.println("NewUserThread
    :  "+""+user[4]);  
  public  void  runNewUserTask()            
throws  Exception{        
        //TODO:  Add  user  to  DataBase!  send  
    //create  a  ServerSocket   a  unique  port  number  to  user.  
for  port  8080            
    ServerSocket  srvrSocket  =        
new  ServerSocket(9000);     MongoClient  mongo  =  new  
  MongoClient("localhost",  27017);  
  srvrSocket.setReuseAddress(true);              
    Socket  sock;           /****  
  Get  database  ****/  
  System.out.println("NewUserThread         //  if  
:  "+"Registration  socket  open");   database  doesn't  exists,  MongoDB  will  create  it  
      for  you  
    while(true){           DB  
      //open  socket   db  =  mongo.getDB("safetimedb");  
connection            
      sock  =           /****  
srvrSocket.accept();   Get  collection  /  table  from  'testdb'  ****/  
                //  if  
      InputStream  in   collection  doesn't  exists,  MongoDB  will  create  
=  sock.getInputStream();   it  for  you  
         

 
xxxv  
 

  DBCollection  table  =   BasicDBObject();  


db.getCollection("users");          
            document.put("name",  user[0]);  
        /****          
Find  and  display  ****/     document.put("phone",  user[1]);  
             
  BasicDBObject  searchQuery  =  new     document.put("email",  user[2]);  
BasicDBObject();          
        document.put("password",  user[3]);  
  searchQuery.put("email",  user[2]);          
            document.put("key",  user[4]);  
             
  DBCursor  cursor  =     document.put("port",  ""+port);  
table.find(searchQuery);          
            table.insert(document);  
        /**              
         *  1:            
Sucessfully  added          
         *  2:     PrintStream  PS  =  new  
Email  already  registered   PrintStream(sock.getOutputStream());  
         *  3:          
User  not  received     PS.println("1");  
        **/          
        if     PS.println(""+port);  
(cursor.length()  >  0)  {           }  
                 
  PrintStream  PS  =  new         }else{  
PrintStream(sock.getOutputStream());        
          PrintStream  PS  =  new  
  PS.println("2");   PrintStream(sock.getOutputStream());  
           
  }else{     PS.println("3");  
              }  
  long  port  =  9003  +  table.count();          
                    sock.close();  
  /****  Insert  ****/       }  
          }  
  //  create  a  document  to  store  key      
and  value   }  
       
  BasicDBObject  document  =  new  
 
 
Ø SendMessageThread.java  
package  socketThreads;     public  
  SendMessageThread(socketServer  context,  
import  java.io.BufferedReader;   Object  msg,  String  usrToSend){  
import  java.io.DataInputStream;       parent  =  context;  
import  java.io.DataOutputStream;       encMessage  =  msg;  
import  java.io.IOException;       user  =  usrToSend;  
import  java.io.InputStream;     }  
import  java.io.InputStreamReader;      
import  java.io.OutputStream;     public  void  run(){  
import  java.io.PrintStream;       try  {  
import  java.net.ServerSocket;         sendMessage();  
import  java.net.Socket;       }  catch  (Exception  e)  {  
import  java.util.ArrayList;         //  TODO  Auto-­‐
  generated  catch  block  
import  saveTimeServer.socketServer;      
    e.printStackTrace();  
public  class  SendMessageThread  extends       }  
Thread{     }  
       
  socketServer  parent;     public  void  sendMessage()  throws  
  Object  encMessage;   Exception{  
  String  user;       try  {  
       

 
xxxvi  
 

  System.out.println("SendMessage         }else{  
running");        
      ServerSocket     dos.writeChar('I');  
srvrSocket  =  new  ServerSocket(8998);            
         
  srvrSocket.setReuseAddress(true);     dos.writeInt(((ArrayList)encMessag
      Socket  sock;   e).size());  
      sock  =            
srvrSocket.accept();        
          for(int  i  =  0;  i  <  
      InputStream  in   ((ArrayList)encMessage).size();  i++){  
=  sock.getInputStream();          
      dos.writeInt(((byte[])((ArrayList)en
  DataInputStream  dis  =  new   cMessage).get(i)).length);  
DataInputStream(in);          
          if(((byte[])((ArrayList)encMessage)
      char  cosa  =   .get(i)).length  >  0){  
dis.readChar();          
      OutputStream    
out  =  sock.getOutputStream();     dos.write(((byte[])((ArrayList)encM
    essage).get(i)),  0,  
  DataOutputStream  dos  =  new   ((byte[])((ArrayList)encMessage).get(i)).lengt
DataOutputStream(out);   h);  
               
      if(encMessage     }  
instanceof  byte[]){           }  
            }  
  System.out.println(new          
String((byte[])encMessage));          
                PrintStream  Ps  
      =  new  PrintStream(sock.getOutputStream());  
  dos.writeChar('M');      
            Ps.println(user);  
             
  dos.writeInt(((byte[])encMessage).l     }  catch  (IOException  e)  {  
ength);         //  TODO  Auto-­‐
          generated  catch  block  
         
  if(((byte[])encMessage).length  >  0){     e.printStackTrace();  
            }  
  dos.write(((byte[])encMessage),  0,     }  
((byte[])encMessage).length);   }  
        }  
 
 
Ø TestThread.java  
package  socketThreads;      
    public  void  run(){  
import  java.io.BufferedReader;       try  {  
import  java.io.DataInputStream;      
import  java.io.IOException;     receiveMessage();  
import  java.io.InputStream;       }  catch  (Exception  e)  {  
import  java.io.InputStreamReader;         //  TODO  Auto-­‐
import  java.net.ServerSocket;   generated  catch  block  
import  java.net.Socket;      
import  java.util.ArrayList;     e.printStackTrace();  
      }  
import  saveTimeServer.socketServer;     }  
     
public  class  TestThread  extends  Thread{     public  void  receiveMessage()  
    throws  Exception{  
  socketServer  parent;       try  {  
       
  public  TestThread(socketServer     System.out.println("TestThread  
context){   running");  
    parent  =  context;         ServerSocket  
  }   srvrSocket  =  new  ServerSocket(8999);  

 
xxxvii  
 

       
  srvrSocket.setReuseAddress(true);          
      Socket  sock;     for(int  i  =  0;  i  <  imgLen;  i++){  
               
      while(true){    
        sock     System.out.println("Receiving...");  
=  srvrSocket.accept();          
              int  len  =  dis.readInt();  
             
  InputStream  in  =       byte[]  data  =  new  
sock.getInputStream();   byte[len];  
             
  DataInputStream  dis  =  new       if  (len  >  0)  {  
DataInputStream(in);          
             
        char     dis.readFully(data);  
type  =  dis.readChar();          
              }  
             
  if(type  ==  'M'){       image.add(data);  
               
  int  len  =  dis.readInt();    
          System.out.println("Received  #"+i);  
           
          }  
  System.out.println("size:  "+len);          
          System.out.println("info  received:  
    "+image.size());  
               
  byte[]  data  =  new  byte[len];      
               
  if  (len  >  0)  {     InputStreamReader  ir  =  new  
        InputStreamReader(sock.getInputStream());  
    dis.readFully(data);          
          BufferedReader  br  =  new  
  }   BufferedReader(ir);  
               
  InputStreamReader  ir  =  new     String  toUser  =  br.readLine();  
InputStreamReader(sock.getInputStream());          
          String  fromUser  =  br.readLine();  
  BufferedReader  br  =  new          
BufferedReader(ir);     System.out.println("To  user:  
        "+toUser);  
  String  toUser  =  br.readLine();          
          System.out.println("from  user:    
  String  fromUser  =  br.readLine();   "+fromUser);  
               
  parent.stopReceivingMsg(data,      
toUser,  fromUser);          
        parent.stopReceivingMsg(image,  
  }else{   toUser,  fromUser);  
                }  
             
                 
  int  imgLen  =  dis.readInt();         }  
               
  System.out.println("size  of  image:       }  catch  (IOException  e)  {  
"+imgLen);         //  TODO  Auto-­‐
        generated  catch  block  
       
          e.printStackTrace();  
  ArrayList<Object>  image  =  new       }  
ArrayList<Object>();     }  
        }  
 
 
 

 
xxxviii  
 

Ø TimerThread.java  
package  socketThreads;        
      //create  a  ServerSocket  
import  saveTimeServer.socketServer;   for  port  8080  
      ServerSocket  srvrSocket  =  
public  class  TimerThread  extends  Thread{   new  ServerSocket(9002);  
     
  socketServer  parent;     srvrSocket.setReuseAddress(true);  
        Socket  sock;  
  public  TimerThread(socketServer    
context){     System.out.println("UpdateKeyThre
    parent  =  context;   ad:  "+"Key  update  socket  open");  
  }        
        while(true){  
  public  void  run(){         //open  socket  
    try  {   connection  
          sock  =  
  Thread.sleep(20000);   srvrSocket.accept();  
    }  catch          
(InterruptedException  e)  {         InputStream  in  
      //  TODO  Auto-­‐ =  sock.getInputStream();  
generated  catch  block      
      ObjectInputStream  dis  =  new  
  e.printStackTrace();   ObjectInputStream(in);  
    }          
        String[]  user  =  
  System.out.println("Timer   new  String[2];  
finished");        
    parent.changeStopLoop();         user  =  
  }   (String[])  dis.readObject();  
}              
        if(user.length  
  !=  0){  
UpdateKeyThread.java           //if  
  a  message  is  received,  print  in  console  
package  socketThreads;        
    System.out.println("UpdateKeyThre
import  java.io.InputStream;   ad:  "+""+user[0]);  
import  java.io.ObjectInputStream;        
import  java.io.PrintStream;     System.out.println("UpdateKeyThre
import  java.net.ServerSocket;   ad:  "+""+user[1]);  
import  java.net.Socket;            
import  java.util.List;        
    //TODO:  Add  user  to  DataBase!  send  
import  com.mongodb.BasicDBObject;   a  unique  port  number  to  user.  
import  com.mongodb.DB;            
import  com.mongodb.DBCollection;        
import  com.mongodb.DBCursor;     MongoClient  mongo  =  new  
import  com.mongodb.DBObject;   MongoClient("localhost",  27017);  
import  com.mongodb.MongoClient;              
          /****  
public  class  UpdateKeyThread  extends  Thread   Get  database  ****/  
{           //  if  
  database  doesn't  exists,  MongoDB  will  create  it  
  public  void  run(){   for  you  
    try  {           DB  
    db  =  mongo.getDB("safetimedb");  
  updateKeyTask();            
    }  catch  (Exception  e)  {           /****  
      //  TODO  Auto-­‐ Get  collection  /  table  from  'testdb'  ****/  
generated  catch  block           //  if  
    collection  doesn't  exists,  MongoDB  will  create  
  e.printStackTrace();   it  for  you  
    }        
  }     DBCollection  table  =  
    db.getCollection("users");  
  public  void  updateKeyTask()  throws            
Exception{           /****  

 
xxxix  
 

Update  ****/   ad:  "+csrList.get(0).get("email").toString());  


        //        
search  document  where  name="mkyong"  and     System.out.println("UpdateKeyThre
update  it  with  new  values   ad:  
      "+csrList.get(0).get("password").toString());  
  BasicDBObject  query  =  new        
BasicDBObject();     System.out.println("UpdateKeyThre
      ad:  "+csrList.get(0).get("key").toString());  
  query.put("email",  user[0]);            
                   
               
        PrintStream  PS  =  new  
  DBCursor  cursor  =  table.find(query);   PrintStream(sock.getOutputStream());  
           
  List<DBObject>  csrList  =     PS.println("Key  successfully  
cursor.toArray();   updated");  
               
  System.out.println("UpdateKeyThre       }else{  
ad:  "+csrList.get(0).get("name").toString());        
        PrintStream  PS  =  new  
  System.out.println("UpdateKeyThre PrintStream(sock.getOutputStream());  
ad:  "+csrList.get(0).get("phone").toString());        
        PS.println("3");  
  System.out.println("UpdateKeyThre       }  
ad:  "+csrList.get(0).get("email").toString());          
                  sock.close();  
  System.out.println("UpdateKeyThre     }  
ad:     }  
"+csrList.get(0).get("password").toString());   }  
     
  System.out.println("UpdateKeyThre
ad:  "+csrList.get(0).get("key").toString());  
         
         
     
  BasicDBObject  newDocument  =  new  
BasicDBObject();  
     
  newDocument.put("key",  user[1]);  
         
     
  BasicDBObject  updateObj  =  new  
BasicDBObject();  
     
  updateObj.put("$set",  
newDocument);  
         
     
  table.update(query,  updateObj);  
         
         
     
  BasicDBObject  query2  =  new  
BasicDBObject();  
     
  query2.put("email",  user[0]);  
         
     
  cursor  =  table.find(query2);  
     
  csrList  =  cursor.toArray();  
     
  System.out.println("UpdateKeyThre
ad:  "+csrList.get(0).get("name").toString());  
     
  System.out.println("UpdateKeyThre
ad:  "+csrList.get(0).get("phone").toString());  
     
  System.out.println("UpdateKeyThre

 
xl  
 

Appendix  C:  Test  RSA  keys  


Public   key   N:  
A   287973047397959966459171224813899804924489958240150171144632418612750012436289393
883489292547390478094515661452003404487648891297123185156001603931868101709758060
854839949352859800329224059177127529381738895709481327666740673015294901850034061
159008879133776767576897374331617835968282645031245013734438071430841271859036038
605069182960019317903533872073443874743942934512007359451933780032525716970355007
790263263221016535946736999155442475443611530939510186499607481645389483498274609
515078604074322961514399829579480338601370882132440005276219970272407684466237794
73484759682939168263552990438933236448270783096179  

e:  
160939886914470350804474172516213429150273668023601232814645095900670025459200230
304644355172135209280127427290074919281076382688927964778360546919274923613177775
654684802629395792000808537872208888755637137297454336251887414392965423713293041
433037548117073451047132571445088585937354286000656687823149582353153283925830167
883667036666620201187344847795225043011272129079516363716182327319675375254314722
448951792554800672650372287768303941950670829458914643309904386843878828987538610
749396912855124401308615602176079823373962777640789622131528358328099466615218788
89061341341366543520090211856990469300451442976351  

Private   key   N:  
A   287973047397959966459171224813899804924489958240150171144632418612750012436289393
883489292547390478094515661452003404487648891297123185156001603931868101709758060
854839949352859800329224059177127529381738895709481327666740673015294901850034061
159008879133776767576897374331617835968282645031245013734438071430841271859036038
605069182960019317903533872073443874743942934512007359451933780032525716970355007
790263263221016535946736999155442475443611530939510186499607481645389483498274609
515078604074322961514399829579480338601370882132440005276219970272407684466237794
73484759682939168263552990438933236448270783096179  

d:  
130286134905903296878809904273909809219128868288854870690284843330319188758403650
92602163120321437241568892607436032444708019114394600985225325345978141119  

Public   key   N:  
B   250375816420717654230341390083618198845133857389865187895448181623536720175215737
298162301587416790236753914696792070740168691581277755465981892844665279344032079
125976212548841750698664552841081756451944696489379954094399833574426518895389395
845245661651847121302424064982201516300295530730638594427374756038627538772481163
212583661719376529251612978716399036673963771202535312831189461306724400313299612
148899906147437344328591580095237534896231635413830237266245708588133793967697039
926803474180916493859329352055220340986127416405819953677016209476062898208613556
40874707113754994144032009208031199649556323224773  

e:  
160043651603909917991739363542657835352920347005814770669336486989694895266587929
316756426693143361273006937259401116945071669413197601790686825488357671930766433
592384957319696945946716984171843986738705652178961505176933725616075821307250323
230924754483957395151720464793300597866219411321393552930202629652278982658200187
093909761956584267608965637558793753398136709445294001102087043886572237622644790

 
xli  
 

581219866854957968076163032820298263445062213411078395088387552002975117527220656
368452276982213433947994297756918784702763953298638278115079740571615973875815210
5989976397068557238550551265514937312957717154885  

Private   key   N:  
B   250375816420717654230341390083618198845133857389865187895448181623536720175215737
298162301587416790236753914696792070740168691581277755465981892844665279344032079
125976212548841750698664552841081756451944696489379954094399833574426518895389395
845245661651847121302424064982201516300295530730638594427374756038627538772481163
212583661719376529251612978716399036673963771202535312831189461306724400313299612
148899906147437344328591580095237534896231635413830237266245708588133793967697039
926803474180916493859329352055220340986127416405819953677016209476062898208613556
40874707113754994144032009208031199649556323224773  

d:  
125154922989015516313948357087251477948476674921424729140171055347407444329693363
76038257673079408354329994964643989080807755408570576427974105419136074769  

 
 
 
 
 
 
 
 
 
 
 
 
 
 

 
xlii  
 

Appendix  D:  Encryption  algorithm  C  code  tests  


Ø AES  algorithm:  
// 0x5E, 0x0B, 0xDB},
// main.c {0xE0, 0x32, 0x3A, 0x0A,
// AESalgorithm 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91,
// 0x95, 0xE4, 0x79},
// Created by Ricardo Viteri on 5/10/15. {0xE7, 0xC8, 0x37, 0x6D,
// Copyright (c) 2015 Ricardo Viteri. All rights 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65,
reserved. 0x7A, 0xAE, 0x08},
// {0xBA, 0x78, 0x25, 0x2E,
0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B,
#include <stdio.h> 0xBD, 0x8B, 0x8A},
{0x70, 0x3E, 0xB5, 0x66,
int cipherKey[4][4] = {{0x2b, 0x28, 0xab, 0x09}, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86,
{0x7e, 0xae, 0xf7, 0xcf}, 0xC1, 0x1D, 0x9E},
{0x15, 0xd2, 0x15, 0x4f}, {0xE1, 0xF8, 0x98, 0x11,
{0x16, 0xa6, 0x88, 0x3c}}; 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE,
0x55, 0x28, 0xDF},
int roundKey[4][44] = {{0x2b, 0x28, 0xab, 0x09, 0x00, {0x8C, 0xA1, 0x89, 0x0D,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xBB, 0x16}};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, int decLookupTbl[16][16] = {{0x52, 0x09, 0x6A, 0xD5,
0x00, 0x00, 0x00}, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81,
{0x7e, 0xae, 0xf7, 0xcf, 0x00, 0xF3, 0xD7, 0xFB},
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {0x7C, 0xE3, 0x39, 0x82,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xE9, 0xCB},
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {0x54, 0x7B, 0x94, 0x32,
0x00, 0x00, 0x00}, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42,
{0x15, 0xd2, 0x15, 0x4f, 0x00, 0xFA, 0xC3, 0x4E},
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {0x08, 0x2E, 0xA1, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xD1, 0x25},
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {0x72, 0xF8, 0xF6, 0x64,
0x00, 0x00, 0x00}, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D,
{0x16, 0xa6, 0x88, 0x3c, 0x00, 0x65, 0xB6, 0x92},
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {0x6C, 0x70, 0x48, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x9D, 0x84},
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, {0x90, 0xD8, 0xAB, 0x00,
0x00, 0x00, 0x00}}; 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8,
0xB3, 0x45, 0x06},
int rCon[4][10] = {{0x01, 0x02, 0x04, 0x08, 0x10, {0xD0, 0x2C, 0x1E, 0x8F,
0x20, 0x40, 0x80, 0x1b, 0x36}, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x8A, 0x6B},
0x00, 0x00, 0x00, 0x00, 0x00}, {0x3A, 0x91, 0x11, 0x41,
{0x00, 0x00, 0x00, 0x00, 0x00, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0,
0x00, 0x00, 0x00, 0x00, 0x00}, 0xB4, 0xE6, 0x73},
{0x00, 0x00, 0x00, 0x00, 0x00, {0x96, 0xAC, 0x74, 0x22,
0x00, 0x00, 0x00, 0x00, 0x00}}; 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C,
0x75, 0xDF, 0x6E},
int mixColumnMatrix[4][4] = {{2, 3, 1, 1}, {0x47, 0xF1, 0x1A, 0x71,
{1, 2, 3, 1}, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA,
{1, 1, 2, 3}, 0x18, 0xBE, 0x1B},
{3, 1, 1, 2}}; {0xFC, 0x56, 0x3E, 0x4B,
0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78,
int encLookupTbl[16][16] = {{0x63, 0x7C, 0x77, 0x7B, 0xCD, 0x5A, 0xF4},
0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, {0x1F, 0xDD, 0xA8, 0x33,
0xD7, 0xAB, 0x76}, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27,
{0xCA, 0x82, 0xC9, 0x7D, 0x80, 0xEC, 0x5F},
0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, {0x60, 0x51, 0x7F, 0xA9,
0xA4, 0x72, 0xC0}, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93,
{0xB7, 0xFD, 0x93, 0x26, 0xC9, 0x9C, 0xEF},
0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, {0xA0, 0xE0, 0x3B, 0x4D,
0xD8, 0x31, 0x15}, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83,
{0x04, 0xC7, 0x23, 0xC3, 0x53, 0x99, 0x61},
0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, {0x17, 0x2B, 0x04, 0x7E,
0x27, 0xB2, 0x75}, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55,
{0x09, 0x83, 0x2C, 0x1A, 0x21, 0x0C, 0x7D}};
0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29,
0xE3, 0x2F, 0x84},
{0x53, 0xD1, 0x00, 0xED, int twoTable[16][16] =
0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, {{0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x
0x4C, 0x58, 0xCF}, 14,0x16,0x18,0x1a,0x1c,0x1e},
{0xD0, 0xEF, 0xAA, 0xFB,
0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, {0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x3
0x3C, 0x9F, 0xA8}, 4,0x36,0x38,0x3a,0x3c,0x3e},
{0x51, 0xA3, 0x40, 0x8F,
0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, {0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x5
0xFF, 0xF3, 0xD2}, 4,0x56,0x58,0x5a,0x5c,0x5e},
{0xCD, 0x0C, 0x13, 0xEC,
0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, {0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x7
0x5D, 0x19, 0x73}, 4,0x76,0x78,0x7a,0x7c,0x7e},
{0x60, 0x81, 0x4F, 0xDC,
0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x9

 
xliii  
 

4,0x96,0x98,0x9a,0x9c,0x9e}, for (int i = 0; i < 4; i++) {


lutYaxis = (keySchCol[i]&0xf0)>>4;
{0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb lutXaxis = keySchCol[i]&0x0f;
4,0xb6,0xb8,0xba,0xbc,0xbe},
keySchCol[i] =
{0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd encLookupTbl[lutYaxis][lutXaxis];
4,0xd6,0xd8,0xda,0xdc,0xde}, }

{0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf for (int j = 0; j < 4; j++) {


4,0xf6,0xf8,0xfa,0xfc,0xfe}, roundKey[j][((rotConNum+1)*4)] =
roundKey[j][(rotConNum*4)] ^ rCon[j][rotConNum] ^
{0x1b,0x19,0x1f,0x1d,0x13,0x11,0x17,0x15,0x0b,0x09,0x0 keySchCol[j];
f,0x0d,0x03,0x01,0x07,0x05}, }

{0x3b,0x39,0x3f,0x3d,0x33,0x31,0x37,0x35,0x2b,0x29,0x2 for (int i = 1; i < 4; i++) {


f,0x2d,0x23,0x21,0x27,0x25}, for (int j = 0; j < 4; j++) {
roundKey[j][i+((rotConNum+1)*4)] =
{0x5b,0x59,0x5f,0x5d,0x53,0x51,0x57,0x55,0x4b,0x49,0x4 roundKey[j][i-1+((rotConNum+1)*4)] ^
f,0x4d,0x43,0x41,0x47,0x45}, roundKey[j][i+(rotConNum*4)];
}
{0x7b,0x79,0x7f,0x7d,0x73,0x71,0x77,0x75,0x6b,0x69,0x6 }
f,0x6d,0x63,0x61,0x67,0x65},
printf("Round Key:\n");
{0x9b,0x99,0x9f,0x9d,0x93,0x91,0x97,0x95,0x8b,0x89,0x8 printf("%02x %02x %02x %02x %02x %02x %02x %02x
f,0x8d,0x83,0x81,0x87,0x85}, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
{0xbb,0xb9,0xbf,0xbd,0xb3,0xb1,0xb7,0xb5,0xab,0xa9,0xa %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
f,0xad,0xa3,0xa1,0xa7,0xa5}, %02x %02x %02x\n%02x %02x %02x %02x %02x %02x %02x
%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
{0xdb,0xd9,0xdf,0xdd,0xd3,0xd1,0xd7,0xd5,0xcb,0xc9,0xc %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
f,0xcd,0xc3,0xc1,0xc7,0xc5}, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
%02x %02x %02x %02x\n%02x %02x %02x %02x %02x %02x
{0xfb,0xf9,0xff,0xfd,0xf3,0xf1,0xf7,0xf5,0xeb,0xe9,0xe %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
f,0xed,0xe3,0xe1,0xe7,0xe5}}; %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
int threeTable[16][16] = %02x %02x %02x %02x %02x\n%02x %02x %02x %02x %02x
{{0x00,0x03,0x06,0x05,0x0c,0x0f,0x0a,0x09,0x18,0x1b,0x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
1e,0x1d,0x14,0x17,0x12,0x11}, %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x
{0x30,0x33,0x36,0x35,0x3c,0x3f,0x3a,0x39,0x28,0x2b,0x2 %02x %02x %02x %02x %02x %02x\n\n", roundKey[0][0],
e,0x2d,0x24,0x27,0x22,0x21}, roundKey[0][1], roundKey[0][2], roundKey[0][3],
roundKey[0][4], roundKey[0][5], roundKey[0][6],
{0x60,0x63,0x66,0x65,0x6c,0x6f,0x6a,0x69,0x78,0x7b,0x7 roundKey[0][7], roundKey[0][8], roundKey[0][9],
e,0x7d,0x74,0x77,0x72,0x71}, roundKey[0][10], roundKey[0][11], roundKey[0][12],
roundKey[0][13], roundKey[0][14], roundKey[0][15],
{0x50,0x53,0x56,0x55,0x5c,0x5f,0x5a,0x59,0x48,0x4b,0x4 roundKey[0][16], roundKey[0][17], roundKey[0][18],
e,0x4d,0x44,0x47,0x42,0x41}, roundKey[0][19], roundKey[0][20], roundKey[0][21],
roundKey[0][22], roundKey[0][23], roundKey[0][24],
{0xc0,0xc3,0xc6,0xc5,0xcc,0xcf,0xca,0xc9,0xd8,0xdb,0xd roundKey[0][25], roundKey[0][26], roundKey[0][27],
e,0xdd,0xd4,0xd7,0xd2,0xd1}, roundKey[0][28], roundKey[0][29], roundKey[0][30],
roundKey[0][31], roundKey[0][32], roundKey[0][33],
{0xf0,0xf3,0xf6,0xf5,0xfc,0xff,0xfa,0xf9,0xe8,0xeb,0xe roundKey[0][34], roundKey[0][35], roundKey[0][36],
e,0xed,0xe4,0xe7,0xe2,0xe1}, roundKey[0][37], roundKey[0][38], roundKey[0][39],
roundKey[0][40], roundKey[0][41], roundKey[0][42],
{0xa0,0xa3,0xa6,0xa5,0xac,0xaf,0xaa,0xa9,0xb8,0xbb,0xb roundKey[0][43], roundKey[1][0], roundKey[1][1],
e,0xbd,0xb4,0xb7,0xb2,0xb1}, roundKey[1][2], roundKey[1][3], roundKey[1][4],
roundKey[1][5], roundKey[1][6], roundKey[1][7],
{0x90,0x93,0x96,0x95,0x9c,0x9f,0x9a,0x99,0x88,0x8b,0x8 roundKey[1][8], roundKey[1][9], roundKey[1][10],
e,0x8d,0x84,0x87,0x82,0x81}, roundKey[1][11], roundKey[1][12], roundKey[1][13],
roundKey[1][14], roundKey[1][15], roundKey[1][16],
{0x9b,0x98,0x9d,0x9e,0x97,0x94,0x91,0x92,0x83,0x80,0x8 roundKey[1][17], roundKey[1][18], roundKey[1][19],
5,0x86,0x8f,0x8c,0x89,0x8a}, roundKey[1][20], roundKey[1][21], roundKey[1][22],
roundKey[1][23], roundKey[1][24], roundKey[1][25],
{0xab,0xa8,0xad,0xae,0xa7,0xa4,0xa1,0xa2,0xb3,0xb0,0xb roundKey[1][26], roundKey[1][27], roundKey[1][28],
5,0xb6,0xbf,0xbc,0xb9,0xba}, roundKey[1][29], roundKey[1][30], roundKey[1][31],
roundKey[1][32], roundKey[1][33], roundKey[1][34],
{0xfb,0xf8,0xfd,0xfe,0xf7,0xf4,0xf1,0xf2,0xe3,0xe0,0xe roundKey[1][35], roundKey[1][36], roundKey[1][37],
5,0xe6,0xef,0xec,0xe9,0xea}, roundKey[1][38], roundKey[1][39], roundKey[1][40],
roundKey[1][41], roundKey[1][42], roundKey[1][43],
{0xcb,0xc8,0xcd,0xce,0xc7,0xc4,0xc1,0xc2,0xd3,0xd0,0xd roundKey[2][0], roundKey[2][1], roundKey[2][2],
5,0xd6,0xdf,0xdc,0xd9,0xda}, roundKey[2][3], roundKey[2][4], roundKey[2][5],
roundKey[2][6], roundKey[2][7], roundKey[2][8],
{0x5b,0x58,0x5d,0x5e,0x57,0x54,0x51,0x52,0x43,0x40,0x4 roundKey[2][9], roundKey[2][10], roundKey[2][11],
5,0x46,0x4f,0x4c,0x49,0x4a}, roundKey[2][12], roundKey[2][13], roundKey[2][14],
roundKey[2][15], roundKey[2][16], roundKey[2][17],
{0x6b,0x68,0x6d,0x6e,0x67,0x64,0x61,0x62,0x73,0x70,0x7 roundKey[2][18], roundKey[2][19], roundKey[2][20],
5,0x76,0x7f,0x7c,0x79,0x7a}, roundKey[2][21], roundKey[2][22], roundKey[2][23],
roundKey[2][24], roundKey[2][25], roundKey[2][26],
{0x3b,0x38,0x3d,0x3e,0x37,0x34,0x31,0x32,0x23,0x20,0x2 roundKey[2][27], roundKey[2][28], roundKey[2][29],
5,0x26,0x2f,0x2c,0x29,0x2a}, roundKey[2][30], roundKey[2][31], roundKey[2][32],
roundKey[2][33], roundKey[2][34], roundKey[2][35],
{0x0b,0x08,0x0d,0x0e,0x07,0x04,0x01,0x02,0x13,0x10,0x1 roundKey[2][36], roundKey[2][37], roundKey[2][38],
5,0x16,0x1f,0x1c,0x19,0x1a}}; roundKey[2][39], roundKey[2][40], roundKey[2][41],
roundKey[2][42], roundKey[2][43], roundKey[3][0],
roundKey[3][1], roundKey[3][2], roundKey[3][3],
void keySchedulingProcess(int rotConNum){ roundKey[3][4], roundKey[3][5], roundKey[3][6],
int keySchCol[4] = {roundKey[1][3+(rotConNum*4)], roundKey[3][7], roundKey[3][8], roundKey[3][9],
roundKey[2][3+(rotConNum*4)], roundKey[3][10], roundKey[3][11], roundKey[3][12],
roundKey[3][3+(rotConNum*4)], roundKey[3][13], roundKey[3][14], roundKey[3][15],
roundKey[0][3+(rotConNum*4)]}; roundKey[3][16], roundKey[3][17], roundKey[3][18],
int lutXaxis, lutYaxis; roundKey[3][19], roundKey[3][20], roundKey[3][21],
roundKey[3][22], roundKey[3][23], roundKey[3][24],

 
xliv  
 

roundKey[3][25], roundKey[3][26], roundKey[3][27], mixResult[j] =


roundKey[3][28], roundKey[3][29], roundKey[3][30], twoTable[lutYaxis][lutXaxis];
roundKey[3][31], roundKey[3][32], roundKey[3][33], }else if (mixColumnMatrix[j][0] == 3){
roundKey[3][34], roundKey[3][35], roundKey[3][36], mixResult[j] =
roundKey[3][37], roundKey[3][38], roundKey[3][39], threeTable[lutYaxis][lutXaxis];
roundKey[3][40], roundKey[3][41], roundKey[3][42], }else{
roundKey[3][43]); mixResult[j] = mixTemp[0];
} }

lutYaxis = (mixTemp[1]&0xf0)>>4;
int main(int argc, const char * argv[]) { lutXaxis = mixTemp[1]&0x0f;
// insert code here...
int dataIn[4][4] = {{0x32, 0x88, 0x31, 0xe0}, if (mixColumnMatrix[j][1] == 2) {
{0x43, 0x5a, 0x31, 0x37}, mixResult[j] = mixResult[j] ^
{0xf6, 0x30, 0x98, 0x07}, twoTable[lutYaxis][lutXaxis];
{0xa8, 0x8d, 0xa2, 0x34}}; }else if (mixColumnMatrix[j][1] == 3){
mixResult[j] = mixResult[j] ^
int rotConNum = 0; threeTable[lutYaxis][lutXaxis];
}else{
//Initial ADDROUNDKEY mixResult[j] = mixResult[j] ^
for (int i = 0; i < 4; i++) { mixTemp[1];
for (int j = 0; j < 4; j++) { }
dataIn[j][i] = dataIn[j][i] ^
roundKey[j][i];
} lutYaxis = (mixTemp[2]&0xf0)>>4;
} lutXaxis = mixTemp[2]&0x0f;
keySchedulingProcess(rotConNum);
rotConNum++; if (mixColumnMatrix[j][2] == 2) {
mixResult[j] = mixResult[j] ^
for (int k = 0; k < 9; k++) { twoTable[lutYaxis][lutXaxis];
//SUBBYTES state }else if (mixColumnMatrix[j][2] == 3){
int lutXaxis, lutYaxis; mixResult[j] = mixResult[j] ^
for (int i = 0; i < 4; i++) { threeTable[lutYaxis][lutXaxis];
for (int j = 0; j < 4; j++) { }else{
lutYaxis = (dataIn[j][i]&0xf0)>>4; mixResult[j] = mixResult[j] ^
lutXaxis = dataIn[j][i]&0x0f; mixTemp[2];
}
dataIn[j][i] =
encLookupTbl[lutYaxis][lutXaxis];
} lutYaxis = (mixTemp[3]&0xf0)>>4;
} lutXaxis = mixTemp[3]&0x0f;
printf("Data after SUBBYTES Round %d\n", k+1);
printf("%02x %02x %02x %02x\n%02x %02x %02x if (mixColumnMatrix[j][3] == 2) {
%02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n", mixResult[j] = mixResult[j] ^
dataIn[0][0], dataIn[0][1], dataIn[0][2], twoTable[lutYaxis][lutXaxis];
dataIn[0][3], dataIn[1][0], dataIn[1][1], }else if (mixColumnMatrix[j][3] == 3){
dataIn[1][2], dataIn[1][3], dataIn[2][0], mixResult[j] = mixResult[j] ^
dataIn[2][1], dataIn[2][2], dataIn[2][3], threeTable[lutYaxis][lutXaxis];
dataIn[3][0], dataIn[3][1], dataIn[3][2], }else{
dataIn[3][3]); mixResult[j] = mixResult[j] ^
mixTemp[3];
//SHIFTROWS state }
for (int i = 1; i < 4; i++) {
int shiftTemp[4] = {dataIn[i][0], }
dataIn[i][1], dataIn[i][2], dataIn[i][3]};
dataIn[i][0] = shiftTemp[i]; dataIn[0][i] = mixResult[0];
dataIn[i][1] = shiftTemp[(i+1 < 4 ? i+1 : dataIn[1][i] = mixResult[1];
i+1-4)]; dataIn[2][i] = mixResult[2];
dataIn[i][2] = shiftTemp[(i+2 < 4 ? i+2 : dataIn[3][i] = mixResult[3];
i+2-4)]; }
dataIn[i][3] = shiftTemp[(i+3 < 4 ? i+3 : printf("Data after MIXCOLUMNS Round %d\n",
i+3-4)]; k+1);
} printf("%02x %02x %02x %02x\n%02x %02x %02x
printf("Data after SHIFTROWS Round %d\n", %02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n",
k+1); dataIn[0][0], dataIn[0][1], dataIn[0][2],
printf("%02x %02x %02x %02x\n%02x %02x %02x dataIn[0][3], dataIn[1][0], dataIn[1][1],
%02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n", dataIn[1][2], dataIn[1][3], dataIn[2][0],
dataIn[0][0], dataIn[0][1], dataIn[0][2], dataIn[2][1], dataIn[2][2], dataIn[2][3],
dataIn[0][3], dataIn[1][0], dataIn[1][1], dataIn[3][0], dataIn[3][1], dataIn[3][2],
dataIn[1][2], dataIn[1][3], dataIn[2][0], dataIn[3][3]);
dataIn[2][1], dataIn[2][2], dataIn[2][3],
dataIn[3][0], dataIn[3][1], dataIn[3][2], //ADDROUNDKEY step
dataIn[3][3]); for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
//MIXCOLUMNS step dataIn[j][i] = dataIn[j][i] ^
for (int i = 0; i < 4; i++) { roundKey[j][i];
int mixTemp[4] = {dataIn[0][i], }
dataIn[1][i], dataIn[2][i], dataIn[3][i]}; }
int mixResult[4];
printf("Data after ADDROUNDKEY Round %d\n",
for (int j = 0; j < 4; j++) { k+1);
mixResult[j] = printf("%02x %02x %02x %02x\n%02x %02x %02x
mixColumnMatrix[j][0]*mixTemp[0] + %02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n",
mixColumnMatrix[j][1]*mixTemp[1] + dataIn[0][0], dataIn[0][1], dataIn[0][2],
mixColumnMatrix[j][2]*mixTemp[2] + dataIn[0][3], dataIn[1][0], dataIn[1][1],
mixColumnMatrix[j][3]*mixTemp[3]; dataIn[1][2], dataIn[1][3], dataIn[2][0],
int lutXaxis, lutYaxis; dataIn[2][1], dataIn[2][2], dataIn[2][3],
lutYaxis = (mixTemp[0]&0xf0)>>4; dataIn[3][0], dataIn[3][1], dataIn[3][2],
lutXaxis = mixTemp[0]&0x0f; dataIn[3][3]);

if (mixColumnMatrix[j][0] == 2) { keySchedulingProcess(rotConNum);

 
xlv  
 

rotConNum++; 4)];
} }
printf("Data after SHIFTROWS Round 10\n");
//final SUBBYTES state printf("%02x %02x %02x %02x\n%02x %02x %02x
int lutXaxis, lutYaxis; %02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n",
for (int i = 0; i < 4; i++) { dataIn[0][0], dataIn[0][1], dataIn[0][2],
for (int j = 0; j < 4; j++) { dataIn[0][3], dataIn[1][0], dataIn[1][1],
lutYaxis = (dataIn[j][i]&0xf0)>>4; dataIn[1][2], dataIn[1][3], dataIn[2][0],
lutXaxis = dataIn[j][i]&0x0f; dataIn[2][1], dataIn[2][2], dataIn[2][3],
dataIn[3][0], dataIn[3][1], dataIn[3][2],
dataIn[j][i] = dataIn[3][3]);
encLookupTbl[lutYaxis][lutXaxis];
} //final ADDROUNDKEY step
} for (int i = 0; i < 4; i++) {
printf("Data after SUBBYTES Round 10\n"); for (int j = 0; j < 4; j++) {
printf("%02x %02x %02x %02x\n%02x %02x %02x dataIn[j][i] = dataIn[j][i] ^
%02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n", roundKey[j][i];
dataIn[0][0], dataIn[0][1], dataIn[0][2], }
dataIn[0][3], dataIn[1][0], dataIn[1][1], }
dataIn[1][2], dataIn[1][3], dataIn[2][0],
dataIn[2][1], dataIn[2][2], dataIn[2][3], printf("Data after ADDROUNDKEY Round
dataIn[3][0], dataIn[3][1], dataIn[3][2], 10\n**************CIPHERETEXT****************\n");
dataIn[3][3]); printf("%02x %02x %02x %02x\n%02x %02x %02x
%02x\n%02x %02x %02x %02x\n%02x %02x %02x %02x\n\n",
//final SHIFTROWS state dataIn[0][0], dataIn[0][1], dataIn[0][2],
for (int i = 1; i < 4; i++) { dataIn[0][3], dataIn[1][0], dataIn[1][1],
int shiftTemp[4] = {dataIn[i][0], dataIn[1][2], dataIn[1][3], dataIn[2][0],
dataIn[i][1], dataIn[i][2], dataIn[i][3]}; dataIn[2][1], dataIn[2][2], dataIn[2][3],
dataIn[i][0] = shiftTemp[i]; dataIn[3][0], dataIn[3][1], dataIn[3][2],
dataIn[i][1] = shiftTemp[(i+1 < 4 ? i+1 : i+1- dataIn[3][3]);
4)];
dataIn[i][2] = shiftTemp[(i+2 < 4 ? i+2 : i+2-
4)]; return 0;
dataIn[i][3] = shiftTemp[(i+3 < 4 ? i+3 : i+3- }

 
 
Ø RSA  algorithm:  
// }
// main.c if (temp == 0) {
// RSAalgorithm coprimes[cCounter] = i;
// cCounter++;
// Created by Ricardo Viteri on 5/7/15. }
// Copyright (c) 2015 Ricardo Viteri. All rights }
reserved.
// e = coprimes[rand()%(cCounter < 5 ? cCounter :
5)];
#include <stdio.h>
#include <math.h> //calculate d such as (d*e)%n = 1
#include <stdlib.h> int d = 0;
for (int i = 0; i<n; i++) {
int main(int argc, const char * argv[]) { int temp = (i*e)%phi;
// insert code here... if (temp == 1) {
d=i;
/******************************** KEY GENERATION break;
*******************************/ }
int p = 3, q = 13; }

//Obtain n printf("We have keys!!\n");


int n = p*q; printf("Public key = (%d, %d)\n", n, e);
printf("Private key = (%d, %d)\n", n, d);
//use Euler totient function to obtain phi
(phi(n))
int phi = n - (p + q - 1); /******************************** ENCRYPTION
*******************************/
//choose an integer e such as (1 < e < phi) and is
coprime with n //Message must be changed into an integer number m
int e = 0; such that (0 <= m <= n)
int array[100], a = 0, coprimes[100], cCounter = int m = n/8;
0; printf("The message is: %d\n",m);
for (int i = 2; i < phi; i++) {
if (phi%i == 0) { //Encryption is done by encMessage = (m^e)mod(n)
array[a] = i; long encMessage = pow(m, e);
a++; encMessage = encMessage%n;
} printf("The encoded message is: %ld\n",
} encMessage);

for (int i = 2; i<phi; i++) {


int temp = 0;
for (int j = 0; j<a-1; j++) { /******************************** DECRYPTION
if (i%array[j] == 0) { *******************************/
temp++;
} //Decryption is done by decMessage =
(encMessage^d)mod(n)

 
xlvi  
 

long decMessage = pow(encMessage, d); decMessage);


decMessage = decMessage%n;
return 0;
//decMessage and m should be the same }
printf("The decoded message is: %ld\n",

 
xlvi  

Potrebbero piacerti anche