package Ġcom . dit ron ic . secure zip notes . password Ċ Ċ import Ġandroid . content . Context Ċ import Ġandroid . os . Build Ċ import Ġandroid . security . keystore . Key Gen Parameter Spec Ċ import Ġandroid . security . keystore . Key Properties Ċ import Ġandroid . util . Base 6 4 Ċ import Ġandroidx . annotation . Requires Api Ċ import Ġandroidx . bio metric . Bio metric Constants Ċ import Ġandroidx . bio metric . Bio metric Prompt Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . fragment . app . Fragment Activity Ċ import Ġtim ber . log . Tim ber Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . security . Invalid Algorithm Parameter Exception Ċ import Ġjava . security . KeyStore Ċ import Ġjava . security . NoSuch AlgorithmException Ċ import Ġjava . security . NoSuch Provider Exception Ċ import Ġjavax . crypto . Cipher Ċ import Ġjavax . crypto . Key Generator Ċ import Ġjavax . crypto . SecretKey Ċ import Ġjavax . crypto . spec . Iv Parameter Spec ĊĊ Ċ private Ġconst Ġval ĠSE C _ ALIAS Ġ= Ġ" pw _ enc _ key _ alias _ v 3 " Ċ Ċ private Ġconst Ġval ĠKEY _ STORE Ġ= Ġ" Android KeyStore " Ċ private Ġval ĠTAG Ġ= Ġ" Pw Storage " Ċ Ċ private Ġconst Ġval ĠP REF _ FILE Ġ= Ġ" pref _ private _ no _ backup " Ċ private Ġconst Ġval ĠP REF _ ENC _ PW Ġ= Ġ" pref _ enc _ pw $ SEC _ ALIAS " Ċ private Ġconst Ġval ĠP REF _ ENC _ PW _ IV Ġ= Ġ" pref _ enc _ pw _ iv $ SEC _ ALIAS " Ċ private Ġconst Ġval ĠP REF _ LOW _ API _ PW Ġ= Ġ" pref _ low _ api _ pw $ SEC _ ALIAS " Ċ Ċ @ Requires Api ( 2 3 ) Ċ private Ġval ĠBLOCK _ MODE Ġ= ĠKey Properties . BLOCK _ MODE _ CBC Ċ @ Requires Api ( 2 3 ) Ċ private Ġval ĠP ADDING Ġ= ĠKey Properties . ENCRYPT ION _ P ADDING _ PKCS 7 Ċ @ Requires Api ( 2 3 ) Ċ private Ġval ĠP W _ ENCRYPT _ ALGORITHM Ġ= Ġ" AES /$ BLOCK _ MODE /$ P ADDING " Ċ Ċ @ Requires Api ( 2 3 ) Ċ @ Throws ( NoSuch AlgorithmException :: class , ĠNoSuch Provider Exception :: class , ĠInvalid Algorithm Parameter Exception :: class ) Ċ private Ġfun Ġtry Generate Ke yst ore Key Unchecked ( user Authentication Required : ĠBoolean ): ĠSecret Key Ġ{ ĊĊĠĠĠ Ġ// ĠTry Ġto Ġgenerate Ġa Ġsymmetric Ġkey Ġwithin Ġthe ĠAndroid KeyStore . ĊĠĠĠ Ġval Ġkey Generator Ġ= ĠKey Generator . getInstance (" AES ", ĠKEY _ STORE ) ĊĠĠĠ Ġval Ġkey Gen Parameter Spec Ġ= ĠKey Gen Parameter Spec . Builder ( SEC _ ALIAS , ĠKey Properties . P URPOSE _ ENCRYPT Ġor ĠKey Properties . P URPOSE _ DE CRYPT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Block Modes ( BLOCK _ MODE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Encryption P add ings ( P ADDING ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setUser Authentication Required ( user Authentication Required ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠ Ġkey Generator . init ( key Gen Parameter Spec ) ĊĠĠĠ Ġreturn Ġkey Generator . generate Key () Ċ } Ċ Ċ @ Requires Api ( 2 3 ) Ċ fun Ġtry Generate KeyStore Key () Ġ: ĠSecret Key ? Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Generate Ke yst ore Key Unchecked ( true ) ĊĠĠĠ Ġ} Ġcatch Ġ( e 1 : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . w ( e 1 ) ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtry Generate Ke yst ore Key Unchecked ( false ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e 2 : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e ( e 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ private Ġval ĠgetKey Store Key : ĠSecret Key ? ĊĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġks Ġ= ĠKey Store . getInstance ( KEY _ STORE ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġks . load ( null ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġks . getKey ( SEC _ ALIAS , Ġnull ) Ġas ĠSecret Key ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . w ( e ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnull ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ private Ġfun Ġget Enc Pw ( cx : ĠContext ): ĠByteArray ? Ġ{ ĊĠĠĠ Ġval Ġprefs Ġ= Ġcx . get SharedPreferences ( PRE F _ FILE , ĠContext . MODE _ PRIVATE ) ĊĠĠĠ Ġif Ġ(! prefs . contains ( PRE F _ ENC _ PW )) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġenc Pw Ġ= Ġprefs . getString ( PRE F _ ENC _ PW , Ġ"") ĊĠĠĠ Ġreturn ĠBase 6 4 . decode ( enc Pw , ĠBase 6 4 . NO _ WRAP ) Ċ } Ċ Ċ private Ġfun Ġget Enc Pw Iv ( cx : ĠContext ): ĠByteArray ? Ġ{ ĊĠĠĠ Ġval Ġprefs Ġ= Ġcx . get SharedPreferences ( PRE F _ FILE , ĠContext . MODE _ PRIVATE ) ĊĠĠĠ Ġif Ġ(! prefs . contains ( PRE F _ ENC _ PW _ IV )) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġenc Pw Iv Ġ= Ġprefs . getString ( PRE F _ ENC _ PW _ IV , Ġ"") ĊĠĠĠ Ġreturn ĠBase 6 4 . decode ( enc Pw Iv , ĠBase 6 4 . NO _ WRAP ) Ċ } Ċ Ċ fun Ġfinalize Pw Encryption ( cx : ĠContext , Ġpassword : ĠString , Ġun locked Cipher : ĠCipher ?): ĠBoolean Ġ{ ĊĠĠĠ Ġif Ġ( unlocked Cipher Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠShould Ġnever Ġhappen ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġenc Pw Iv Ġ= Ġun locked Cipher . iv ĊĠĠĠ Ġval Ġenc Pw : ĠByteArray ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġenc Pw Ġ= Ġun locked Cipher . do Final ( password . toByteArray ( StandardCharsets . UTF _ 8 )) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . e ( e ) ĊĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠSave Ġthe Ġencrypted Ġpassword ĊĠĠĠ Ġval Ġprefs Ġ= Ġcx . get SharedPreferences ( PRE F _ FILE , ĠContext . MODE _ PRIVATE ) ĊĠĠĠ Ġval Ġedit Ġ= Ġprefs . edit () ĊĠĠĠ Ġedit . putString ( PRE F _ ENC _ PW , ĠBase 6 4 . encode ToString ( enc Pw , ĠBase 6 4 . NO _ WRAP )) ĊĠĠĠ Ġedit . putString ( PRE F _ ENC _ PW _ IV , ĠBase 6 4 . encode ToString ( enc Pw Iv , ĠBase 6 4 . NO _ WRAP )) ĊĠĠĠ Ġedit . apply () ĊĠĠĠ Ġreturn Ġtrue Ċ } Ċ Ċ @ Requires Api ( 2 3 ) Ċ fun Ġinit Encrypt Cipher ( secret Key : ĠSecret Key ) Ġ: ĠCipher ? Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher To Unlock Ġ= ĠCipher . getInstance ( PW _ ENCRYPT _ ALGORITHM ) ĊĠĠĠĠĠĠĠ Ġcipher To Unlock . init ( Cipher . ENCRYPT _ MODE , Ġsecret Key ) ĊĠĠĠĠĠĠĠ Ġreturn Ġcipher To Unlock ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . e ( e ) ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ @ Requires Api ( 2 3 ) Ċ fun Ġinit Decrypt Cipher ( ac : ĠFragment Activity ) Ġ: ĠCipher ? Ġ{ ĊĠĠĠ Ġval Ġsecret Key Ġ= ĠgetKey Store Key ĊĠĠĠ Ġval Ġpw Enc Iv Ġ= Ġget Enc Pw Iv ( ac ) ĊĠĠĠ Ġif Ġ( secret Key Ġ== Ġnull Ġ|| Ġpw Enc Iv Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull Ġ// ĠPassword Ġmaterial Ġnot Ġavailable . ĊĠĠĠ Ġ} ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcipher To Unlock Ġ= ĠCipher . getInstance ( PW _ ENCRYPT _ ALGORITHM ) ĊĠĠĠĠĠĠĠ Ġcipher To Unlock . init ( Cipher . DE CRYPT _ MODE , Ġsecret Key , ĠI v Parameter Spec ( pw Enc Iv )) ĊĠĠĠĠĠĠĠ Ġreturn Ġcipher To Unlock ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . e ( e ) ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġdecrypt Password ( cx : ĠContext , Ġcipher : ĠCipher ): ĠString ? Ġ{ ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġenc Pw Ġ= Ġget Enc Pw ( cx ) Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġreturn ĠString ( cipher . do Final ( enc Pw ), ĠStandard Charsets . UTF _ 8 ) ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠ ĠTim ber . e ( e ) ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} Ċ } Ċ Ċ fun Ġclear Private Prefs ( ac : ĠFragment Activity ) Ġ{ ĊĠĠĠ Ġac . get SharedPreferences ( PRE F _ FILE , ĠContext . MODE _ PRIVATE ). edit (). clear (). apply () Ċ } ĊĊ Ċ fun Ġsave Low API Pw ( pw : ĠString , Ġac : ĠFragment Activity ) Ġ{ ĊĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= Ġ 2 3 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthrow ĠRuntimeException (" Do Ġnot Ġstore Ġpasswords Ġin Ġplaintext ") ĊĠĠĠ Ġ} ĊĠĠĠ Ġ// ĠLow ĠAPI Ġlevels Ġdo Ġnot Ġsupport ĠAndroid Ke yst ore Ġwith Ġsymmetric Ġencryption . ĊĠĠĠ Ġ// ĠOr Ġthey Ġmight Ġeven Ġnot Ġsupport ĠAndroid Ke yst ore Ġat Ġall . ĊĠĠĠ Ġval Ġprefs Ġ= Ġac . get SharedPreferences ( PRE F _ FILE , ĠContext . MODE _ PRIVATE ) ĊĠĠĠ Ġprefs . edit (). putString ( PRE F _ LOW _ API _ PW , Ġpw ). apply () Ċ } Ċ Ċ fun Ġget Old Api Pw ( cx : ĠContext ): ĠString ? Ġ{ ĊĠĠĠ Ġif Ġ( Build . VERSION . SDK _ INT Ġ>= Ġ 2 3 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĠĠĠ Ġval Ġprefs Ġ= Ġcx . get SharedPreferences ( PRE F _ FILE , ĠContext . MODE _ PRIVATE ) ĊĠĠĠ Ġreturn Ġprefs . getString ( PRE F _ LOW _ API _ PW , Ġnull ) Ċ } Ċ Ċ @ Requires Api ( 2 3 ) Ċ internal Ġfun Ġunlock Cipher With Bio metric Prompt ( ac : ĠFragment Activity , Ġcipher To Unlock : ĠCipher , Ġauth Callback : Ġ( Cipher ?) Ġ-> ĠUnit ) Ġ{ ĊĊĠĠĠ Ġ// ĠHere Ġwe Ġshould Ġuse ĠBio metric Prompt . Builder . set Device Credential Allowed ( true ). ĊĠĠĠ Ġ// ĠHowever , Ġset Device Credential Allowed Ġis Ġnot Ġyet Ġavailable Ġwithin Ġthe Ġcompat Ġlib . ĊĊĠĠĠ Ġval Ġexecutor Ġ= ĠContext Compat . get Main Executor ( ac ) ĊĠĠĠ Ġval Ġbio metric Prompt Ġ= ĠBio metric Prompt ( ac , Ġexecutor , Ġobject Ġ: ĠBio metric Prompt . Authentication Callback () Ġ{ ĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Authentication Error ( errorCode : ĠInt , Ġerr String : ĠCharSequence ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Authentication Error ( errorCode , Ġerr String ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . w (" on Authentication Error Ġ$ errorCode : Ġ$ err String ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCheck Ġwhether Ġthe Ġuser Ġdeli ber ately Ġaborted Ġthe Ġoperation . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( errorCode Ġ!= ĠBio metric Constants . ERROR _ USER _ C ANCE LED Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠerrorCode Ġ!= ĠBio metric Constants . ERROR _ C ANCE LED Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠerrorCode Ġ!= ĠBio metric Constants . ERROR _ NEGATIVE _ BUTTON ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠTry Ġto Ġuse Ġthe Ġoriginal Ġcipher Ġin Ġcase Ġof Ġauthentication Ġerrors . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġshould Ġwork Ġin Ġcase Ġof Ġdevices Ġthat Ġdo Ġnot Ġhave Ġany Ġfingerprint Ġregistered . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġauth Callback ( cipher To Unlock ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Authentication Succeeded ( result : ĠBio metric Prompt . Authentication Result ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Authentication Succeeded ( result ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcrypto Object Ġ= Ġresult . crypto Object ĊĠĠĠĠĠĠĠĠĠĠĠ Ġauth Callback ( crypto Object ?. cipher ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġon Authentication Failed () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . on Authentication Failed () ĊĠĠĠĠĠĠĠĠĠĠĠ ĠTim ber . e (" on Authentication Failed ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ}) ĊĠĠĠ Ġval Ġprompt Info Ġ= ĠBio metric Prompt . Prompt Info . Builder () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. setTitle (" Unlock ĠEncryption ĠKey ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . set Subtitle (" Subtitle ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// . setDescription (" Description ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Negative ButtonText ( ac . getString ( android . R . string . cancel )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠ Ġval Ġcrypto Object Ġ= ĠBio metric Prompt . Crypto Object ( cipher To Unlock ) ĊĠĠĠ Ġbio metric Prompt . authenticate ( prompt Info , Ġcrypto Object ) Ċ } Ċ