JCA/JCE • 0J Java Crypto Architecture / Java Crypto Extensions Dušan Klinec deadcode.me C RA C S Centre for Research on Cryptography and Security www.fi.mu n i.cz/crocs CRvvCS Provider architecture Application ("MD5") MDS McssagoDigeS irorn PrgyiderB Provider Framework Message SHrt-1 S H A - 2 5 B Message Digest M K SHA-513. Dlgasl MD5 S H A - 2 S 6 , PrnuidiwA Providern Prnu idrrfl www.fi.muni.cz/crocs Provider architecture Application MB35agoDipes_3aUriSarico MDS MessngeDigeS (J MD5") 1rom FrrjyiderB MessageDigest. getlnstance("MD5"); Provider Framework Message SHrt-1 S H A - 2 5 B Message M K SHA-513. Dlgasl MD5 S H A - 2 S 6 , PrnuidiwA Providern Prnu idrrfl Provider architecture Application MessageDigest. getlnstance("MD5" "ProviderC"); fron ProviderC PrcuriridrA P r o v i d e r n Prcmidc:rC JCA • Java.security.* • SecureRandom - PRNG • MessageDigest - SHA256, MD5, • Signature - RSA, DSA • KeyStore-PKCS12 • KeyPairGenerator, KeyFactory, CertificateFactory, CRvvCS JCE • iavax.crypto.* • Cipher-AES, RSA, EIGamal, RC4, Salsa20 • Mac - HMACWithSHA256 • KeyGenerator www.fi.muni.cz/crocs Provider architecture • Implementation independence • Implementation interoperability • Algorithm extensibility CRvvCS Bouncy Castle www.fi.muni.cz/crocs CRvvCS Bouncy Castle Application ("MD5") MDS McssagoDigeS Provider Framework Message SHrt-1 S H A - 2 5 B Message Digest M K SHA-513. Dlgasl MD5 S H A - 2 S 6 , BouncyCastle PrnuidrrA Providern Prnu idrrf: www.fi.muni.cz/crocs CRvvCS Bouncy Castle • Implements a LOT OF ciphers, cipher suites, algorithms, modes, ASN.1, PEM, Certs, ... • Origin: Australian, former advantage (crypto regulations) • Android www.fi.muni.cz/crocs CRvvCS Provider architecture MessageDigest • JEü * Delegate (m) ? MessageDigest(Sinng) getlnstance(String): MessageDfgest j")l» getlnstance(String, String): MessageDigest j^'li getlnstancefString, Provider): MessageDigest getProviderQ: Provider (55)11 up date (byte): void (55)11 update(byte[]< int, int>- void (55)1» update(byte[]}: void !§)1» update(Byteßuffer): void (55) 1» digestO: byte[] (55)1» digest(byte[], int, int): int m li digest(byte[]}: byte[] (55)11 toStrings String TObjecv f 1) isEqual(byte[], byte[]): boolean (55) 1» resetO: void ?üyl» getAlgorithmQ: String ÜÜJ)!» getDigestLengthO: int Engine classes • getlnstance() • update() • digest() • reset() www.fi.muni.cz/crocs C R C v C S Provider architecture - Engine classes © b Cipher Jp:'b getlnstance(String): Cipher Jjj) b getlnstancefString, String): Cipher 5p;b getlnstance(String, Provider): Cipher ?n)b getProviderQ: Provider ?n)b getAlgorithmQ: String ?n)b getBfockSizeO: in* ^ b getOutputSize(int): int ^" ti getlVQ: byte[] getPararnetersQ: AfgorithmParameters getExemptionMechanismQ: LxemptionMechanism ® b % ' b fob Mint, Key): void ' it(int, Key, SecureRandom): vofd tflnt, Key, AlgorithmPararneterSpec): void t(int, Key, AlgorithmPararneterSpec, SecureRandom): vt" t(int, Key, AfgorithmParameters): void tfint, Key, AfgorithmParameters, SecureRandom): void t(fnt, Certificate): void '[(int, Certificate, SecureRandom): void b update(byte[]): byte[] V b update(byte[], int, int): byte[] tfeb update(byte[], int, int, byte[]): int getlnstanceQ init() update() doFinal() www.fi.muni.cz/crocs CRvvCS Provider architecture - Spi skeleton public abstract class CipherSpi { public CiphcrSpi{) { ] } protected abstract void engineSetModefString varl) throws NoSuthAlgorithiriELxception; protected abstract void engineSetPadding{5tring varl) throws NoSuchPaddingException; protected abstract int cngineGetBlockSizeO; protected abstract int engineGetOutputSize(int v a r l ) ; protected abstract byte[] enqineGetlW); protected abstract AIgorithmParameters engine&etParameters(); protected abstract void enginelnitdnt v a r l . Key var2, SecureRandom var3) throws Inval protected abstract void enginelnit{int v a r l , Key var2, AlgorithiriParameterSpec var3, 5c protected abstract void cntjinclnitdnt v a r l , Key var2, AlqorithiriParameters var3, Secur www.fi.muni.cz/crocs CRvvCS Provider architecture - Spi skeleton X. H .— . ^ X ^ ^ J - . LT L~~ 1. Choose Subclass of CipherSpi (207 classes found)r 0AESCipher ( c o n . s u n . c r y p t o . p r o v i d e r ) ^ AESWrapCipher {COITI.sun-crypto,provider) ^= ARCTOURCipher [-coin. sun. crypto, provider) AsymmetricBlockCipher (org.bouncycastle-pqc-jcajce-provider.util) ® AsymmetricHybridCipher {org.bouncycastle.pqc-jcajce-provider-util) JE) Base in ARC4 (org-bouncycastle-jcajce-provider,symmetric) Base in ChaCha [org-bouncycastle-:ica:: ce-provider.symmetric) ^= Base in Grainl28 {org.bouncycastle-jcajce-provider-symmetric) ifc) Base in Grainvl {org-bouncycastle-jcajce-provider-symmetric) Base in HC12S (org.bouncycastle.jcajce.provider-symmetric) ©Base in HC256 {org-bouncycastle-jcajce-provider-symmetric) ^= Base in Salsa2D {org-bouncycastle-jcajce.provider-symmetric) JE) Base in VMPC {org-bouncycastle.jcajce-provider-symmetric) jE) Base in VMPCKSA3 {org-bouncycastle.jcajce-provider-symmetric) JE) Base in XSalsa20 {org-bouncycastle-jcajce-provider-symmetric) BascBlockCipher (com-eniqmabridqe.provider) •—• r—: :—r~ r i — r 1—:— n : n ~ • — : =r— C www.fi.muni.cz/crocs void cncryptBloc^íbyte[] v a r l , i n t var2, byte[] var3, i n t var4) { byte var5 = 6' i n t varl0000 = varl[var2-H-] « 24 | (varl[var2-H*] & 255) « 16 | (varl[var2-H-] & i n t varJ _3 = var5 y !• i n t var6 = varl&&&& A t h i s . K [ v a r 5 ] ; i n t var7 = Warl[var2-H-] « 24 | (varl[var2-M-] & 255) « 16 | (varl[var2-H-] & 255! i n t var3 = (varl[var2-H*] « 24 | {varl[var2-H-] & 255) « 16 | (varl[var2-H-] & 255! i n t var9; i n t varle j i n t v a r ! 2 ; for(var9 = (varl[var2-H-| « 24 | (varl[var2-r-K] & 255) « 16 | (varl[var2-t-t ] & 255'. varlG = Tl[var6 » > 24] A T2[var7 » > 16 i 255] A T3[var3 > » 8 & 255] * T4[VE i n t v a ř i l = Tl[var7 » > 24] A T2[var8 > » 16 & 255] A T3[var9 > » 3 Ä 255] varl2 = Tl[var8 » > 24] A T2[var9 » > 16 & 255] * T3[var6 > » 8 & 255] * T4[VE var9 = Tl[var9 24] * T2[var6 w 16 & 255] A T3[var7 » > 8 & 255] A T4[vai var6 = varl&; var7 = v a ř i l ; varlB = this.K[varl3++]; var3[var4++] = (byte)(S[var6 » > 24] A varlO » > 24) i var3[var4++] = {byte)(S[var7 » > 16 & 255] * var!0 » > 16); var3[var4++] = [byte)(S[var3 » > 3 & 255] * var!0 » > 8 ) ; var3[var4++] = (byte)(S[var& & 255] * varlfl); varle = this,K[uarl3++]; var3[var4n] = [byte)(S[var7 » > 24] * varlG > » 24); var3[var4++] = [byte)(S[var3 » > 16 & 255] A varl0 » > 16); var3[var4++] = [byte)(S[var9 » > 3 & 255] * varlG » > 3 ) ; var3[var4++] = (byte)(S[var6 & 255] * varlG); CRvvCS Strong cryptography • Limits the strength of your crypto • the size of the Key • AES-256, RSA-2048 not available by default • Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files www.fi.muni.cz/crocs CRvvCS Sign In/Register Help Country v Communities v lama,., v Iwantto,., v I S e a r c h Products Solutions Downloads Store Support Training Partner Oracle Technology Network JavaSE > Downloads Java S E Java EE Java M E Java S E Support Java S E Advanced & Suite Java Embedded Java DE Web Tier Java Card Java TV New Ho Java Connrn unity Java Magazine Overview Downloads Documentation Community Technologies Training Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files You must accept the Oracle Binary Code License Agreement for the Java SE Platform Products to download this software. Accept License Agreement Q Decline License Agreement Product / File Description File Size Download Java Cryptography Extension (JCE) Unlimited Strength Ju risdi eti on Pol icy Fi les 7 7.3 K U nli mitedJC EPoli cyJ • K7.zip www.fi.muni.cz/crocs CRvvCS Strong cryptography Algorithm Key size DES DESede RC2 RC4 128 RSA * (KeyPairGenerator 1024) other www.fi.muni.cz/crocs CRvvCS Download NetBeans project goo.gl/ntSDHP Case sensitive www.fi.muni.cz/crocs CRvvCS Pis open NetBeans www.fi.muni.cz/crocs CRvvCS Pis open M NetBeans • Edit View Navigate Source • •• t n s ] H New Project... S New File... E N Projects Q Files Open Project... Open Recent Project Close Project [PV181JCA) www.fi.muni.cz/crocs CRvvCS Getting started Ta sk 0 0AE SStre n gth j ava Q p v l 6 1 jca.tasks rig. TaskQ15ecureRandorri Java rfg. TaskOZMessageDigestjava rf& Task03AE5java rfg. Task045ignatureJava www.fi.muni.cz/crocs CRvvCS Cipher - import missing S y s t e m * o u t * p r i n t l n j " M a x i m u m a l l o w e d AES key s i z e i s " + getMsxAUowedKeyLengtfri " A E S " ) ); www.fi.muni.cz/crocs CRvvCS Cipher - import missing S y s t e m * o u t * p r i n t l n j " M a x i m u m a l l o w e d AES key s i z e i s " + getMsxAUowedKeyLengtfri " A E S " ) ); www.fi.muni.cz/crocs CRvvCS Lighbulb helps S y s t e m * o u t . p r i n t l n ( " M a x i m u m a l l o w e d AES key s i z e i s getMaxAllowedKeyLengthi " A E S " ) ) ; • i ? Add import for javax.crypto.Cipher 9 Create class "Cipher" in package pvlfiljca/tasks (Source Packages) 9 Create class "Cipher" in pvlBl.jca.tasks.TaskOOAESStrength 9 Create field "Cipher11 in pvlfil.jca.tasks.TaskGOAESStrength 9 Flip operands of '+' (may alter semantics} www.fi.muni.cz/crocs CRvvCS Getting started CTRL+SHIFT+I S y s t e m * o u t . p r i n t l n ( " M a x i m u m a l l o w e d AES key s i z e i s getMaxAllowedKeyLengthi " A E S " ) ) ; • i ? Add import for javax.crypto.Cipher 9 Create class "Cipher" in package pvlfiljca/tasks (Source Packages) 9 Create class "Cipher" in pvlBl.jca.tasks.TaskOOAESStrength 9 Create field "Cipher11 in pvlfil.jca.tasks.TaskGOAESStrength 9 Flip operands of '+' (may alter semantics} www.fi.muni.cz/crocs CRvvCS Problem again S y s t e m * o u t * p r i n t l n f " M a x i m u m a l l o w e d AES key s i z e i s " + C i p h e r * getMsxAIIowedKeyLength ] • www.fi.muni.cz/crocs CRvvCS Problem again p u b l i c c l a s s TaskOBAESStrength { p u b l i c s t a t i c v o i d m a i n { S t r i n g a r g s M ) t h r ^ w s ^ o S u c h A ^ o j r ^ h f i ^ www.fi.muni.cz/crocs CRvvCS The web www.fi.muni.cz/crocs CRvvCS Pis open - the guide goo.gl/4Ztqen Case sensitive www.fi.muni.cz/crocs TaskOI - SecureRandom • SecureRandom rnd = new SecureRandom() • rnd.nextDouble() • rnd.nextByte() • rnd SecureRandom - solution • SecureRandom rnd = new SecureRandom(); • rnd.nextBytes(buffer); • System.out.println(Globals.bytesToHex(buffer)); CRvvCS Task02 - MessageDigest • MessageDigest md5 = MessageDigest.getlnstance("MD5"); www.fi.muni.cz/crocs MessageDigest • MessageDigest md5 = MessageDigest.getlnstance("MD5"); • md5.update(inputBuffer, 0, bytesRead); • md5.update(inputBuffer, 0, bytesRead); • md5.update(inputBuffer, 0, bytesRead); • byte[] md5hash = md5.digest() C R w C S MessageDigest - incremental API md5.update(data) MD5 md5.digest() md5.update(data) MD5 md5.digest() md5.update(data) MD5 md5.digest() md5.update(data) MD5 md5.digest() md5.update(data) md5.update(data) md5.update(data) byte[] hash www.fi.muni.cz/crocs CRvvCS www.fi.muni.cz/crocs CRvvCS MessageDigest - solution p u b l i c s t a t i c v o i d ma±n[String a r g s [ ] ) throws E x c e p t i o n { InputStream i s 0 1 = new J R U " r t t p : / / w w w . f i * m u n i . c z / * - x k l i n e c / j a v a / f i l e _ a * b i n " byte[] b u f f e r = new b y t e [ 1 0 2 4 ] ; MessageDigest md5 = M e s s a g e D i g e s t * g e t l n s t a n c e { " M D 5 " ) ; MessageDigest sha - MessageDigest*getInstance{"S\iA-25b"); i n t bytesRead = - 1 ; while {(bytesRead = i s 0 1 * r e a d ( b u f f e r ) ) >= 0 H md5*update!buffer, 0, bytesRead); s h a - u p d a t e ! b u f f e r , 0, bytesRead); S y s t e m * o u t . p r i n t i n g G l o b a I s * b y t e s T o H e x ( m d 5 * d i g e s t { ) , f a l s e ) ) ; S y s t e m * o u t . p r i n t i n g G l o b a I s * b y t e s T o H e x { s h a * d i g e s t { ) , f a l s e ) ) ; www.fi.muni.cz/crocs CRvvCS Task03 - Cipher • getl nstance("algorithm/mode/padding'); • Default mode: ECB • Default padding: PKCS5 2 bytes $ 5 e 5 www.fi.muni.cz/crocs CRvvCS Cipher www.fi.muni.cz/crocs CRvvCS Cipher • init(mode, key, algorithmParameterSpec) • Cipher. DECRYPT_MODE • new SecretKevSpec(aesKev, "AES") • new IvParameterSpec(iv) www.fi.muni.cz/crocs CRvvCS Cipher - Key vs KeySpec • Key - opaque key used in engine • getAlgoritmO, getEncoded() • KeySpec - key specification, transport & storage • getPQ, getQ(), getNQ www.fi.muni.cz/crocs CRvvCS Cipher - Key vs KeySpec • SecretKeySpec = Spec & Key in the same time www.fi.muni.cz/crocs CRvvCS Cipher - Key vs KeySpec public class RSAPrivateCrtKeySpcc extends RSAPrivateKeySpec { private final Diglnteger publicExponent; private final Diglnteger primeP" private final Diglnteger primet}' private final Diglnteger primeExponentP; private final Diglnteger primeEstponentt}; private final Diglnteger crtCoefficient; www.fi.muni.cz/crocs Cipher - Key vs KeySpec • Why separated? CRvvCS Cipher - Key vs KeySpec • Why separated? Cipher.init(Cipher.DECRYPT_MODE, key) www.fi.muni.cz/crocs CRvvCS Cipher - Key vs KeySpec • Why separated? Cipher.init(Cipher.DECRYPT_MODE, key) Handle=0x123330 www.fi.muni.cz/crocs CRvvCS Cipher - Key vs KeySpec • Why separated? Cipher.init(Cipher.DECRYPT_MODE, key) Cloud encryption HSM Handle=0x123330, endpoint=https://... www.fi.muni.cz/crocs CRvvCS Cipher - Key materials • String vs. char[] • String is immutable, cannot zero out • Zero-out mutable byte[] after use to prevent key leakage to swap files (or Heartblead) www.fi.muni.cz/crocs CRvvCS Cipher - Key materials • GC deallocates but does not zero-out - key still there • Modern GC can copy, reorder mem (heap defrag), unable to properly delete keys from memory nowadays (Java does not specify behaviour, can differ). www.fi.muni.cz/crocs CRvvCS Cipher - Solution b y t e [ ] key = DatatypeConverter*parseflase64flinary{ "AAAAAAAAAAAAAAAAAAAAAA=="); b y t e [ ] i v = DatatypeConverter*parseSasee4Siflary{ "AAAAAAAAAAAAAAAAAAAAAA-"); b y t e [ ] c i p h e r t e x t = DatatypeConverter*pars"efiase64Sinary{ , , 6\/MSY9xFduwNsiyn8mGZdLG6/NXb3ziw81MBSf aKozs="); Cipher aes = Cipher* gfetl/istaricer'AES/CBC/PKCSSPadding"); Key aesKey = new SecretKeySpec{key, "AES"); aes* i n i t { Cipher m DECRYPTJ^fGDE^ aesKey, new IvParameterSpec{ i v ) ) ; byte[] p l a i n t e x t = a e s * d o F i n a U c i p h e r t e x t ) ; S y s t e m * o u t * p r i n t I n { G l o b a I s * b y t e s T o H e x ( p l a i n t e x t , f a l s e ] 5 ; System*out*printIn{new S t r i n g { p l a i n t e x t ) ) ; www.fi.muni.cz/crocs CRvvCS Key Factories • KeySpec -> Key • Key -> KeySpec • KeyFactory - asymetrie keys • SecretKeyFactory - symmetric keys www.fi.muni.cz/crocs CRvvCS Key generators • KeyGenerator - symmetric • generateSecret() -> SecretKey • KeyPairGenerator - asymmetric • generateKeyPairQ -> KeyPair www.fi.muni.cz/crocs CRvvCS Certificate Builder • X509V3CertificateGenerator • goo.gl/l9WLUD www.fi.muni.cz/crocs Diffie Hellman • KeyPairGenerator • KeyAgreement • goo.gl/Lus40Y CRvvCS Thank you for your attention! Questions p www.fi.muni.cz/crocs CRvvCS References / resources • TBD www.fi.muni.cz/crocs