Udemy: Hands-On Cryptography with Java

Russell Bateman
August 2022

Erik Costlow, author and presenter.

This whole presentation gravitates toward the development of Java cryptological code instead of what I needed which was a detailed account of keys, certificates, Java key- and trust stores, openssl, keytool and what's inside. This is not unappreciated, but it's not primarily what I needed right now. It's just that it was the only course I could find that even touched upon Java key- and trust stores, but it did not really even mention the trust store let alone its relationship with the keystore. And, you have to buy before you can learn at the detailed level what's in a course.

Hence, I have added in here emerging notes in the appendices about what I really needed to learn instead of or in addition to what was taught.

Table of contents

Course sections
1. Cryptographic Introduction
2. Basic Ciphers
3. Advanced Ciphers, Asymmetry and Public Keys
4. Hacking Technologies: Breaking and By-passing
5. Putting It All Together
Appendix 1: Make up for missing keystore vs. trust store focus
Appendix 2: Where do OSes keep their certificate authorites?
Appendix 3: Where do browsers keep their certificate authorities?
Appendix 4: Questions to answer

Random (incomplete) notes...

...because I skipped over a lot of the early bits of the course, not needing the elementary introduction nor wishing to spend time conveying them in here.

    Section 1: Cryptographic Introduction
    Concepts That Will Be Important
  1. Certificates do not contain keys, but are associated with them.
  2. Certificates are signed with a key.
  3. Public key cryptosystem (PKCS)
    • PKCS1, PKCS4, PKCS12, etc.—the numbers do not matter.
    • PKCS 2 isn't "better than" PKCS 1.
    • The numbers refer to different cryptosystems, not versions, so take the name as a whole.
  4. Algorithm is how something is encrypted and decrypted
    • RSA
    • AES
    • 3DES
    • etc.
  5. The number of bits used by an algorithm represents the strength of the encryption
    • Move in powers of 2 (block size).
    • Cannot be meaningfully compared between algorithms:
      • RSA 2048 is stronger than RSA 1024, but
      • RSA 2048 isn't string than EC 571, nor is
      • RSA stronger than AES, however
      • AES is strong than DES (because the latter's successor).
  6. Section 2: Basic Ciphers
    Symmetric Ciphers and Where They Are Used
  7. Symmetric ciphers
    • Are fast, but
    • The same key both encrypts and decrypts:
    • Anyone who can encrypt a message can also decrypt it.
    • Use when everything is under your control, but
    • not when multiple people need to encrypt.
    • There is danger, for example, that when someone loses their key, everyone else is compromised.
    • You can't tell, however, who encrypted and who decrypted—could be anyone since everyone's "key" (password) is the same! Mathematically, there is no possible repudiation.
    • Examples include AES (and DES/3DES), Blowfish, Serpent.
  8. Can keys be used as passwords?
    • No, because passwords are frequently length-dependent
    • (and keys can be very long).
    • Passwords are measured in characters;
    • Keys are measured in bits
    • —a 128-bit key (very weak) requires 16 bytes to hold it.
  9. Basic Encryption with Symmetric Ciphers
  10. Coded demonstration
    SecureRandom sr                   = new SecureRandom();
    byte[]       key                  = new byte[ 16 ];       // 128-bit key (AES)
    byte[]       initializationVector = new byte[ 16 ];
    sr.nextBytes( key );
    System.out.println( "           Random key=" + bytesToHex( key ) );
    System.out.println( "Initialization vector=" + bytesToHex( initializationVector ) );
  11. Hashing and MessageDigest for Validation
  12. Hashing and message digest
    • These are the same thing.
    • Used to hash one direction and answer questions such as
      • Does this file match?
      • How to validate a password without knowing it?
    • Command algorithms include
      • SHA (out of date)
      • MD5 (ibid)
      • SHA-256 (SHA-512)
    • Hashing is a one-way street from original data to hashed value.
    • The original data can never be recovered from its hashed value.
    • It's only use is to determine whether two samples of original data are identical.
    • Collisions (common with out-of-date algorithms) occur when two different inputs result in the same hashed output.
    • Repeatable values are useful under certain circumstances, e.g.: validating a download.
    • Repeatable values are not desired if the data is supposed to be secret, i.e.: a password. (SALT)
    • What happens if we don't salt? Or we reuse salts?
      • Someone precomputes a giant dictionary (on the web).
      • He looks up your hashed value to reverse it, because...
      • if he has it, then he can go back and derive the original.
      • —why many websites have bizarre password requirements.
      • —such requirements make the needed dictionary significantly L@Rg3r with MiXeD C4SE, etc.
    final String     password   = "12345";
    final String     SALT       = "[email protected]";
    final int        keylength  = 512;
    final int        iterations = 32;      // (number of times through the SALT)
    PBEKeySpec       keyspec    = new PBEKeySpec( password.toCharArray(), SALT.getBytes(), iterations, keylength );
    SecretKeyFactory factory    = SecretKeyFactory.getInstance( "PBKDF2WithHmacSHA256" );
    byte             hashed     = factory.generateSecret( keyspec ).getEncoded();
    System.out.println( "The SHA-256 value salted with PBKDF2 is " + hashed );
  13. Common Security Flaws When Using Symmetric Ciphers
  14. Why all of this?
    • Because cryptography is not usually broken, it's by-passed
      • Small errors render cryptography ineffective.
      • Do everything right except some small thing and security is lost!
    • Common flaws
      • Exposing symmetric keys.
      • Using same symmetric key for different things.
      • Failing to salt sensitive hash information.
      • Relying on bad algorithms because upgrading is hard.
      • Disclosing keys (or passwords) is common.
      • Mistakes in logging statements like
        logger( "Decrypting text with password: " + password );
      • Putting passwords in properties files.
  15. Section 3: Advanced Ciphers, Asymmetry and Public Keys
    Asymmetric Ciphers and Where They Are Used
  16. Two people haven't talked before, ...
    • They have no shared key (symmetric cipher).
    • How to write a message for someone to read?
    • Only they can read the message (not even you can).
    • How to prove who wrote the message? Etc.
      • Because she combined her private key and his public key to encrypt the data, we know it was sent by her.
      • Because it uses his public key, we know that the data is for him.
      • It can only be read by someone who knows her public key and his private key.
    • Optimized hybrid approach: Use asymmetry to exchange a unique symmetric key, then switch to symmetric exchange which is much faster.
    • Otherwise, communication will be very (noticeably) slow. However, this is how most people do it because it takes effort to implement the hybrid system.
    • The name of a populate asymmetric algorithm is RSA, not to be confused with the company of the same (whose founders implemented it). Others include Elliptical Curve (EC) and Diffie-Hellman (DH).
    • The most common asymmetric system is HTTPS, which employs keys and certificates as well as a key-signing request such that the private key remains secret.
  17. Creating a KeyPairGenerator Instance
  18. How do I make a public/private key?
    • Java class KeyPairGenerator.
    • You can use KeyPairGenerator to wrap a key-pair in a certificates before putting it into a key store.
    • Most tend to use OpenSSL rather than Java.
    final KeyPairGenerator generator  = KeyPairGenerator.getInstance( "RSA" ).initialize( 2048 );
    final KeyPair          keypair    = generator.generateKeyPair();
    final PublicKey        publickey  = keypair.getPublic();
    final PrivateKey       privatekey = keypair.getPrivate();
    System.out.println( "  Public key is " + publickey );
    System.out.println( "Hex encoding is " + Util.bytesToHex( publickey.getEncoded() ) );
    System.out.println( " Private key is " + privatekey );
  19. Storing the Java Keystore
  20. What is the point of a keystore?
    • To store one or more keys.
    • Often, you'll have more than one key.
    • A keystore makes it easier to protect keys.
    • A keystore can also be hardware.
    • Makes it so people know where the keys are (not strewn around).
    • There are two types of keystores available to Java developers:
      1. Java Keystore
        • ≤ JDK8
        • Pre-PKCS12
        • file extension .jks
      2. PKCS12 (public-key cryptosystem)
        • ≥ JDK9
        • Cross-system compatibility
        • file extensions .pkcs12, .p12, .pfx
      3. Password...
        • not needed to list contents, but
        • needed to access private-key entries.
        • for the keystore, and
        • for the private key.
        • The Java CA store default is "changeit."
    /* Bouncy Castle Java demo */
  21. The Java keytool
  22. The Java keytool...
    • lists keystore contents,
    • changes (adds or removes) keys and certificates,
    • generates keys,
    • wraps keys in certificates,
    • separates keys to a dedicated tool,
    • makes it easier to demonstrate to someone how you do cryptography correctly.
    • Useful post covering all of keytool.
    /* Java keytool demo */
  23. Creating a KeyGenerator Instance
  24. What is a key generator?
    • Class KeyGenerator generates a key for symmetric cryptology as opposed to
    • KeyPairGenerator which is asymmetric.
    /* Java key generator demo */
  25. Basic Encryption with Asymmetric Ciphers
  26. How asymmetric encryption works
    • Generate two key-pairs,
    • Encrypt and decrypt a message with a key-pair,
    • Show how a signature works.
    /* Basic asymmetric encryption demo */
  27. What to Do When PKIX Validation Fails
  28. PKIX validation failures are a very common problem in Java cryptography development
    • Public key infrastructure for x.509 (certificates)
    • Java error messages about SSL (TLS) and crypto are horrible.
    • There are two common solutions to try before anything else:
      • For ≤ Java 8, apply unlimited cryptography Java Cryptography Extension, jce_policy-8.zip; this unlocks cryptography of a much higher strength.
      • Why does one need unlimited JCE on ≤ Java 8? Because prior to Java 9, the cryptographic base software may not be speaking the particular dialect, for example, SHA-???, required in your problem.
      • In Java 9, this was fixed.
      • Alternatively, ensure that you have the root certificate for whatever it is that you're connecting to inside of your keystore by using keytool -importcert.
      • Where and how to add a root certificate?
      • Look back at the keytool section in this presentation where this wasn't really covered. The main root certificate store is in lib/security/cacerts and its password is "changeit."
      • Export the problem certificate from your browser and import it thus:
        $ keytool -importcert
        keytool will perform duplicate-certificate avoidance for you.
    • Other tricks:
      • At JRE start-up: -Djavax.net.debug=all .
      • Also,
        • -Dhttps.proxyHost
        • -Dhttps.proxyPort
        • -Dhttps.proxyUser
        • -Dhttps.proxyPassword
      • See Diagnosing TLS, SSL and HTTPS.
    • What should you not do?
      • Disable SSL validation (as many suggest in places like stackoverlow).
  29. Java Certificate Chains
  30. How to analyze these chains
    • What is a certificate chain?
      • Java trusts a lot of root-certificate authorities
        • lib/security/cacerts
        • A root signs one or more intermediaries.
        • The last intermediary signs a website certificate.
        • (This is a chain.)
        • All certificates (along the way) have one or more public keys.
        • All certificates are x.509.
        • Messing with these isn't something you ordinarily do.
    /* Java demo certificate chains */
  31. The Key Escrow Problem
  32. Escrow, the state of being kept in custody or trust. Public keys are escrowed in order that they may be shared or publicized.
    • If you have never talked to someone before...
      • If find his public key, how do you know it's his?
      • How do you know he even has a private key?
    • Therefore, you use an existing certificate authority to distribute and validate public keys.
  33. Section 4: Hacking Techniques: Breaking and By-passing
  34. I'm skipping this because it's 45 minutes long and doesn't contribute to what I need to learn.
  35. Section 5: Putting It All Together
    Encrypting and Decrypting Files
  36. —including streams?
    • Don't code advanced, confusing things.
    • Enforce correct behavior throught typing, e.g.:
      • Classes Random and SecureRandom
      • Requiring the latter, it's not possible to do the wrong thing, accidentally pass in a "wrong type of random number," etc.
    • No Java programmer wants to work on objects of type byte[] so these are wrapped by closeable streams (e.g.: CipherInputStream and CipherOutputStream).
    • Demonstration that does this:
      1. Initialize a symmetric cipher (this code already written in section 2, above),
      2. encrypt a PowerPoint presentation,
      3. decrypt that PowerPoint presentation, then
      4. open the PowerPoint presenation and finish the walk-through.
      SecureRandom random = new SecureRandom();
      byte[]       key    = new byte[ 16 ];        // 128-bit
      byte[]       vector = new byte[ 16 ];
      random.nextBytes( key );
      System.out.println( "           Random key=" + Util.bytesToHex( key ) );
      System.out.println( "Initialization vector=" + Util.bytesToHex( vector ) );
      IvParameterSpec initializationVector = new IvParameterSpec( vector );
      SecretKeySpec   keyspec              = new SecretKeySpec( key, "AES" );
      Cipher          cipher               = Cipher.getInstance( "AES/CBC/PKCS5PADDING" );
      cipher.init( Cipher.ENCRYPT_MODE, keyspec, initializationVector );
      final String TEMPORARY_DIRECTORY = "packt-crypto";
      final String RESOURCE_DIRECTORY  = "1 - Encrypting and Decrypting files.pptx";
      final String ENCRYPTED_DIRECTORY = RESOURCE_DIRECTORY + ".encrypted";
      final Path directory = Files.createTempDirectory( TEMPORARY_DIRECTORY );
      final Path path      = directory.resolve( ENCRYPTED_DIRECTORY );
      try( InputStream        inputStream        = FileEncryptor.class.getResourcesAsStream( DIRECTORY ),
          OutputStream       __encrypted__      = Files.newOutputStream( path )
          CipherOutputStream cipherOutputStream = new CipherOutputStream( __encrypted__, cipher )
        final byte[] bytes = new byte[ 1024 ];
        for( int length = inputStream.read( bytes ); length != EOF; length = inputStream.read( bytes ) )
          cipherOutputStream.write( bytes, 0, length );
      catch( IOException e )
       logger.warn( "Unable to encrypt", e );
      logger.info( "Encryption finished; saved at ", path );
      ...decrypt, etc.
  37. Obtaining Certificates from LetsEncrypt (or AWS)
  38. Lets Encrypt
    • Real certificates cost money
      • They validate ownership of keys.
      • They prevent impersonation.
      • No one knows your self-signed key or shares it.
      • Anymore, they don't cost: read on!
    • Let's Encrypt provides...
      • Free forever certificates.
      • Trusted certificates.
      • Via fully automatable and scriptable means.
      • Full support for on-premise or in any cloud.
      • Let's Encrypt FAQ
      • Down-sides include
      • Short-lived (90 days).
      • Work better with Internet-connected systems.
  39. Qualys SSL Labs for Your Servers
  40. Qualys SSL Labs is free and scans your servers for health.
  41. The DeepViolet Security Analyzer
  42. DeepViolet is a tool to look at SSL.

See Appendices here.