package Ġcom . radix d lt . client . application . identity Ċ Ċ import Ġcom . google . gson . Gson Ċ import Ġcom . google . gson . Gson Builder Ċ import Ġcom . google . gson . stream . Json Reader Ċ import Ġcom . radix d lt . client . application . identity . model . Cipher params Ċ import Ġcom . radix d lt . client . application . identity . model . Crypto Ċ import Ġcom . radix d lt . client . application . identity . model . Ke yst ore Ċ import Ġcom . radix d lt . client . application . identity . model . P bk df params Ċ import Ġcom . radix d lt . client . core . atoms . Rad ix Hash Ċ import Ġcom . radix d lt . client . core . crypto . EC KeyPair Ċ import Ġcom . radix d lt . client . core . crypto . EC KeyPair Generator Ċ import Ġcom . radix d lt . client . core . crypto . Linux Secure Random Ċ import Ġcom . radix d lt . client . core . crypto . Mac Mismatch Exception Ċ import Ġcom . radix d lt . client . core . util . Android Util Ċ import Ġok io . ByteString Ċ import Ġorg . bouncycastle . j ce . provider . Bo unc y Castle Provider Ċ import Ġjava . io . IOException Ċ import Ġjava . io . Reader Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . nio . charset . StandardCharsets Ċ import Ġjava . security . General Security Exception Ċ import Ġjava . security . NoSuch AlgorithmException Ċ import Ġjava . security . Secure Random Ċ import Ġjava . security . Security Ċ import Ġjava . security . spec . Invalid KeySpec Exception Ċ import Ġjava . util . Arrays Ċ import Ġjavax . crypto . Cipher Ċ import Ġjavax . crypto . SecretKey Ċ import Ġjavax . crypto . SecretKey Factory Ċ import Ġjavax . crypto . spec . Iv Parameter Spec Ċ import Ġjavax . crypto . spec . P BE KeySpec Ċ import Ġjavax . crypto . spec . SecretKey Spec Ċ Ċ object ĠPrivate Key Encrypt er Ġ{ ĊĊĠĠĠ Ġprivate Ġval Ġsecure Random : ĠSecure Random ĊĊĠĠĠ Ġprivate Ġconst Ġval ĠI TER ATIONS Ġ= Ġ 1 0 0 0 0 0 ĊĠĠĠ Ġprivate Ġconst Ġval ĠKEY _ LENGTH Ġ= Ġ 3 2 ĊĠĠĠ Ġprivate Ġconst Ġval ĠDIG EST Ġ= Ġ" sha 5 1 2 " ĊĠĠĠ Ġprivate Ġconst Ġval ĠAL G ORITHM Ġ= Ġ" aes - 2 5 6 - ctr " ĊĊĠĠĠ Ġprivate Ġval Ġsalt : ĠString ĊĠĠĠĠĠĠĠ Ġget () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsalt Ġ= ĠByteArray ( 3 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsecure Random . next Bytes ( salt ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠByte String . of (* salt ). hex () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠIn Ġorder Ġto Ġprevent Ġthe Ġpossibility Ġof Ġdevelopers Ġwho Ġmay Ġuse Ġor Ġtweak Ġthe Ġlibrary Ġfor Ġversions Ġof ĠAndroid ĊĠĠĠ Ġ// Ġlower Ġthan ĠAPI Ġ 1 7 ĠJ el ly bean Ġwhere Ġthere Ġis Ġa Ġvulnerability Ġin Ġthe Ġimplementation Ġof ĠSecure Random , Ġthe Ġbelow ĊĠĠĠ Ġ// Ġinitial isation Ġof ĠSecure Random Ġon ĠAndroid Ġfixes Ġthe Ġpotential Ġissue . ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( Android Util . is Android Runtime ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLinux Secure Random () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠEnsure Ġthe Ġlibrary Ġversion Ġof ĠBo unc y Castle Ġis Ġused Ġfor ĠAndroid ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSecurity . remove Provider ( Bo unc y Castle Provider . PROVIDER _ NAME ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSecurity . insert Provider At ( Bo unc y Castle Provider (), Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġsecure Random Ġ= ĠSecure Random () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( General Security Exception :: class ) ĊĠĠĠ Ġfun Ġcreate Encrypted PrivateKey ( password : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġec KeyPair Ġ= ĠEC KeyPair Generator . newInstance (). generate KeyPair () ĊĠĠĠĠĠĠĠ Ġval ĠprivateKey Ġ= ĠByte String . of (* ec KeyPair . get PrivateKey ()). hex () ĊĠĠĠĠĠĠĠ Ġval Ġsalt Ġ= Ġsalt . toByteArray ( StandardCharsets . UTF _ 8 ) ĊĊĠĠĠĠĠĠĠ Ġval Ġderived Key Ġ= Ġget SecretKey ( password , Ġsalt , ĠI TER ATIONS , ĠKEY _ LENGTH ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= ĠCipher . getInstance (" AES / CTR / No Padding ") ĊĠĠĠĠĠĠĠ Ġcipher . init ( Cipher . ENCRYPT _ MODE , Ġderived Key ) ĊĠĠĠĠĠĠĠ Ġval Ġiv Ġ= Ġcipher . parameters . getParameter Spec ( Iv Parameter Spec :: class . java ). iv ĊĊĠĠĠĠĠĠĠ Ġval Ġcipher Text Ġ= Ġencrypt ( cipher , ĠprivateKey ) ĊĠĠĠĠĠĠĠ Ġval Ġmac Ġ= Ġgenerate Mac ( derived Key . encoded , ĠByte String . decode Hex ( cipher Text ). toByteArray ()) ĊĊĠĠĠĠĠĠĠ Ġval Ġkeystore Ġ= Ġcreate Ke yst ore ( ec KeyPair , Ġcipher Text , Ġmac , Ġiv , Ġsalt ) ĊĊĠĠĠĠĠĠĠ Ġval Ġgson Ġ= ĠGson Builder (). set Pretty Print ing (). create () ĊĠĠĠĠĠĠĠ Ġreturn Ġgson . toJson ( keystore ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class , ĠGeneral Security Exception :: class ) ĊĠĠĠ Ġfun Ġdecrypt PrivateKey ( password : ĠString , Ġkey Reader : ĠReader ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġkeystore Ġ= Ġget Ke yst ore ( key Reader ) ĊĠĠĠĠĠĠĠ Ġval Ġsalt Ġ= Ġkeystore . crypto !!. pb k df params !!. salt . toByteArray () ĊĠĠĠĠĠĠĠ Ġval Ġiterations Ġ= Ġkeystore . crypto !!. pb k df params !!. iterations ĊĠĠĠĠĠĠĠ Ġval Ġkey Len Ġ= Ġkeystore . crypto !!. pb k df params !!. key len ĊĠĠĠĠĠĠĠ Ġval Ġiv Ġ= ĠByte String . decode Hex ( keystore . crypto ?. cipher params !!. iv ). toByteArray () ĊĠĠĠĠĠĠĠ Ġval Ġmac Ġ= ĠByte String . decode Hex ( keystore . crypto !!. mac ). toByteArray () ĊĠĠĠĠĠĠĠ Ġval Ġcipher Text Ġ= ĠByte String . decode Hex ( keystore . crypto !!. ciphertext ). toByteArray () ĊĊĠĠĠĠĠĠĠ Ġval Ġderived Key Ġ= Ġget SecretKey ( password , Ġsalt , Ġiterations , Ġkey Len ) ĊĊĠĠĠĠĠĠĠ Ġval Ġcipher Ġ= ĠCipher . getInstance (" AES / CTR / No Padding ") ĊĠĠĠĠĠĠĠ Ġcipher . init ( Cipher . DE CRYPT _ MODE , Ġderived Key , ĠI v Parameter Spec ( iv )) ĊĊĠĠĠĠĠĠĠ Ġval Ġcomputed Mac Ġ= Ġgenerate Mac ( derived Key . encoded , Ġcipher Text ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! Arrays . equals ( computed Mac , Ġmac )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠMac Mismatch Exception ( computed Mac , Ġmac ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠprivateKey Ġ= Ġdecrypt ( cipher , Ġcipher Text ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠByte String . decode Hex ( privateKey ). toByteArray () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch AlgorithmException :: class , ĠInvalid KeySpec Exception :: class ) ĊĠĠĠ Ġprivate Ġfun Ġget SecretKey ( pass Phrase : ĠString , Ġsalt : ĠByteArray , Ġiterations : ĠInt , Ġkey Length : ĠInt ): ĠSecret Key Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġfactory Ġ= ĠSecret Key Factory . getInstance (" PB K DF 2 With H mac SHA 5 1 2 ") ĊĠĠĠĠĠĠĠ Ġval Ġspec Ġ= ĠP BE KeySpec ( pass Phrase . toCharArray (), Ġsalt , Ġiterations , Ġkey Length Ġ* Ġ 8 ) ĊĠĠĠĠĠĠĠ Ġval Ġkey Ġ= Ġfactory . generate Secret ( spec ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠSecret KeySpec ( key . encoded , Ġ" AES ") ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( IOException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġget Ke yst ore ( key Reader : ĠReader ): ĠKe yst ore Ġ{ ĊĠĠĠĠĠĠĠ ĠJson Reader ( key Reader ). use Ġ{ Ġjson Reader Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠGson (). fromJson ( json Reader , ĠKe yst ore :: class . java ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcreate Ke yst ore ( ĊĠĠĠĠĠĠĠ Ġec KeyPair : ĠEC KeyPair , ĊĠĠĠĠĠĠĠ Ġcipher Text : ĠString , ĊĠĠĠĠĠĠĠ Ġmac : ĠByteArray , ĊĠĠĠĠĠĠĠ Ġiv : ĠByteArray , ĊĠĠĠĠĠĠĠ Ġsalt : ĠByteArray ĊĠĠĠ Ġ): ĠKe yst ore Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġpb k df params Ġ= ĠP bk df params (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdigest Ġ= ĠDIG EST ĊĠĠĠĠĠĠĠĠĠĠĠ Ġiterations Ġ= ĠI TER ATIONS ĊĠĠĠĠĠĠĠĠĠĠĠ Ġkey len Ġ= ĠKEY _ LENGTH ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . salt Ġ= ĠString ( salt , ĠStandard Charsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcipher params Ġ= ĠCipher params (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . iv Ġ= ĠByte String . of (* iv ). hex () ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcrypto Ġ= ĠCrypto (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcipher Ġ= ĠAL G ORITHM ĊĠĠĠĠĠĠĠĠĠĠĠ Ġciphertext Ġ= Ġcipher Text ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . mac Ġ= ĠByte String . of (* mac ). hex () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . cipher params Ġ= Ġcipher params ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . pb k df params Ġ= Ġpb k df params ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn ĠKe yst ore (). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġid Ġ= Ġec KeyPair . get UID (). toString () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthis . crypto Ġ= Ġcrypto ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( General Security Exception :: class ) ĊĠĠĠ Ġprivate Ġfun Ġencrypt ( cipher : ĠCipher , Ġencrypt : ĠString ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġbytes Ġ= Ġencrypt . toByteArray ( StandardCharsets . UTF _ 8 ) ĊĠĠĠĠĠĠĠ Ġval Ġencrypted Ġ= Ġcipher . do Final ( bytes ) ĊĠĠĠĠĠĠĠ Ġreturn ĠByte String . of (* encrypted ). hex () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( General Security Exception :: class ) ĊĠĠĠ Ġprivate Ġfun Ġdecrypt ( cipher : ĠCipher , Ġencrypted : ĠByteArray ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdecrypted Ġ= Ġcipher . do Final ( encrypted ) ĊĠĠĠĠĠĠĠ Ġreturn ĠString ( de crypted , ĠStandard Charsets . UTF _ 8 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ@ Throws ( NoSuch AlgorithmException :: class ) ĊĠĠĠ Ġprivate Ġfun Ġgenerate Mac ( derived Key : ĠByteArray , Ġcipher Text : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġresult Ġ= ĠByteArray ( derived Key . size Ġ+ Ġcipher Text . size ) ĊĠĠĠĠĠĠĠ Ġresult Ġ= ĠByteBuffer . wrap ( result ). put ( derived Key ). put ( cipher Text ). array () ĊĊĠĠĠĠĠĠĠ Ġreturn ĠRad ix Hash . of ( result ). toByteArray () ĊĠĠĠ Ġ} Ċ } Ċ