package Ġcom . pe ters am ok hin . k br an ca Ċ Ċ import Ġio . ser u co . encoding . base 6 2 . Base 6 2 Ċ import Ġorg . bouncycastle . crypto . macs . Poly 1 3 0 5 Ċ import Ġorg . bouncycastle . crypto . params . Key Parameter Ċ import Ġorg . bouncycastle . crypto . params . Parameters With IV Ċ import Ġjava . nio . ByteBuffer Ċ import Ġjava . util . Arrays Ċ Ċ /** Ċ Ġ* ĠConstructs ĠBr an ca Ġtokens Ġfrom Ġprovided Ġpayload s Ġas Ġwell Ġas Ġvalidates Ġand Ġunpack s Ġthem . Ċ Ġ*/ Ċ class ĠBr an ca Token Factory ( secret Key : ĠByteArray ) Ġ{ ĊĠĠĠ Ġprivate Ġval Ġkey : ĠByteArray ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( secret Key . size Ġ!= Ġ 3 2 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Secret Ġkey Ġmust Ġbe Ġ 3 2 Ġbytes ") ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġthis . key Ġ= Ġsecret Key . copyOf ( secret Key . size ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGenerates Ġa ĠBr an ca Ġtoken Ġwith Ġplain Ġtext Ġas Ġthe Ġpayload Ġusing Ġthe Ġprovided Ġnonce . ĠMake Ġsure Ġthis Ġnonce Ġis Ġpl enty Ġrandom . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġsource ĠSource Ġbytes ĊĠĠĠĠ Ġ* Ġ@ param Ġnonce ĠN once ĊĠĠĠĠ Ġ* Ġ@ return ĠEn coded Ġbyte Ġarray ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġ@ Jvm Over loads ĊĠĠĠ Ġfun Ġencode ( source : ĠByteArray , Ġnonce : ĠByteArray Ġ= ĠBytes . make Random Nonce ()): ĠByteArray Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġheader Ġ= ĠByteBuffer . allocate ( 1 Ġ+ Ġ 4 Ġ+ Ġ 2 4 ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠVersion Ġ( 1 B ) Ġ*/ ĊĠĠĠĠĠĠĠ Ġheader . put ( 0 , ĠVERSION ) ĊĠĠĠĠĠĠĠ Ġheader . position ( 1 ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠTimestamp Ġ( 4 B ) Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġtimestamp Ġ= ĠTime . make Timestamp () ĊĠĠĠĠĠĠĠ Ġheader . put ( timestamp , Ġ 0 , Ġtimestamp . size ) ĊĠĠĠĠĠĠĠ Ġheader . position ( 5 ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠN once Ġ( 2 4 B ) Ġ*/ ĊĠĠĠĠĠĠĠ Ġheader . put ( nonce , Ġ 0 , Ġnonce . size ) ĊĠĠĠĠĠĠĠ Ġheader . position ( 2 9 ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠC iph ertext Ġ(* B ) Ġ*/ ĊĠĠĠĠĠĠĠ Ġval Ġcipher And Tag Ġ= Ġencrypt ( header . array (), Ġsource , Ġnonce ) ĊĠĠĠĠĠĠĠ Ġval Ġheader And Cipher Ġ= ĠBytes . addAll ( header . array (), Ġcipher And Tag ) ĊĊĠĠĠĠĠĠĠ Ġreturn ĠBytes . base 6 2 Encode ( header And Cipher ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġencrypt ( header : ĠByteArray , Ġplaintext : ĠByteArray , Ġnonce : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcp Ġ= ĠKey Parameter ( key ) ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠParameters With IV ( cp , Ġnonce ) ĊĠĠĠĠĠĠĠ Ġval Ġengine Ġ= ĠX Ch a Ch a 2 0 Engine () ĊĠĠĠĠĠĠĠ Ġengine . init ( true , Ġparams ) ĊĠĠĠĠĠĠĠ Ġval Ġencrypted Ġ= ĠByteArray ( plaintext . size Ġ+ ĠTAG _ LENGTH ) ĊĠĠĠĠĠĠĠ Ġengine . process Bytes ( plaintext , Ġ 0 , Ġplaintext . size , Ġencrypted , Ġ 0 ) ĊĊĠĠĠĠĠĠĠ Ġ/* ĠGenerate ĠPoly 1 3 5 0 9 Ġand Ġappend Ġto Ġcipher Ġ*/ ĊĠĠĠĠĠĠĠ Ġwith ( Poly 1 3 0 5 ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit ( cp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate ( header , Ġ 0 , Ġheader . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Final ( encrypted , Ġplaintext . size ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġencrypted ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdecrypt ( header : ĠByteArray , Ġplaintext : ĠByteArray , Ġnonce : ĠByteArray , Ġmac : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcp Ġ= ĠKey Parameter ( key ) ĊĠĠĠĠĠĠĠ Ġval Ġparams Ġ= ĠParameters With IV ( cp , Ġnonce ) ĊĊĠĠĠĠĠĠĠ Ġval Ġheader Mac Ġ= ĠByteArray ( 1 6 ) ĊĊĠĠĠĠĠĠĠ Ġwith ( Poly 1 3 0 5 ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġinit ( cp ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate ( header , Ġ 0 , Ġheader . size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Final ( header Mac , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ(! Arrays . equals ( header Mac , Ġmac )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Auth Ġfailed ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġengine Ġ= ĠX Ch a Ch a 2 0 Engine () ĊĠĠĠĠĠĠĠ Ġengine . init ( false , Ġparams ) ĊĠĠĠĠĠĠĠ Ġval Ġdecrypted Ġ= ĠByteArray ( plaintext . size ) ĊĠĠĠĠĠĠĠ Ġengine . process Bytes ( plaintext , Ġ 0 , Ġplaintext . size , Ġdecrypted , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġreturn Ġdecrypted ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGiven Ġa ĠBr an ca Ġtoken Ġin Ġthe Ġcorrect Ġformat Ġthis Ġmethod Ġreturns Ġthe Ġplaintext ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ@ param Ġtoken Ġvalid ĠBr an ca Ġtoken ĊĠĠĠĠ Ġ* Ġ@ return Ġdecoded Ġbyte Ġarray ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġfun Ġdecode ( token : ĠByteArray ): ĠByteArray Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġdecoded Ġ= ĠBase 6 2 . create Instance (). decode ( token ) ĊĊĠĠĠĠĠĠĠ Ġif Ġ( decoded [ 0 ] Ġ!= ĠVERSION ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠIllegalArgumentException (" Not Ġa Ġvalid Ġversion ") ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġcy pher Text Ġ= ĠArrays . copyOf Range ( decoded , ĠHEADER _ LENGTH , Ġdecoded . size ) ĊĠĠĠĠĠĠĠ Ġval Ġnonce Ġ= ĠArrays . copyOf Range ( decoded , Ġ 5 , Ġdecoded . size Ġ- Ġcy pher Text . size ) ĊĠĠĠĠĠĠĠ Ġval Ġtag Ġ= ĠArrays . copyOf Range ( decoded , Ġdecoded . size Ġ- ĠTAG _ LENGTH , Ġdecoded . size ) ĊĠĠĠĠĠĠĠ Ġval Ġheader Ġ= ĠArrays . copyOf Range ( decoded , Ġ 0 , ĠHEADER _ LENGTH ) ĊĠĠĠĠĠĠĠ Ġval Ġdecrypted Ġ= Ġdecrypt ( header , Ġcy pher Text , Ġnonce , Ġtag ) ĊĠĠĠĠĠĠĠ Ġreturn ĠArrays . copyOf Range ( de crypted , Ġ 0 , Ġdecrypted . size Ġ- Ġ 1 6 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠVERSION Ġ= Ġ 0 xBA . to Byte () Ġ// Ġmagic Ġbr an ca Ġbyte ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠTAG _ LENGTH Ġ= Ġ 1 6 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠHEADER _ LENGTH Ġ= Ġ 2 9 ĊĠĠĠ Ġ} Ċ }