package Ġcom . tom o chain . wallet . core . hab ak . crypto graphy . legacy Ċ Ċ import Ġandroid . annotation . Target Api Ċ import Ġandroid . content . Context Ċ import Ġandroid . content . SharedPreferences Ċ import Ġandroid . os . Build Ċ import Ġandroid . security . KeyPair Generator Spec Ċ import Ġandroid . security . keystore . Key Gen Parameter Spec Ċ import Ġandroid . security . keystore . Key Properties Ċ import Ġandroid . util . Base 6 4 Ċ import Ġjava . io .* Ċ import Ġjava . math . BigInteger Ċ import Ġjava . nio . charset . Charset Ċ import Ġjava . security .* Ċ import Ġjava . security . cert . Certificate Exception Ċ import Ġjava . security . interfaces . RS AP rivate Key Ċ import Ġjava . security . interfaces . RS AP ublic Key Ċ import Ġjava . util .* Ċ import Ġjavax . crypto .* Ċ import Ġjavax . crypto . spec . GCM Parameter Spec Ċ import Ġjavax . crypto . spec . Iv Parameter Spec Ċ import Ġjavax . crypto . spec . SecretKey Spec Ċ import Ġjavax . security . auth . x 5 0 0 . X 5 0 0 Principal Ċ import Ġkotlin . experimental . xor Ċ Ċ /** Ċ Ġ* ĠCreated Ġby ĠN ien Le Ġon Ġ 1 1 , Oct ober , 2 0 1 8 Ċ Ġ* ĠMid summer . Ċ Ġ* ĠPing Ġme Ġat Ġn ien bk ict @ gmail . com Ċ Ġ* ĠH appy Ġcoding Ġ^ _ ^ Ċ Ġ*/ Ċ class ĠEncryption Manager Ċ /** Ċ Ġ* Ċ Ġ* Ġ@ param Ġcontext Ġapplication Ġcontext Ċ Ġ* Ġ@ param Ġpref Store Ġbacking Ġstore Ġfor Ġstoring Ġinformation Ċ Ġ* Ġ@ param Ġkey Alias Prefix Ġprefix Ġfor Ġkey Ġaliases Ċ Ġ* Ġ@ param Ġbit Sh ifting Key Ġa Ġkey Ġto Ġuse Ġfor Ġrandom ization Ġ( seed ) Ġand Ġbit Ġsh ifting , Ġthis Ġen h ances Ċ Ġ* Ġthe Ġsecurity Ġon Ġolder ĠOS Ġversions Ġa Ġbit Ċ Ġ* Ġ@ param Ġrecovery Handler Ġcallback / listener Ġfor Ġrecovery Ġnotification Ċ Ġ* Ġ@ throws ĠIOException Ċ Ġ* Ġ@ throws ĠNoSuch AlgorithmException Ċ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception Ċ Ġ* Ġ@ throws ĠNoSuch Provider Exception Ċ Ġ* Ġ@ throws ĠNoSuch Padding Exception Ċ Ġ* Ġ@ throws ĠCertificate Exception Ċ Ġ* Ġ@ throws ĠKey Store Exception Ċ Ġ* Ġ@ throws ĠUn recover able Entry Exception Ċ Ġ* Ġ@ throws ĠInvalid Key Exception Ċ Ġ* Ġ@ throws ĠIllegalStateException Ċ Ġ*/ Ċ @ Throws ( IOException :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch Padding Exception :: class , ĠCertificate Exception :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class , ĠInvalid Key Exception :: class , ĠIllegalStateException :: class ) Ċ constructor ( private Ġval ĠmContext : ĠContext , Ġinternal Ġvar Ġm Prefs : ĠSharedPreferences , Ġ Ġkey Alias Prefix : ĠString ?, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠSHIFT ING _ KEY : ĠByteArray ?, Ġinternal Ġvar Ġm Recovery Handler : ĠKey Store Recovery Notifier ?) Ġ{ ĊĠĠĠ Ġprivate Ġval ĠRSA _ BIT _ LENGTH Ġ= Ġ 2 0 4 8 ĊĠĠĠ Ġprivate Ġval ĠAES _ BIT _ LENGTH Ġ= Ġ 2 5 6 ĊĠĠĠ Ġprivate Ġval ĠMAC _ BIT _ LENGTH Ġ= Ġ 2 5 6 ĊĠĠĠ Ġprivate Ġval ĠG CM _ TAG _ LENGTH Ġ= Ġ 1 2 8 ĊĊĠĠĠ Ġprivate Ġval ĠCOMP AT _ IV _ LENGTH Ġ= Ġ 1 6 ĊĠĠĠ Ġprivate Ġval ĠIV _ LENGTH Ġ= Ġ 1 2 ĊĊĠĠĠ Ġprivate Ġval ĠKEY STORE _ PROVIDER Ġ= Ġ" Android KeyStore " ĊĠĠĠ Ġprivate Ġval ĠSSL _ PROVIDER Ġ= Ġ" Android Open SSL " ĊĠĠĠ Ġprivate Ġval ĠBO UN CY _ CAST LE _ PROVIDER Ġ= Ġ" BC " ĊĊĠĠĠ Ġprivate Ġval ĠRSA _ KEY _ ALIAS : ĠString ĊĠĠĠ Ġprotected Ġval ĠAES _ KEY _ ALIAS : ĠString ĊĠĠĠ Ġprotected Ġval ĠMAC _ KEY _ ALIAS : ĠString ĊĊĠĠĠ Ġprivate Ġval ĠDE LIMITER Ġ= Ġ" ]" ĊĊĠĠĠ Ġprivate Ġval ĠRSA _ CIPHER Ġ= ĠKEY _ ALGORITHM _ RSA Ġ+ Ġ"/" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBLOCK _ MODE _ E CB Ġ+ Ġ"/" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEN CRYPT ION _ P ADDING _ RSA _ PKCS 1 ĊĠĠĠ Ġprivate Ġval ĠAES _ CIPHER Ġ= ĠKEY _ ALGORITHM _ AES Ġ+ Ġ"/" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBLOCK _ MODE _ GCM Ġ+ Ġ"/" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEN CRYPT ION _ P ADDING _ NONE ĊĠĠĠ Ġprivate Ġval ĠAES _ CIPHER _ COMPAT Ġ= ĠKEY _ ALGORITHM _ AES Ġ+ Ġ"/" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠBLOCK _ MODE _ CBC Ġ+ Ġ"/" Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠEN CRYPT ION _ P ADDING _ PKCS 7 ĊĠĠĠ Ġprivate Ġval ĠMAC _ CIPHER Ġ= ĠMAC _ ALGORITHM _ HMAC _ SHA 2 5 6 ĊĊĠĠĠ Ġprotected Ġval ĠIS _ COMPAT _ MODE _ KEY _ ALIAS : ĠString ĊĊĠĠĠ Ġprivate Ġvar Ġm Store : ĠKey Store ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġaes Key : ĠSecret Key ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġmac Key : ĠSecret Key ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġvar ĠpublicKey : ĠRS AP ublic Key ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar ĠprivateKey : ĠRS AP rivate Key ? Ġ= Ġnull ĊĊĠĠĠ Ġprivate Ġval Ġm Key Alias Prefix : ĠString ĊĊĠĠĠ Ġprivate Ġvar Ġis Compat Mode Ġ= Ġfalse ĊĊĠĠĠ Ġinternal Ġval Ġiv : ĠByteArray ĊĠĠĠĠĠĠĠ Ġ@ Throws ( Unsupported EncodingException :: class ) ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġiv : ĠByteArray ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! is Compat Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġiv Ġ= ĠByteArray ( IV _ LENGTH ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġiv Ġ= ĠByteArray ( COMPAT _ IV _ LENGTH ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrng Ġ= ĠSecure Random () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrng . next Bytes ( iv ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġiv ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġcontext ĊĠĠĠĠ Ġ* Ġ@ param Ġpref Store ĊĠĠĠĠ Ġ* Ġ@ param Ġrecovery Notifier ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠCertificate Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠKey Store Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUn recover able Entry Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Deprecated (" Use Ġthe Ġfull Ġconstructor Ġfor Ġbetter Ġsecurity Ġon Ġolder Ġversions Ġof ĠAndroid \ n " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" ĠĠĠĠĠ Ġ") ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠCertificate Exception :: class , ĠNoSuch AlgorithmException :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠNoSuch Provider Exception :: class ) ĊĠĠĠ Ġconstructor ( context : ĠContext , Ġpref Store : ĠSharedPreferences , Ġrecovery Notifier : ĠKey Store Recovery Notifier ) Ġ: Ġthis ( context , Ġpref Store , Ġnull , Ġnull , Ġrecovery Notifier ) Ġ{ ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġkey Alias Prefix Ġ= Ġkey Alias Prefix ĊĊĠĠĠĠĠĠĠ Ġkey Alias Prefix Ġ= Ġm Prefs . getString ( get Has hed ( OVER RID ING _ KEY _ ALIAS _ PREFIX _ NAME ), Ġkey Alias Prefix ) ĊĠĠĠĠĠĠĠ Ġm Key Alias Prefix Ġ= Ġkey Alias Prefix Ġ?: ĠDEFAULT _ KEY _ ALIAS _ PREFIX ĊĠĠĠĠĠĠĠ ĠIS _ COMPAT _ MODE _ KEY _ ALIAS Ġ= ĠString . format ("% s _% s ", Ġm Key Alias Prefix , ĠIS _ COMPAT _ MODE _ KEY _ ALIAS _ NAME ) ĊĠĠĠĠĠĠĠ ĠRSA _ KEY _ ALIAS Ġ= ĠString . format ("% s _% s ", Ġm Key Alias Prefix , ĠRSA _ KEY _ ALIAS _ NAME ) ĊĠĠĠĠĠĠĠ ĠAES _ KEY _ ALIAS Ġ= ĠString . format ("% s _% s ", Ġm Key Alias Prefix , ĠAES _ KEY _ ALIAS _ NAME ) ĊĠĠĠĠĠĠĠ ĠMAC _ KEY _ ALIAS Ġ= ĠString . format ("% s _% s ", Ġm Key Alias Prefix , ĠMAC _ KEY _ ALIAS _ NAME ) ĊĊĠĠĠĠĠĠĠ Ġval Ġis Compat Key Ġ= Ġget Has hed ( IS _ COMPAT _ MODE _ KEY _ ALIAS ) ĊĠĠĠĠĠĠĠ Ġis Compat Mode Ġ= Ġm Prefs . getBoolean ( is Compat Key , ĠBuild . VERSION . SDK _ INT Ġ< ĠBuild . VERSION _ CODES . M ) ĊĊĠĠĠĠĠĠĠ Ġload KeyStore () ĊĊĠĠĠĠĠĠĠ Ġvar Ġtry Again Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup ( mContext , Ġm Prefs , ĠSHIFT ING _ KEY ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Recover able Error ( ex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Again Ġ= Ġtry Recovery ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( try Again ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup ( mContext , Ġm Prefs , ĠSHIFT ING _ KEY ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġ< T Ġ: ĠException > Ġis Recover able Error ( error : ĠT ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġ( error Ġis ĠKey Store Exception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġerror Ġis ĠUn recover able Entry Exception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġerror Ġis ĠInvalid Key Exception ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġerror Ġis ĠIllegalStateException ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ|| Ġerror Ġis ĠIOException Ġ&& Ġerror . cause Ġ!= Ġnull Ġ&& Ġerror . cause Ġis ĠBad Padding Exception ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠNoSuch AlgorithmException :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġsetup ( context : ĠContext , Ġpref Store : ĠSharedPreferences , Ġ Ġseed : ĠByteArray ?) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Generated Ġ= Ġgenerate Key ( context , Ġseed , Ġpref Store ) ĊĠĠĠĠĠĠĠ Ġif Ġ( key Generated ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// store Ġthe Ġalias Ġprefix ĊĠĠĠĠĠĠĠĠĠĠĠ Ġm Prefs . edit (). putString ( get Has hed ( OVER RID ING _ KEY _ ALIAS _ PREFIX _ NAME ), Ġm Key Alias Prefix ). commit () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġload Key ( pref Store ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġ< T Ġ: ĠException > Ġtry Recovery ( e : ĠT ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġm Recovery Handler Ġ!= Ġnull Ġ&& Ġm Recovery Handler !!. on Recovery Required ( e , Ġm Store !! , Ġkey Aliases ()) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġkey Aliases (): ĠList < String > Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠArrays . asList ( AES _ KEY _ ALIAS , ĠRSA _ KEY _ ALIAS ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠT ries Ġto Ġrecover Ġonce Ġif Ġa ĠKe yst ore Ġerror Ġoccurs ĊĠĠĠĠ Ġ* Ġ@ param Ġbytes ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠIOException :: class , ĠBad Padding Exception :: class , ĠIllegal BlockSize Exception :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Key Exception :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class ) ĊĠĠĠ Ġfun Ġtry Encrypt ( bytes : ĠByteArray ): ĠEn crypted Data ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult : ĠEn crypted Data ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġtry Again Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġencrypt ( bytes ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Recover able Error ( ex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Again Ġ= Ġtry Recovery ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( try Again ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup ( mContext , Ġm Prefs , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġencrypt ( bytes ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDoes n 't Ġdelete Ġthe Ġoriginal Ġfile . ĊĠĠĠĠ Ġ* Ġ@ param Ġfile In Ġfile Ġto Ġencrypt ĊĠĠĠĠ Ġ* Ġ@ param Ġfile Out Ġfile Ġto Ġwrite Ġencrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠKey Store Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUn recover able Entry Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Padding Exception :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class ) ĊĠĠĠ Ġfun Ġtry Encrypt ( file In : ĠBuffered InputStream , Ġfile Out : ĠBuffered OutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtry Again Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġencrypt ( file In , Ġfile Out ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Recover able Error ( ex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Again Ġ= Ġtry Recovery ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( try Again ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup ( mContext , Ġm Prefs , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġencrypt ( file In , Ġfile Out ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠDoes n 't Ġdelete Ġthe Ġoriginal Ġfile . ĊĠĠĠĠ Ġ* Ġ@ param Ġfile In Ġfile Ġto Ġdecrypt ĊĠĠĠĠ Ġ* Ġ@ param Ġfile Out Ġfile Ġto Ġwrite Ġdecrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠKey Store Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUn recover able Entry Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Padding Exception :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class ) ĊĠĠĠ Ġfun Ġtry Decrypt ( file In : ĠBuffered InputStream , Ġfile Out : ĠBuffered OutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġtry Again Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdecrypt ( file In , Ġfile Out ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Recover able Error ( ex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Again Ġ= Ġtry Recovery ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( try Again ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup ( mContext , Ġm Prefs , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdecrypt ( file In , Ġfile Out ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġtries Ġrecovery Ġonce Ġif Ġa ĠKe yst ore Ġerror Ġoccurs ĊĠĠĠĠ Ġ* Ġ@ param Ġdata ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠKey Store Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUn recover able Entry Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Mac Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Key Exception :: class , ĠIOException :: class , ĠBad Padding Exception :: class , ĠIllegal BlockSize Exception :: class , ĠInvalid Mac Exception :: class ) ĊĠĠĠ Ġfun Ġtry Decrypt ( data : ĠEn crypted Data ): ĠByteArray ? Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult : ĠByteArray ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġvar Ġtry Again Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġdecrypt ( data ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ex : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Recover able Error ( ex )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Again Ġ= Ġtry Recovery ( ex ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġex ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( try Again ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsetup ( mContext , Ġm Prefs , Ġnull ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġdecrypt ( data ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* Ġ@ param Ġbytes ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠIOException :: class , ĠBad Padding Exception :: class , ĠNoSuch Provider Exception :: class , ĠIllegal BlockSize Exception :: class , ĠInvalid Algorithm Parameter Exception :: class ) ĊĠĠĠ Ġfun Ġencrypt ( bytes : ĠByteArray ?): ĠEn crypted Data ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( bytes Ġ!= Ġnull Ġ&& Ġbytes . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠIV Ġ= Ġiv ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( is Compat Mode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencrypt AES Compat ( bytes , ĠIV ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġencrypt AES ( bytes , ĠIV ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġdata ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Mac Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠIllegal BlockSize Exception :: class , ĠBad Padding Exception :: class , ĠInvalid Mac Exception :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Key Exception :: class ) ĊĠĠĠ Ġfun Ġdecrypt ( data : ĠEn crypted Data ?): ĠByteArray ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( data Ġ!= Ġnull Ġ&& Ġdata . encrypted Data Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( is Compat Mode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecrypt AES Compat ( data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdecrypt AES ( data ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġnull ĊĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġtext ĊĠĠĠĠ Ġ* Ġ@ return Ġbase 6 4 Ġencoded Ġencrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( Invalid Key Exception :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Padding Exception :: class , ĠIOException :: class , ĠIllegal BlockSize Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch Provider Exception :: class , ĠBad Padding Exception :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġencrypt ( text : ĠString ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( text Ġ!= Ġnull Ġ&& Ġtext . length Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencrypted Ġ= Ġtry Encrypt ( text . toByteArray ( charset ( DEFAULT _ CHARSET ))) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġencode Encrypted Data ( encrypted ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġtext Ġbase 6 4 Ġencoded Ġencrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ return ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠNoSuch AlgorithmException :: class , ĠIllegal BlockSize Exception :: class , ĠBad Padding Exception :: class , ĠInvalid Mac Exception :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠKey Store Exception :: class , ĠUn recover able Entry Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġdecrypt ( text : ĠString ?): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( text Ġ!= Ġnull Ġ&& Ġtext . length Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencrypted Data Ġ= Ġdecode Encrypted Text ( text ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdecrypted Ġ= Ġtry Decrypt ( encrypted Data ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠString ( de crypted !! , Ġ 0 , Ġdecrypted !!. size , ĠCharset . default Charset ()) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġfile In Ġfile Ġto Ġencrypt ĊĠĠĠĠ Ġ* Ġ@ param Ġfile Out Ġfile Ġto Ġstore Ġencrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Padding Exception :: class ) ĊĠĠĠ Ġfun Ġencrypt ( file In : ĠBuffered InputStream , Ġfile Out : ĠBuffered OutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠIV Ġ= Ġiv ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= Ġif Ġ( is Compat Mode ) Ġget Cipher AES Compat ( IV , Ġtrue ) Ġelse Ġget Cipher AES ( IV , Ġtrue ) ĊĠĠĠĠĠĠĠ Ġval Ġcipher Out Ġ= ĠCipher OutputStream ( file Out , Ġcipher ) ĊĊĠĠĠĠĠĠĠ Ġ// store ĠIV ĊĠĠĠĠĠĠĠ Ġfile Out . write ( IV ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( 4 0 9 6 ) ĊĠĠĠĠĠĠĠ Ġvar Ġread Ġ= Ġfile In . read ( buffer ) ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( read Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Ġ= Ġfile In . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcipher Out . write ( buffer , Ġ 0 , Ġread ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ// TODO : Ġfind Ġa Ġway Ġto Ġcompute ĠMAC Ġiter atively Ġwithout Ġloading Ġthe Ġwhole Ġfile Ġin Ġmemory ĊĊĠĠĠĠĠĠĠ Ġcipher Out . flush () ĊĠĠĠĠĠĠĠ Ġcipher Out . close () ĊĊĠĠĠĠĠĠĠ Ġfile In . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġfile In Ġencrypted Ġfile ĊĠĠĠĠ Ġ* Ġ@ param Ġfile Out Ġfile Ġto Ġstore Ġdecrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠIOException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Padding Exception :: class ) ĊĠĠĠ Ġfun Ġdecrypt ( file In : ĠBuffered InputStream , Ġfile Out : ĠBuffered OutputStream ) Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠIV Length Ġ= Ġif Ġ( is Compat Mode ) ĠCOMP AT _ IV _ LENGTH Ġelse ĠIV _ LENGTH ĊĠĠĠĠĠĠĠ Ġval ĠIV Ġ= ĠByteArray ( IV Length ) ĊĊĠĠĠĠĠĠĠ Ġvar Ġread Ġ= Ġfile In . read ( IV , Ġ 0 , ĠIV Length ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( read Ġ== Ġ- 1 Ġ|| Ġread Ġ!= ĠIV Length ) Ġthrow ĠIllegalArgumentException (" Unexpected Ġencryption Ġstate ") ĊĊĠĠĠĠĠĠĠ Ġ// TODO : Ġfind Ġa Ġway Ġto Ġvalidate ĠMAC Ġiter atively Ġwithout Ġloading Ġthe Ġwhole Ġfile Ġin Ġmemory ĊĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= Ġif Ġ( is Compat Mode ) Ġget Cipher AES Compat ( IV , Ġfalse ) Ġelse Ġget Cipher AES ( IV , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġval Ġcipher In Ġ= ĠCipher InputStream ( file In , Ġcipher ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbuffer Ġ= ĠByteArray ( 4 0 9 6 ) ĊĊĠĠĠĠĠĠĠ Ġread Ġ= Ġcipher In . read ( buffer ) ĊĠĠĠĠĠĠĠ Ġwhile Ġ( read Ġ!= Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġread Ġ= Ġcipher In . read ( buffer ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfile Out . write ( buffer , Ġ 0 , Ġread ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġfile Out . flush () ĊĠĠĠĠĠĠĠ Ġfile Out . close () ĊĊĠĠĠĠĠĠĠ Ġcipher In . close () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġencode Encrypted Data ( data : ĠEn crypted Data ?): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( data !!. mac Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbase 6 4 Encode ( data . iv ) Ġ+ ĠDE LIMITER Ġ+ Ġbase 6 4 Encode ( data . encrypted Data ) Ġ+ ĠDE LIMITER Ġ+ Ġbase 6 4 Encode ( data . mac ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbase 6 4 Encode ( data . iv ) Ġ+ ĠDE LIMITER Ġ+ Ġbase 6 4 Encode ( data . encrypted Data ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinternal Ġfun Ġdecode Encrypted Text ( text : ĠString ): ĠEn crypted Data Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠEn crypted Data () ĊĠĠĠĠĠĠĠ Ġval Ġparts Ġ= Ġtext . split ( DE LIMITER . to Regex ()). drop Last While Ġ{ Ġit . isEmpty () Ġ}. to Typed Array () ĊĠĠĠĠĠĠĠ Ġresult . iv Ġ= Ġbase 6 4 Decode ( parts [ 0 ]) ĊĠĠĠĠĠĠĠ Ġresult . encrypted Data Ġ= Ġbase 6 4 Decode ( parts [ 1 ]) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( parts . size Ġ> Ġ 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresult . mac Ġ= Ġbase 6 4 Decode ( parts [ 2 ]) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( KeyStore Exception :: class , ĠCertificate Exception :: class , ĠNoSuch AlgorithmException :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġload KeyStore () Ġ{ ĊĠĠĠĠĠĠĠ Ġm Store Ġ= ĠKey Store . getInstance ( KEY STORE _ PROVIDER ) ĊĠĠĠĠĠĠĠ Ġm Store !!. load ( null ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param ĠIV ĠInitial isation ĠVector ĊĠĠĠĠ Ġ* Ġ@ param Ġmode Encrypt Ġif Ġtrue Ġthen Ġcipher Ġis Ġfor Ġencryption , Ġde cryption Ġotherwise ĊĠĠĠĠ Ġ* Ġ@ return Ġa ĠCipher ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Target Api ( Build . VERSION _ CODES . KIT K AT ) ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠInvalid Key Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġget Cipher AES ( IV : ĠByteArray ?, Ġmode Encrypt : ĠBoolean ): ĠCipher Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= ĠCipher . getInstance ( AES _ CIPHER ) ĊĠĠĠĠĠĠĠ Ġcipher . init ( if Ġ( mode Encrypt ) ĠCipher . ENCRYPT _ MODE Ġelse ĠCipher . DE CRYPT _ MODE , Ġaes Key , ĠG CM Parameter Spec ( GCM _ TAG _ LENGTH , ĠIV )) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġcipher ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġbytes ĊĠĠĠĠ Ġ* Ġ@ param ĠIV ĊĠĠĠĠ Ġ* Ġ@ return ĠIV Ġand ĠEn crypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUnsupported EncodingException ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Target Api ( Build . VERSION _ CODES . KIT K AT ) ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠInvalid Key Exception :: class , ĠBad Padding Exception :: class , ĠIllegal BlockSize Exception :: class , ĠUnsupported EncodingException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġencrypt AES ( bytes : ĠByteArray , ĠIV : ĠByteArray ): ĠEn crypted Data Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= Ġget Cipher AES ( IV , Ġtrue ) ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠEn crypted Data () ĊĠĠĠĠĠĠĠ Ġresult . iv Ġ= Ġcipher . iv ĊĠĠĠĠĠĠĠ Ġresult . encrypted Data Ġ= Ġcipher . do Final ( bytes ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġencrypted Data Ġ- ĠIV Ġand ĠEn crypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ return Ġdecrypted Ġdata ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUnsupported EncodingException ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Target Api ( Build . VERSION _ CODES . KIT K AT ) ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠInvalid Key Exception :: class , ĠBad Padding Exception :: class , ĠIllegal BlockSize Exception :: class , ĠUnsupported EncodingException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġdecrypt AES ( encrypted Data : ĠEn crypted Data ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= Ġget Cipher AES ( encrypted Data . iv , Ġfalse ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcipher . do Final ( encrypted Data . encrypted Data ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠInvalid Key Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġget Cipher AES Compat ( IV : ĠByteArray ?, Ġmode Encrypt : ĠBoolean ): ĠCipher Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġc Ġ= ĠCipher . getInstance ( AES _ CIPHER _ COMPAT , ĠBO UN CY _ CAST LE _ PROVIDER ) ĊĠĠĠĠĠĠĠ Ġc . init ( if Ġ( mode Encrypt ) ĠCipher . ENCRYPT _ MODE Ġelse ĠCipher . DE CRYPT _ MODE , Ġaes Key , ĠI v Parameter Spec ( IV )) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġc ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġbytes ĊĠĠĠĠ Ġ* Ġ@ param ĠIV ĊĠĠĠĠ Ġ* Ġ@ return ĠIV , ĠEn crypted ĠData Ġand ĠMac ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch AlgorithmException ĊĠĠĠĠ Ġ* Ġ@ throws ĠNoSuch Provider Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Key Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠBad Padding Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠIllegal BlockSize Exception ĊĠĠĠĠ Ġ* Ġ@ throws ĠUnsupported EncodingException ĊĠĠĠĠ Ġ* Ġ@ throws ĠInvalid Algorithm Parameter Exception ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Key Exception :: class , ĠBad Padding Exception :: class , ĠIllegal BlockSize Exception :: class , ĠUnsupported EncodingException :: class , ĠInvalid Algorithm Parameter Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġencrypt AES Compat ( bytes : ĠByteArray , ĠIV : ĠByteArray ): ĠEn crypted Data Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġget Cipher AES Compat ( IV , Ġtrue ) ĊĠĠĠĠĠĠĠ Ġval Ġresult Ġ= ĠEn crypted Data () ĊĠĠĠĠĠĠĠ Ġresult . iv Ġ= Ġc . iv ĊĠĠĠĠĠĠĠ Ġresult . encrypted Data Ġ= Ġc . do Final ( bytes ) ĊĠĠĠĠĠĠĠ Ġresult . mac Ġ= Ġcompute Mac ( result . data For Mac Computation ) ĊĊĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Unsupported EncodingException :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠBad Padding Exception :: class , ĠIllegal BlockSize Exception :: class , ĠInvalid Mac Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġdecrypt AES Compat ( encrypted Data : ĠEn crypted Data ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( verify Mac ( encrypted Data . mac , Ġencrypted Data . data For Mac Computation )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġget Cipher AES Compat ( encrypted Data . iv , Ġfalse ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġc . do Final ( encrypted Data . encrypted Data ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠInvalid Mac Exception () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( KeyStore Exception :: class , ĠUn recover able Entry Exception :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Padding Exception :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Key Exception :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġload Key ( pref Store : ĠSharedPreferences ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Compat Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( m Store !!. contains Alias ( AES _ KEY _ ALIAS ) Ġ&& Ġm Store !!. entry InstanceOf ( AES _ KEY _ ALIAS , ĠKey Store . SecretKey Entry :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġm Store !!. getEntry ( AES _ KEY _ ALIAS , Ġnull ) Ġas ĠKey Store . SecretKey Entry ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġaes Key Ġ= Ġentry . secret Key ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġaes Key Ġ= Ġget Fallback AES Key ( pref Store ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmac Key Ġ= Ġget Mac Key ( pref Store ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( KeyStore Exception :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠUn recover able Entry Exception :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġgenerate Key ( context : ĠContext , Ġ Ġseed : ĠByteArray ?, Ġpref Store : ĠSharedPreferences ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġkey Generated Ġ= Ġfalse ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! is Compat Mode ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Generated Ġ= Ġgenerate AES Key ( seed ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Generated Ġ= Ġgenerate RSA Keys ( context , Ġseed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġload RSA Keys () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Generated Ġ= Ġgenerate Fallback AES Key ( pref Store , Ġseed ) Ġ|| Ġkey Generated ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Generated Ġ= Ġgenerate Mac Key ( pref Store , Ġseed ) Ġ|| Ġkey Generated ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġkey Generated ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Target Api ( Build . VERSION _ CODES . M ) ĊĠĠĠ Ġ@ Throws ( KeyStore Exception :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġgenerate AES Key ( Ġseed : ĠByteArray ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! m Store !!. contains Alias ( AES _ KEY _ ALIAS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Gen Ġ= ĠKey Generator . getInstance ( Key Properties . KEY _ ALGORITHM _ AES , ĠKEY STORE _ PROVIDER ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspec Ġ= ĠKey Gen Parameter Spec . Builder ( AES _ KEY _ ALIAS , ĠKey Properties . P URPOSE _ ENCRYPT Ġor ĠKey Properties . P URPOSE _ DE CRYPT ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Certificate Subject ( X 5 0 0 Principal (" CN Ġ= ĠSec ured ĠPreference ĠStore , ĠO Ġ= ĠDev living ĠOnline ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Certificate SerialNumber ( BigInteger . ONE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Key Size ( AES _ BIT _ LENGTH ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Block Modes ( Key Properties . BLOCK _ MODE _ GCM ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Encryption P add ings ( Key Properties . ENCRYPT ION _ P ADDING _ NONE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Random ized Encryption Required ( false ) Ġ// TODO : Ġset Ġto Ġtrue Ġand Ġlet Ġthe ĠCipher Ġgenerate Ġa Ġsec ured ĠIV ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( seed Ġ!= Ġnull Ġ&& Ġseed . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrandom Ġ= ĠSecure Random ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . init ( spec , Ġrandom ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . init ( spec ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . generate Key () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠKey Store Exception :: class , ĠNoSuch Provider Exception :: class , ĠUn recover able Entry Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġgenerate Fallback AES Key ( pref Store : ĠSharedPreferences , Ġ Ġseed : ĠByteArray ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget Has hed ( AES _ KEY _ ALIAS ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! pref Store . contains ( key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Gen Ġ= ĠKey Generator . getInstance ( KEY _ ALGORITHM _ AES ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( seed Ġ!= Ġnull Ġ&& Ġseed . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrandom Ġ= ĠSecure Random ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . init ( AES _ BIT _ LENGTH , Ġrandom ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . init ( AES _ BIT _ LENGTH ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġs Key Ġ= Ġkey Gen . generate Key () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshifted Encoded Key Ġ= Ġxor With Key ( s Key . encoded , ĠSHIFT ING _ KEY ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencrypted Data Ġ= ĠRSA Encrypt ( shift ed Encoded Key ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval ĠAES Key Ġ= Ġbase 6 4 Encode ( encrypted Data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġpref Store . edit (). putString ( key , ĠAES Key ). commit () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġis Compat Key Ġ= Ġget Has hed ( IS _ COMPAT _ MODE _ KEY _ ALIAS ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġpref Store . edit (). put Boolean ( is Compat Key , Ġtrue ). apply () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠNoSuch AlgorithmException :: class , ĠKey Store Exception :: class , ĠNoSuch Provider Exception :: class , ĠUn recover able Entry Exception :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġgenerate Mac Key ( pref Store : ĠSharedPreferences , Ġ Ġseed : ĠByteArray ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget Has hed ( MAC _ KEY _ ALIAS ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! pref Store . contains ( key )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrandom Bytes Ġ= ĠByteArray ( MAC _ BIT _ LENGTH Ġ/ Ġ 8 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrng : ĠSecure Random ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( seed Ġ!= Ġnull Ġ&& Ġseed . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrng Ġ= ĠSecure Random ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrng Ġ= ĠSecure Random () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġrng . next Bytes ( random Bytes ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencrypted Key Ġ= ĠRSA Encrypt ( random Bytes ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmac Key Ġ= Ġbase 6 4 Encode ( encrypted Key ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġpref Store . edit (). putString ( key , Ġmac Key ). commit () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġxor With Key ( a : ĠByteArray , Ġkey : ĠByteArray ?): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( key Ġ== Ġnull Ġ|| Ġkey . size Ġ== Ġ 0 ) Ġreturn Ġa ĊĊĠĠĠĠĠĠĠ Ġval Ġout Ġ= ĠByteArray ( a . size ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġa . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġout [ i ] Ġ= Ġ( a [ i ] Ġxor Ġkey [ i Ġ% Ġkey . size ]). to Byte () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġout ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch Padding Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġget Fallback AES Key ( pref Store : ĠSharedPreferences ): ĠSecret Key ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget Has hed ( AES _ KEY _ ALIAS ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbase 6 4 Value Ġ= Ġpref Store . getString ( key , Ġnull ) ĊĠĠĠĠĠĠĠ Ġif Ġ( base 6 4 Value Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencrypted Data Ġ= Ġbase 6 4 Decode ( base 6 4 Value ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġshifted Encoded Key Ġ= ĠRSA Decrypt ( encrypted Data ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Data Ġ= Ġxor With Key ( shift ed Encoded Key , ĠSHIFT ING _ KEY ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSecret KeySpec ( key Data , Ġ" AES ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch Padding Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġget Mac Key ( pref Store : ĠSharedPreferences ): ĠSecret Key ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġget Has hed ( MAC _ KEY _ ALIAS ) ĊĊĠĠĠĠĠĠĠ Ġval Ġbase 6 4 Ġ= Ġpref Store . getString ( key , Ġnull ) ĊĠĠĠĠĠĠĠ Ġif Ġ( base 6 4 Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġencrypted Key Ġ= Ġbase 6 4 Decode ( base 6 4 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Data Ġ= ĠRSA Decrypt ( encrypted Key ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠSecret KeySpec ( key Data , ĠMAC _ CIPHER ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( KeyStore Exception :: class , ĠUn recover able Entry Exception :: class , ĠNoSuch AlgorithmException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġload RSA Keys () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( m Store !!. contains Alias ( RSA _ KEY _ ALIAS ) Ġ&& Ġm Store !!. entry InstanceOf ( RSA _ KEY _ ALIAS , ĠKey Store . PrivateKey Entry :: class . java )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentry Ġ= Ġm Store !!. getEntry ( RSA _ KEY _ ALIAS , Ġnull ) Ġas ĠKey Store . PrivateKey Entry ĊĠĠĠĠĠĠĠĠĠĠĠ ĠpublicKey Ġ= Ġentry . certificate . publicKey Ġas ĠRS AP ublic Key ĊĠĠĠĠĠĠĠĠĠĠĠ ĠprivateKey Ġ= Ġentry . privateKey Ġas ĠRS AP rivate Key ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch Provider Exception :: class , ĠNoSuch AlgorithmException :: class , ĠInvalid Algorithm Parameter Exception :: class , ĠKey Store Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġgenerate RSA Keys ( context : ĠContext , Ġseed : ĠByteArray ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! m Store !!. contains Alias ( RSA _ KEY _ ALIAS )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġkey Gen Ġ= ĠKey Pair Generator . getInstance ( KEY _ ALGORITHM _ RSA , ĠKEY STORE _ PROVIDER ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġspec : ĠKey Pair Generator Spec ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstart Ġ= ĠCalendar . getInstance () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// prob able Ġfix Ġfor Ġthe Ġtimezone Ġissue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġstart . add ( Calendar . HOUR _ OF _ DAY , Ġ- 2 6 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġend Ġ= ĠCalendar . getInstance () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġend . add ( Calendar . YEAR , Ġ 1 0 0 ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= ĠBuild . VERSION _ CODES . KIT K AT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspec Ġ= ĠKey Pair Generator Spec . Builder ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Alias ( RSA _ KEY _ ALIAS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Key Size ( RSA _ BIT _ LENGTH ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set KeyType ( Key Properties . KEY _ ALGORITHM _ RSA ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set SerialNumber ( BigInteger . ONE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Subject ( X 5 0 0 Principal (" CN Ġ= ĠSec ured ĠPreference ĠStore , ĠO Ġ= ĠDev living ĠOnline ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set StartDate ( start . time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set EndDate ( end . time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġspec Ġ= ĠKey Pair Generator Spec . Builder ( context ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Alias ( RSA _ KEY _ ALIAS ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set SerialNumber ( BigInteger . ONE ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Subject ( X 5 0 0 Principal (" CN Ġ= ĠSec ured ĠPreference ĠStore , ĠO Ġ= ĠDev living ĠOnline ")) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set StartDate ( start . time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set EndDate ( end . time ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( seed Ġ!= Ġnull Ġ&& Ġseed . size Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġrandom Ġ= ĠSecure Random ( seed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . initialize ( spec , Ġrandom ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . initialize ( spec ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey Gen . generate KeyPair () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch AlgorithmException :: class , ĠInvalid Key Exception :: class ) ĊĠĠĠ Ġinternal Ġfun Ġcompute Mac ( data : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠH mac Sha 2 5 6 Ġ= ĠMac . getInstance ( MAC _ CIPHER ) ĊĠĠĠĠĠĠĠ ĠH mac Sha 2 5 6 . init ( mac Key ) ĊĠĠĠĠĠĠĠ Ġreturn ĠH mac Sha 2 5 6 . do Final ( data ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( Invalid Key Exception :: class , ĠNoSuch AlgorithmException :: class ) ĊĠĠĠ Ġinternal Ġfun Ġverify Mac ( mac : ĠByteArray ?, Ġdata : ĠByteArray ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( mac Ġ!= Ġnull Ġ&& Ġdata Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġactual Mac Ġ= Ġcompute Mac ( data ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( actual Mac . size Ġ!= Ġmac . size ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= Ġ 0 ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġactual Mac . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġresult Ġ= Ġresult Ġor Ġ(( actual Mac [ i ] Ġxor Ġmac [ i ]). toInt ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġresult Ġ== Ġ 0 ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( KeyStore Exception :: class , ĠUn recover able Entry Exception :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Provider Exception :: class , ĠNoSuch Padding Exception :: class , ĠInvalid Key Exception :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun ĠRSA Encrypt ( bytes : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= ĠCipher . getInstance ( RSA _ CIPHER , ĠSSL _ PROVIDER ) ĊĠĠĠĠĠĠĠ Ġcipher . init ( Cipher . ENCRYPT _ MODE , ĠpublicKey ) ĊĊĠĠĠĠĠĠĠ Ġval ĠoutputStream Ġ= ĠByteArrayOutputStream () ĊĠĠĠĠĠĠĠ Ġval Ġcipher OutputStream Ġ= ĠCipher OutputStream ( output Stream , Ġcipher ) ĊĠĠĠĠĠĠĠ Ġcipher OutputStream . write ( bytes ) ĊĠĠĠĠĠĠĠ Ġcipher OutputStream . close () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠoutputStream . toByteArray () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch Padding Exception :: class , ĠNoSuch AlgorithmException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Key Exception :: class , ĠIOException :: class ) ĊĠĠĠ Ġinternal Ġfun ĠRSA Decrypt ( bytes : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= ĠCipher . getInstance ( RSA _ CIPHER , ĠSSL _ PROVIDER ) ĊĠĠĠĠĠĠĠ Ġcipher . init ( Cipher . DE CRYPT _ MODE , ĠprivateKey ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcipher InputStream Ġ= ĠCipher InputStream ( ByteArray InputStream ( bytes ), Ġcipher ) ĊĊĠĠĠĠĠĠĠ Ġval Ġvalues Ġ= ĠArrayList < Byte >() ĊĠĠĠĠĠĠĠ Ġvar Ġnext Byte Ġ= Ġcipher InputStream . read () ĊĊĠĠĠĠĠĠĠ Ġwhile Ġ( next Byte Ġ!== Ġ- 1 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvalues . add ( next Byte . to Byte ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Byte Ġ= Ġcipher InputStream . read () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġd bytes Ġ= ĠByteArray ( values . size ) ĊĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġd bytes . indices ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġd bytes [ i ] Ġ= Ġvalues [ i ] ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġcipher InputStream . close () ĊĠĠĠĠĠĠĠ Ġreturn Ġd bytes ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠEn crypted Data Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġiv : ĠByteArray ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġencrypted Data : ĠByteArray ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġmac : ĠByteArray ? Ġ= Ġnull ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return ĠIV Ġ+ ĠC IP HER ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġinternal Ġval Ġdata For Mac Computation : ĠByteArray ĊĠĠĠĠĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcombined Data Ġ= ĠByteArray ( iv !!. size Ġ+ Ġencrypted Data !!. size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( iv , Ġ 0 , Ġcombined Data , Ġ 0 , Ġiv !!. size ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . arraycopy ( encrypted Data , Ġ 0 , Ġcombined Data , Ġiv !!. size , Ġencrypted Data !!. size ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġcombined Data ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġconstructor () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġiv Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġencrypted Data Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmac Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġconstructor ( IV : ĠByteArray , Ġencrypted Data : ĠByteArray , Ġmac : ĠByteArray ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . iv Ġ= ĠIV ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . encrypted Data Ġ= Ġencrypted Data ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . mac Ġ= Ġmac ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġinner Ġclass ĠInvalid Mac Exception Ġ: ĠGeneral Security Exception (" Invalid ĠMac , Ġfailed Ġto Ġverify Ġintegrity .") ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠDEFAULT _ CHARSET Ġ= Ġ" UTF - 8 " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠRSA _ KEY _ ALIAS _ NAME Ġ= Ġ" rsa _ key " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠAES _ KEY _ ALIAS _ NAME Ġ= Ġ" aes _ key " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠMAC _ KEY _ ALIAS _ NAME Ġ= Ġ" mac _ key " ĊĊĠĠĠĠĠĠĠ Ġprotected Ġval ĠOVER RID ING _ KEY _ ALIAS _ PREFIX _ NAME Ġ= Ġ" Over riding Alias " ĊĠĠĠĠĠĠĠ Ġprotected Ġval ĠDEFAULT _ KEY _ ALIAS _ PREFIX Ġ= Ġ" sp s " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠKEY _ ALGORITHM _ AES Ġ= Ġ" AES " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠKEY _ ALGORITHM _ RSA Ġ= Ġ" RSA " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠBLOCK _ MODE _ E CB Ġ= Ġ" E CB " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠBLOCK _ MODE _ GCM Ġ= Ġ" GCM " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠBLOCK _ MODE _ CBC Ġ= Ġ" CBC " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠEN CRYPT ION _ P ADDING _ RSA _ PKCS 1 Ġ= Ġ" PKCS 1 Padding " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠEN CRYPT ION _ P ADDING _ PKCS 7 Ġ= Ġ" PKCS 7 Padding " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠEN CRYPT ION _ P ADDING _ NONE Ġ= Ġ" No Padding " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠMAC _ ALGORITHM _ HMAC _ SHA 2 5 6 Ġ= Ġ" H mac SHA 2 5 6 " ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠIS _ COMPAT _ MODE _ KEY _ ALIAS _ NAME Ġ= Ġ" data _ in _ compat " ĊĊĠĠĠĠĠĠĠ Ġ@ Throws ( NoSuch AlgorithmException :: class , ĠUnsupported EncodingException :: class ) ĊĠĠĠĠĠĠĠ Ġfun Ġget Has hed ( text : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdigest Ġ= ĠMessage Digest . getInstance (" SHA - 2 5 6 ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresult Ġ= Ġdigest . digest ( text . toByteArray ( charset ( DEFAULT _ CHARSET ))) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġto Hex ( result ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġinternal Ġfun Ġto Hex ( data : ĠByteArray ): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsb Ġ= ĠStringBuilder () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( b Ġin Ġdata ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsb . append ( String . format ("% 0 2 X ", Ġb )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsb . toString () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġbase 6 4 Encode ( data : ĠByteArray ?): ĠString Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBase 6 4 . encode ToString ( data , ĠBase 6 4 . NO _ WRAP ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġfun Ġbase 6 4 Decode ( text : ĠString ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠBase 6 4 . decode ( text , ĠBase 6 4 . NO _ WRAP ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }