O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)

706 visualizações

Publicada em

Cryptography for Java Developers

Hashes, MAC, Key Derivation, Encrypting Passwords, Symmetric Ciphers & AES, Digital Signatures & ECDSA

About the Speaker
What is Cryptography?
Cryptography in Java – APIs and Libraries
Hashes, MAC Codes and Key Derivation (KDF)
Encrypting Passwords: from Plaintext to Argon2
Symmetric Encryption: AES (KDF + Block Modes + IV + MAC)
Digital Signatures, Elliptic Curves, ECDSA, EdDSA

Live demos and code examples: https://github.com/nakov/Java-Cryptography-Examples

Video (in Bulgarian language): https://youtu.be/ZG3BLXWVwJM

Blog: https://nakov.com/blog/2019/01/26/cryptography-for-java-developers-nakov-at-jprofessionals-jan-2019/

Publicada em: Educação
  • Seja o primeiro a comentar

  • Seja a primeira pessoa a gostar disto

Cryptography for Java Developers: Nakov jProfessionals (Jan 2019)

  1. 1. Hashes, MAC, Key Derivation, Encrypting Passwords, Symmetric Ciphers & AES, Digital Signatures & ECDSA Cryptography for Java Developers Dr. Svetlin Nakov Co-Founder, Chief Training & Innovation @ Software University (SoftUni) https://nakov.com Software University (SoftUni) – http://softuni.org
  2. 2. Table of Contents 1. About the Speaker 2. What is Cryptography? 3. Cryptography in Java – APIs and Libraries 4. Hashes, MAC Codes and Key Derivation (KDF) 5. Encrypting Passwords: from Plaintext to Argon2 6. Symmetric Encryption: AES (KDF + Block Modes + IV + MAC) 7. Digital Signatures, Elliptic Curves, ECDSA, EdDSA 2
  3. 3.  Software engineer, trainer, entrepreneur, PhD, author of 15+ books, blockchain expert  3 successful tech educational initiatives (150,000+ students) About Dr. Svetlin Nakov 3
  4. 4. Book "Practical Cryptography for Developers" 4 GitHub: github.com/nakov/pra ctical-cryptography- for-developers-book Book site: https://cryptobook. nakov.com
  5. 5. What is Cryptography?
  6. 6.  Cryptography provides security and protection of information  Storing and transmitting data in a secure way  Hashing data (message digest) and MAC codes  Encrypting and decrypting data  Symmetric and asymmetric schemes  Key derivation functions (KDF)  Key agreement schemes, digital certificates  Digital signatures (sign / verify) What is Cryptography? 6
  7. 7. Cryptography in Java: JCA, Bouncy Castle, Other Libraries
  8. 8.  JDK defines security APIs based on pluggable security providers  Build-in providers (come with JDK) and 3rd party providers  Named algorithms, e.g.  MessageDigest: SHA-256, SHA3- 256, RipeMD160, Skein-1024  Cipher: AES, Blowfish, ECIES  Signature: SHA3-256withECDSA, SHA512withRSA, SHA384withDSA Java Security: Architecture 8
  9. 9.  Cryptography in Java is based on the Java Cryptography Architecture (JCA)  The built-in functionality is limited  Typical Java style: lot of boilerplate code  Bouncy Castle is a leading Java crypto library / API / provider  https://www.bouncycastle.org/java.html  Argon2 JVM – fast Argon2 native implementation for Java  https://github.com/phxql/argon2-jvm Cryptography APIs in Java 9
  10. 10.  Cava Crypto – excellent simple ECDSA library for secp256k1  https://github.com/ConsenSys/cava  https://github.com/ConsenSys/cava/tree/master/crypto  Web3j / Crypto – a simplified library for secp256k1 signatures  https://github.com/web3j  Ed25519-Java – simple EdDSA and Ed25519 implementation  https://github.com/str4d/ed25519-java Cryptography APIs in Java 10
  11. 11.  Use Maven / Gradle to install the Java crypto libraries  Installing the Bouncy Castle crypto provider / API Installing the Libraries 11 pom.xml <!-- Install the Bouncy Castle crypto provider for Java --> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.60</version> </dependency>
  12. 12. Cryptographic Hash Functions
  13. 13. What is Cryptographic Hash Function? 13  One-way transformation, infeasible to invert  Extremely little chance to find a collision Some text Some text Some text Some text Some text Some text Some text 20c9ad97c081d63397d 7b685a412227a40e23c 8bdc6688c6f37e97cfb c22d2b4d1db1510d8f6 1e6a8866ad7f0e17c02 b14182d37ea7c3c8b9c 2683aeb6b733a1 Text Hash (digest) Cryptographic hash function
  14. 14.  SHA-2 (SHA-256, SHA-384, SHA-512)  Secure crypto hash function, the most widely used today (RFC 4634)  Used in Bitcoin, IPFS, many others  SHA-3 (SHA3-256, SHA3-384, SHA3-512) / Keccak-256  Strong cryptographic hash function, more secure than SHA-2  Used in Ethereum and many modern apps Modern Hashes: SHA-2, SHA3 14 SHA-256('hello') = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7 425e73043362938b9824 SHA3-256('hello') = 3338be694f50c5f338814986cdf0686453a888b84f4 24d792af4b9202398f392
  15. 15.  BLAKE2 (BLAKE2s – 256-bit, BLAKE2b – 512-bit)  Secure crypto hash function, very fast  RIPEMD-160 (160-bit crypto hash)  Considered weak, just 160-bits, still unbroken  Broken hash algorithms: MD5, SHA-1, MD4, SHA-0, MD2  Git and GitHub still use SHA-1 and suffer of collision attacks Modern Hashes: BLAKE2, RIPEMD-160 15 BLAKE2s('hello') = 19213bacc58dee6dbde3ceb9a47cbb330b3d86f8cca8 997eb00be456f140ca25 RIPEMD-160('hello') = 108f07b8382412612c048d07d13f814118445acd
  16. 16.  Calculate SHA-256 hash using the built-in JCA provider: SHA-256 in Java – Example 16 var digest = MessageDigest.getInstance("SHA-256"); digest.update("hello".getBytes()); byte[] hash = digest.digest(); System.out.println("SHA-256('hello') = " + Hex.toHexString(hash)); import java.security.MessageDigest; import org.bouncycastle.util.encoders.Hex; SHA-256('hello') = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
  17. 17.  Calculate RIPEMD-160 hash using the Bouncy Castle provider: RIPEMD-160 in Java – Example 17 var digest = MessageDigest.getInstance("RIPEMD160"); digest.update("hello".getBytes()); byte[] hash = digest.digest(); System.out.println("RIPEMD-160('hello') = " + Hex.toHexString(hash)); import java.security.*; import org.bouncycastle.util.encoders.Hex; import org.bouncycastle.jce.provider.BouncyCastleProvider; // One-time registration of the "BouncyCastle" JCA provider Security.addProvider(new BouncyCastleProvider()); 108f07b8382412612c048d07d13f814118445acd
  18. 18. HMAC and Key Derivation (KDF) MAC, HMAC, PBKDF2, Scrypt, Argon2
  19. 19.  HMAC = Hash-based Message Authentication Code (RFC 2104)  HMAC(key, msg, hash_func)  hash  Message hash mixed with a secret shared key  Used for message integrity / authentication / key derivation MAC Codes and HMAC 19 HMAC('key', 'hello', SHA-256) = 9307b3b915efb5171ff14d8cb55fbc c798c6c0ef1456d66ded1a6aa723a58b7b HMAC('key', 'hello', RIPEMD-160) = 43ab51f803a68a8b894cb32ee19e6854e9f4e468
  20. 20.  Calculate HMAC-SHA-256 hash using the built-in JCA provider: HMAC in Java – Example 20 Mac mac = Mac.getInstance("HmacSHA256"); Key key = new SecretKeySpec("key".getBytes(), "HmacSHA256"); mac.init(key); byte[] hash = mac.doFinal("hello".getBytes()); System.out.println("HMAC-SHA-256: " + Hex.toHexString(hash)); import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.Key; import org.bouncycastle.util.encoders.Hex; HMAC-SHA-256: 9307b3b915efb5171ff14d8cb55fbcc798c6c0ef1456d66ded1a6aa723a58b7b
  21. 21.  Key derivation function (KDF) == function(password)  key  PBKDF2 (Password-Based Key Derivation Function 2, RFC 2898) Key Derivation Functions (KDF) 21 PBEKeySpec spec = new PBEKeySpec("password".toCharArray(), "salt".getBytes(), 1000, 128); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); byte[] derivedKey = keyFactory.generateSecret(spec).getEncoded(); System.out.println("PBKDF2 key: " + Hex.toHexString(derivedKey)); PBKDF2 derived key: 632c2812e46d4604102ba7618e9d6d7d
  22. 22.  Scrypt (RFC 7914) is a strong cryptographic key-derivation function  Memory intensive, designed to prevent ASIC and FPGA attacks  key = Scrypt(password, salt, N, r, p, derived-key-len)  N – iterations count (affects memory and CPU usage), e.g. 16384  r – block size (affects memory and CPU usage), e.g. 8  p – parallelism factor (threads to run in parallel), usually 1  Memory used = 128 * N * r * p bytes, e.g. 128 * 16384 * 8 = 16 MB  Parameters for interactive login: N=16384, r=8, p=1 (RAM=16MB)  Parameters for file encryption: N=1048576, r=8, p=1 (RAM=1GB) Key Derivation Functions: Scrypt 22
  23. 23. Scrypt in Java – Example 23 // One-time registration of the "BouncyCastle" JCA provider Security.addProvider(new BouncyCastleProvider()); ScryptKeySpec spec = new ScryptKeySpec( "password".toCharArray(), "salt".getBytes(), 16384, 8, 1, 128); var keyFact = SecretKeyFactory.getInstance("Scrypt"); byte[] derivedKey = keyFact.generateSecret(spec).getEncoded(); System.out.println("Scrypt: " + Hex.toHexString(derivedKey)); Scrypt: 745731af4484f323968969eda289aeee
  24. 24.  Argon2 is ASIC-resistant KDF, stronger than Scrypt and bcrypt  Recommended due to better ASIC-resistance Key Derivation: Argon2 24 pom.xml <!-- Install Argon2-JVM – fast native Argon2 library for Java --> <dependency> <groupId>de.mkammerer</groupId> <artifactId>argon2-jvm</artifactId> <version>2.5</version> </dependency>
  25. 25. Argon2 in Java – Example 25 import de.mkammerer.argon2.Argon2Advanced; import de.mkammerer.argon2.Argon2Factory; import org.bouncycastle.util.encoders.Hex; Argon2Advanced argon2 = Argon2Factory.createAdvanced( Argon2Factory.Argon2Types.ARGON2id); byte[] hash = argon2.rawHash(16, 1 << 15, 2, "password", "some salt".getBytes()); System.out.println("Argon2 hash: " + Hex.toHexString(hash)); Argon2 hash: 157f21dd3fdf7bafb76d2923ccaffa0b7be7cbae394709474d2bc66ee7b09d3e
  26. 26.  Clear-text passwords, e.g. store the password directly in the DB  Never do anti-pattern!  Simple password hash, e.g. store SHA256(password) in the DB  Highly insecure, still better than clear-text, dictionary attacks  Salted hashed passwords, e.g. store HMAC(pass, random_salt)  Almost secure, GPU / ASIC-crackable  ASIC-resistant KDF password hash, e.g. Argon2(password)  Recommended, secure (when the KDF settings are secure) Password Encryption (Register / Login) 26
  27. 27.  Argon2 is the recommended password-hashing for apps Encrypting Passwords: Argon2 27 String hash = argon2.hash(8, 1 << 16, 4, "password"); System.out.println("Argon2 hash (random salt): " + hash); System.out.println("Argon2 verify (correct password): " + argon2.verify(hash, "password")); System.out.println("Argon2 verify (wrong password): " + argon2.verify(hash, "wrong123")); Argon2 hash (random salt): $argon2id$v=19$m=65536,t=8,p=4$FW2kqbP+nidwHnT3Oc vSEg$oYlK3rXJvk0Be+od3To131Cnr8JksL39gjnbMlUCCTk Argon2 verify (correct password): true Argon2 verify (wrong password): false Register Login Invalid Login
  28. 28. Symmetric Encryption AES, Block Modes, Authenticated Encryption encrypt (secret key) I am a non- encrypted message … decrypt (secret key) I am a non- encrypted message …
  29. 29.  Symmetric key ciphers  Use the same key (or password) to encrypt and decrypt data  Popular symmetric algorithms  AES, ChaCha20, Twofish, Serpent, RC5, RC6  Broken algorithms (don't use them!)  DES, 3DES, RC2, RC4 Symmetric Key Ciphers 29
  30. 30.  Block ciphers  Split data on blocks (e.g. 128 bits), then encrypt each block separately, change the internal state, encrypt the next block, …  Stream ciphers  Work on sequences of data (encrypts / decrypts byte by byte)  Block ciphers can be transformed to stream ciphers  Using block mode of operation (e.g. CBC, CTR, GCM, CFB, …)  https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation Symmetric Key Ciphers 30
  31. 31.  AES – Advanced Encryption Standard (Rijndael)  Symmetric key block cipher (128-bit blocks)  Key lengths: 128, 160, 192, 224 and 256 bits  No significant practical attacks are known for AES  Modern CPU hardware implements AES instructions  This speeds-up AES and secure Internet communication  AES is used by most Internet Web sites for the https:// content The "AES" Cipher 31
  32. 32.  AES is a "block cipher" – encrypts block by block (e.g. 128 bits)  Supports several modes of operation (CBC, CTR, GCM, …)  Some modes of operation (like CBC / CTR) require initial vector (IV)  Non-secret random salt  used to get different result each time  Recommended modes: CTR (Counter) or GCM (Galois/Counter)  CBC may use a padding algorithm (typically PKCS7) to help splitting the input data into blocks of fixed block-size (e.g. 128 bits)  May use password to key derivation function, e.g. Argon2(passwd)  May use MAC to check the password validity, e.g. HMAC(text, key) AES Cipher Settings 32
  33. 33. The AES Encryption Process 33 input msg random IV+ AES key+ ciphertext input msg MAC key+ MAC code input msg key+ AES ciphertext MAC+IV+ KDF password key kdf-salt+
  34. 34. The AES Decryption Process 34 original msg MAC key+ MAC code AES ciphertext IV+ KDF password key original msg decrypt Decryption MAC code compare Encryption MAC code key+ kdf-salt+
  35. 35. AES-256-CTR-Argon2-HMAC – Encrypt 35 static Map<String, String> aes256CtrArgon2HMacEncrypt( String plainText, String password) throws Exception { // Derive a secret key from the encryption password SecureRandom rand = new SecureRandom(); byte[] argon2salt = new byte[16]; rand.nextBytes(argon2salt); // Generate 128-bit salt byte[] argon2hash = Argon2Factory.createAdvanced( Argon2Factory.Argon2Types.ARGON2id).rawHash(16, 1 << 15, 2, password, argon2salt); Key secretKey = new SecretKeySpec(argon2hash, "AES");
  36. 36. AES-256-CTR-Argon2-HMAC – Encrypt 36 // AES encryption: {plaintext + IV + secretKey} -> ciphertext byte[] aesIV = new byte[16]; rand.nextBytes(aesIV); // Generate 128-bit IV (salt) IvParameterSpec ivSpec = new IvParameterSpec(aesIV); Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec); byte[] plainTextBytes = plainText.getBytes("utf8"); byte[] cipherBytes = cipher.doFinal(plainTextBytes); // Calculate the MAC of the plaintext with the argon2hash Mac mac = Mac.getInstance("HmacSHA256"); Key macKey = new SecretKeySpec(argon2hash, "HmacSHA256"); mac.init(macKey); byte[] hmac = mac.doFinal(plainText.getBytes("utf8"));
  37. 37. AES-256-CTR-Argon2-HMAC – Encrypt 37 var encryptedMsg = Map.of( "kdf", "argon2", "kdfSalt", Hex.toHexString(argon2salt), "cipher", "aes-256-ctr", "cipherIV", Hex.toHexString(aesIV), "cipherText", Hex.toHexString(cipherBytes), "mac", Hex.toHexString(hmac) ); return encryptedMsg; Encrypted msg: {cipherIV=dd088070cf4f2f6c6560b8fa7fb43f49, kdf=argon2, cipherText=a847f3b2bc59278107, mac=6c143d139d0d7b29aaa 4e0dc5916908d3c27576f4856e3ef487be6eafb23b39a, kdfSalt=90c6fcc318f d273f4f661c019b39b8ed, cipher=aes-256-ctr}
  38. 38. AES-256-CTR-Argon2-HMAC – Decrypt 38 static String aes256CtrArgon2HMacDecrypt(Map<String, String> encryptedMsg, String password) throws Exception { // Derive the secret key from the encryption password with argon2salt byte[] argon2salt = Hex.decode(encryptedMsg.get("kdfSalt")); byte[] argon2hash = Argon2Factory.createAdvanced( Argon2Factory.Argon2Types.ARGON2id).rawHash(16, 1 << 15, 2, password, argon2salt);
  39. 39. AES-256-CTR-Argon2-HMAC – Decrypt 39 // AES decryption: {cipherText + IV + secretKey} -> plainText byte[] aesIV = Hex.decode(encryptedMsg.get("cipherIV")); IvParameterSpec ivSpec = new IvParameterSpec(aesIV); Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding"); Key secretKey = new SecretKeySpec(argon2hash, "AES"); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec); byte[] cipherTextBytes = Hex.decode(encryptedMsg.get("cipherText")); byte[] plainTextBytes = cipher.doFinal(cipherTextBytes); String plainText = new String(plainTextBytes, "utf8");
  40. 40. AES-256-CTR-Argon2-HMAC – Decrypt 40 // Calculate & check the MAC code: HMAC(plaintext, argon2hash) Mac mac = Mac.getInstance("HmacSHA256"); Key macKey = new SecretKeySpec(argon2hash, "HmacSHA256"); mac.init(macKey); byte[] hmac = mac.doFinal(plainText.getBytes("utf8")); String decodedMac = Hex.toHexString(hmac); String cipherTextMac = encryptedMsg.get("mac"); if (! decodedMac.equals(cipherTextMac)) throw new InvalidKeyException("MAC does not match: maybe wrong password"); return plainText; }
  41. 41. Digital Signatures ECDSA, EdDSA, Sign / Verify
  42. 42.  Digital signatures provide message signing / verification  Authentication (proof that known sender have signed the message)  Integrity (the message cannot be altered after signing)  Non-repudiation (signer cannot deny message signing)  Digital signatures are based on public key cryptography  Messages are signed by someone's private key  Signatures are verified by the corresponding public key  May use RSA, DSA, elliptic curves (ECC) like ECDSA / EdDSA Digital Signatures – Concepts 42
  43. 43.  Uses a pair of keys: public key + private key  Sign / decrypt by private key  Verify / encrypt by public key Public Key Cryptography 43
  44. 44.  Well-known public-key crypto-systems  RSA – based on discrete logarithms  ECC – based on elliptic curves  ECC cryptography is considered more secure  3072-bit RSA key ≈≈ 256-bit ECC key  ~ 128-bit security level  Most blockchains (like Bitcoin, Ethereum and EOS) use ECC  But be warned: ECC is not quantum-safe! Public Key Crypto Systems 44
  45. 45.  Digital signatures in Java are painful  use external libraries  Use the "Cava Crypto" library for secp256k1 ECDSA signatures ECDSA in Java – Example 45 pom.xml !-- Install Cava Crypto: simple secp256k1 ECDSA library --> <dependency> <groupId>net.consensys.cava</groupId> <artifactId>cava-crypto</artifactId> <version>0.5.0</version> </dependency>
  46. 46. ECDSA in Java – Example 46  Registering the Bouncy Castle crypto provider  Generating public + private key pair: Security.addProvider(new BouncyCastleProvider()); // Generate random key-pair SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.random(); // Load key-pair from existing private key SECP256K1.KeyPair keyPair = SECP256K1.KeyPair.fromSecretKey( SECP256K1.SecretKey.fromInteger(new BigInteger( "207724f0eba0800350f579726c2a8bbd1ac6385f4168e493cfd91efe522959cf", 16)));
  47. 47. ECDSA in Java – Example 47 System.out.println("Private key (256 bits): " + Hex.toHexString(keyPair.secretKey().bytesArray())); System.out.println("Public key (512 bits): 04" + Hex.toHexString(keyPair.publicKey().bytesArray())); System.out.println("Public key (compressed): " + compressPubKey(keyPair.publicKey())); static String compressPubKey(SECP256K1.PublicKey pk) { BigInteger pubKey = new BigInteger(1, pk.bytesArray()); String pubKeyYPrefix = pubKey.testBit(0) ? "03" : "02"; String pubKeyHex = pubKey.toString(16); String pubKeyX = pubKeyHex.substring(0, 64); return pubKeyYPrefix + pubKeyX; }
  48. 48.  Signing a message with SHA256 + ECDSA with secp256k1 ECDSA in Java – Example 48 String msg = "Message for signing"; byte[] msgHash = Hash.sha2_256(msg.getBytes()); var signature = SECP256K1.signHashed(msgHash, keyPair); System.out.println("Msg: " + msg); System.out.println("Msg hash: " + Hex.toHexString(msgHash)); System.out.printf("Signature: [r = %s, s = %s, v = %d]n", signature.r().toString(16), signature.s().toString(16), signature.v()); Signature: [r = 3ce2c58b02a06f16c849d6ac1d05e9d6dc41b92929ed2733d3 ddf060e2035c20, s = 292d5d83ffd5a46befeef33a9c6e9fc562d412e0d90934 dfb4ed0a7d80caff61, v = 0]
  49. 49.  Verify ECDSA signature: ECDSA in Java – Example 49 boolean validSig = SECP256K1.verifyHashed( msgHash, signature, keyPair.publicKey()); System.out.println("Signature valid (correct key)? " + validSig); boolean validSigWrongKey = SECP256K1.verifyHashed( msgHash, signature, SECP256K1.KeyPair.random().publicKey()); System.out.println("Signature valid (wrong key)? " + validSigWrongKey); Signature valid (wrong key)? false Signature valid (correct key)? true
  50. 50. ECDSA + secp256k1: Recover Public Key 50 // Recover the public key from msg + signature SECP256K1.PublicKey recoveredPubKey = SECP256K1.PublicKey. recoverFromHashAndSignature(msgHash, signature); System.out.println("Recovered pubKey: 04" + Hex.toHexString(recoveredPubKey.bytesArray())); System.out.println("Signature valid ? " + recoveredPubKey.equals(keyPair.publicKey())); Recovered pubKey: 0425c919aa487e577cc361f43a9b81f3484286ac6132c9ef f047ec6eca6c1dcc89200c1bf5d6da42a8206a2f01b585d35ea05c2648050f3dd4 c98fc0b87f5191e5 Signature valid ? true
  51. 51.  EdDSA is elliptic curve-based digital signature scheme (based on Edwards curves)  Ed25519 is fast Edwards curve, used for EdDSA signatures  256-bit public key (252 + 5 fixed bits) and 256-bit private key  Supported by 3rd party libraries like  https://github.com/str4d/ed25519-java  EdDSA is preferred to ECDSA in most modern apps  Faster and easier to use EdDSA + Ed25519 Signatures 51
  52. 52. EdDSA in Java – Example 52  Installing the required library Ed25519-Java using Maven  Registering the EdDSA-Java crypto provider Security.addProvider(new EdDSASecurityProvider()); pom.xml <dependency> <groupId>net.i2p.crypto</groupId> <artifactId>eddsa</artifactId> <version>0.3.0</version> </dependency>
  53. 53. EdDSA in Java – Example 53  Generating a random EdDSA public + private key pair var keyGen = KeyPairGenerator.getInstance("EdDSA"); var keyPair = keyGen.generateKeyPair(); System.out.println("Private key: " + Hex.toHexString(keyPair.getPrivate().getEncoded())); System.out.println("Public key: " + Hex.toHexString(keyPair.getPublic().getEncoded())); Private key: 302e020100300506032b657004220420b57ea3f12b503be8e7c89 99dd9cb630ecb06cb68e10763fb40331e5131b2a1f0 Public key: 302a300506032b6570032100796295d26f7a69a2a573cf95f99bd5 becb906e757bb55424deb4ed00a99cc572
  54. 54. EdDSA in Java – Example 54  Signing a message with EdDSA String msg = "Message for signing"; Signature signer = new EdDSAEngine( MessageDigest.getInstance("SHA-512")); signer.initSign(keyPair.getPrivate()); signer.update(msg.getBytes()); byte[] signature = signer.sign(); System.out.println("Signature: " + Hex.toHexString(signature)); Signature: 1256d92d27b5b4e633494b86f5f55dc18155ae4eed35d5f596f1dbb 894acef0df7e2b756ef5e5681260d2f46dd1c26e180591e1ec3f9997f213ddf0ca 55c6703
  55. 55. EdDSA in Java – Example 55  Verifying EdDSA signature: {msg + signature + pubKey}  bool Signature verifier = new EdDSAEngine(MessageDigest.getInstance("SHA-512")); verifier.initVerify(keyPair.getPublic()); verifier.update(msg.getBytes()); boolean validSig = verifier.verify(signature); System.out.println("Signature valid (correct key)? " + validSig); Signature valid (correct key)? true
  56. 56. Live Demos and Code Examples https://github.com/nakov/Java-Cryptography-Examples
  57. 57. https://nakov.com Cryptography for Java Developers

×