├── .gitbook
└── assets
│ ├── AES-decrypt-msg.png
│ ├── AES-encryption-process.png
│ ├── AES-input-output.png
│ ├── Argon2-online.png
│ ├── CTR-block-mode.png
│ ├── Compare-encryption-decryption-MAC.png
│ ├── Diffie-Hellman-Key-Exchange-Protocol.png
│ ├── Diffie-Hellman-online.png
│ ├── ECC-multiply-point-example.png
│ ├── ECIES.png
│ ├── Edwards-curve.png
│ ├── GCM-Galois_Counter_Mode.png
│ ├── HMAC-calculation-AES.png
│ ├── HMAC-online.png
│ ├── HMAC-original-msg.png
│ ├── MAC-message-authentication-code.png
│ ├── MyEtherWallet.png
│ ├── PBKDF2-calculator.png
│ ├── Practical-Cryptography-for-Developers-Book-Nakov-front-cover.png
│ ├── Scrypt-key-derivation.png
│ ├── SoftUni-banner.jpg
│ ├── Svetlin-Nakov-photo-face.jpg
│ ├── aes-decrypt-msg.png
│ ├── aes-encryption-process.png
│ ├── aes-input-output.png
│ ├── aesencryption.net.png
│ ├── argon2-online.png
│ ├── asymmetric-encryption-diagram.png
│ ├── asymmetric-encryption-online-demo-jsencrypt.png
│ ├── bcrypt-online-example.png
│ ├── bitaddress-entropy.png
│ ├── bitcoin-elliptic-curve.png
│ ├── checksum-download-openssl.png
│ ├── compare-encryption-decryption-mac.png
│ ├── crypto-hash-function-examples.jpg
│ ├── crypto-hash-function.jpg
│ ├── ctr-block-mode.png
│ ├── diffie-hellman-key-exchange-protocol.png
│ ├── diffie-hellman-online.png
│ ├── ec-generator-f17.png
│ ├── ecc-multiply-point-example.png
│ ├── ecc-visualization-tool.png
│ ├── ecies.png
│ ├── edwards-curve.png
│ ├── elliptic-curve-general-case.png
│ ├── elliptic-curve-over-f17-example.png
│ ├── elliptic-curve-over-f17-points-per-y-coordinate.png
│ ├── elliptic-curve-subgroups.png
│ ├── encrypt-decrypt-live-demo.jpg
│ ├── gcm-galois_counter_mode.png
│ ├── git-commit-logs.png
│ ├── hash-function.jpg
│ ├── hash-functions-online.png
│ ├── hmac-calculation-aes.png
│ ├── hmac-online.png
│ ├── hmac-original-msg.png
│ ├── hybrid-decryption (1).png
│ ├── hybrid-decryption.png
│ ├── hybrid-encryption (1).png
│ ├── hybrid-encryption.png
│ ├── insecure-rnd-python-demo.png
│ ├── key-exchange-by-color-mixing-part-1.png
│ ├── key-exchange-by-color-mixing-part-2.png
│ ├── linux-shadow-encrypted-passwords.png
│ ├── mac-message-authentication-code.png
│ ├── more-cryptographic-concepts-OTP-secret-QR-code.png
│ ├── more-cryptographic-concepts-otp-secret-qr-code.png
│ ├── myetherwallet.png
│ ├── one-time-passwords-otp-example-qr-code.png
│ ├── password-kdf-key.png
│ ├── pbkdf2-calculator.png
│ ├── points-on-elliptic-curve-over-finite-field.png
│ ├── practical-cryptography-for-developers-book-nakov-front-cover.png
│ ├── pseudo-random-function.png
│ ├── public-key-cryptography-encrypt-decrypt.png
│ ├── public-key-cryptography-sign-verify.png
│ ├── scrypt-key-derivation.png
│ ├── signature-sign-verify.png
│ ├── softuni-banner.jpg
│ ├── svetlin-nakov-photo-face.jpg
│ ├── symmetric-encryption.png
│ └── symmetric-key-encryption-decryption.gif
├── .gitignore
├── LICENSE
├── README.md
├── SUMMARY.md
├── assets
├── AES-decrypt-msg.png
├── AES-encryption-process.png
├── AES-input-output.png
├── Argon2-online.png
├── CTR-block-mode.png
├── Compare-encryption-decryption-MAC.png
├── Diffie-Hellman-Key-Exchange-Protocol.png
├── Diffie-Hellman-online.png
├── ECC-multiply-point-example.png
├── ECIES.png
├── Edwards-curve.png
├── GCM-Galois_Counter_Mode.png
├── HMAC-calculation-AES.png
├── HMAC-online.png
├── HMAC-original-msg.png
├── MAC-message-authentication-code.png
├── MyEtherWallet.png
├── PBKDF2-calculator.png
├── Practical-Cryptography-for-Developers-Book-Nakov-front-cover.png
├── Scrypt-key-derivation.png
├── SoftUni-banner.jpg
├── Svetlin-Nakov-photo-face.jpg
├── aesencryption.net.png
├── asymmetric-encryption-diagram.png
├── asymmetric-encryption-online-demo-jsencrypt.png
├── bcrypt-online-example.png
├── bitaddress-entropy.png
├── bitcoin-elliptic-curve.png
├── checksum-download-openssl.png
├── crypto-hash-function-examples.jpg
├── crypto-hash-function.jpg
├── ec-generator-f17.png
├── ecc-visualization-tool.png
├── elliptic-curve-general-case.png
├── elliptic-curve-over-f17-example.png
├── elliptic-curve-over-f17-points-per-y-coordinate.png
├── elliptic-curve-subgroups.png
├── encrypt-decrypt-live-demo.jpg
├── git-commit-logs.png
├── hash-function.jpg
├── hash-functions-online.png
├── hybrid-decryption.png
├── hybrid-encryption.png
├── insecure-rnd-python-demo.png
├── js
│ └── repl.it-code-runner.js
├── key-exchange-by-color-mixing-part-1.png
├── key-exchange-by-color-mixing-part-2.png
├── linux-shadow-encrypted-passwords.png
├── more-cryptographic-concepts-OTP-secret-QR-code.png
├── one-time-passwords-otp-example-qr-code.png
├── password-kdf-key.png
├── points-on-elliptic-curve-over-finite-field.png
├── pseudo-random-function.png
├── public-key-cryptography-encrypt-decrypt.png
├── public-key-cryptography-sign-verify.png
├── signature-sign-verify.png
├── symmetric-encryption.png
└── symmetric-key-encryption-decryption.gif
├── asymmetric-key-ciphers
├── README.md
├── ecc-encrypt-decrypt-examples.md
├── ecc-encryption-decryption.md
├── ecdh-key-exchange-examples.md
├── ecdh-key-exchange.md
├── ecies-example.md
├── ecies-public-key-encryption.md
├── elliptic-curve-cryptography-ecc.md
├── exercises-ecdh-key-exchange.md
├── exercises-ecies-encrypt-decrypt.md
├── exercises-rsa-encrypt-decrypt.md
├── rsa-encrypt-decrypt-examples.md
├── rsa-or-ecc-which-is-better.md
└── the-rsa-cryptosystem-concepts.md
├── book.json
├── conclusion.md
├── cover.jpg
├── crypto-libraries-for-developers
├── README.md
├── c-crypto-libraries.md
├── java-crypto-libraries.md
├── javascript-crypto-libraries.md
└── python-crypto-libraries.md
├── cryptographic-hash-functions
├── README.md
├── crypto-hashes-and-collisions.md
├── exercises-calculate-hashes.md
├── hash-functions-applications.md
├── hash-functions-examples.md
├── proof-of-work-hash-functions.md
└── secure-hash-algorithms.md
├── cryptography-overview.md
├── digital-signatures
├── README.md
├── ecdsa-sign-verify-examples.md
├── ecdsa-sign-verify-messages.md
├── eddsa-and-ed25519.md
├── eddsa-sign-verify-examples.md
├── exercises-eddsa-sign-and-verify.md
├── exercises-rsa-sign-and-verify.md
├── exercises-secp256k1-sign-verify.md
├── rsa-sign-verify-examples.md
└── rsa-signatures.md
├── encryption-symmetric-and-asymmetric.md
├── key-agreement-protocols.md
├── key-exchange
├── README.md
├── dhke-examples.md
├── diffie-hellman-key-exchange.md
└── exercises-dhke-key-exchange.md
├── mac-and-key-derivation
├── README.md
├── argon2.md
├── bcrypt.md
├── exercises-calculate-hmac.md
├── exercises-password-encryption.md
├── exercises-scrypt-key-derivation.md
├── hmac-and-key-derivation.md
├── hmac-calculation-examples.md
├── kdf-deriving-key-from-password.md
├── linux-crypt.md
├── modern-key-derivation-functions.md
├── password-encryption.md
├── pbkdf2.md
└── scrypt.md
├── more-cryptographic-concepts
├── README.md
├── digital-certificates-example.md
├── one-time-passwords-otp-example.md
└── tls-example.md
├── preface.md
├── quantum-safe-cryptography
├── README.md
├── quantum-safe-asymmetric-encryption-example.md
├── quantum-safe-key-exchange-example.md
└── quantum-safe-signatures-example.md
├── resources
└── Practical-cryptography-for-developers-book-cover.png
├── secure-random-generators
├── README.md
├── exercises-pseudo-random-generator.md
├── pseudo-random-numbers-examples.md
└── secure-random-generators-csprng.md
├── styles
├── pdf.css
└── website.css
└── symmetric-key-ciphers
├── README.md
├── aes-cipher-concepts.md
├── aes-encrypt-decrypt-examples.md
├── chacha20-poly1305.md
├── cipher-block-modes.md
├── ethereum-wallet-encryption.md
├── exercises-aes-encrypt-decrypt.md
├── exercises-chacha20-poly1305.md
└── popular-symmetric-algorithms.md
/.gitbook/assets/AES-decrypt-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/AES-decrypt-msg.png
--------------------------------------------------------------------------------
/.gitbook/assets/AES-encryption-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/AES-encryption-process.png
--------------------------------------------------------------------------------
/.gitbook/assets/AES-input-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/AES-input-output.png
--------------------------------------------------------------------------------
/.gitbook/assets/Argon2-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Argon2-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/CTR-block-mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/CTR-block-mode.png
--------------------------------------------------------------------------------
/.gitbook/assets/Compare-encryption-decryption-MAC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Compare-encryption-decryption-MAC.png
--------------------------------------------------------------------------------
/.gitbook/assets/Diffie-Hellman-Key-Exchange-Protocol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Diffie-Hellman-Key-Exchange-Protocol.png
--------------------------------------------------------------------------------
/.gitbook/assets/Diffie-Hellman-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Diffie-Hellman-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/ECC-multiply-point-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ECC-multiply-point-example.png
--------------------------------------------------------------------------------
/.gitbook/assets/ECIES.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ECIES.png
--------------------------------------------------------------------------------
/.gitbook/assets/Edwards-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Edwards-curve.png
--------------------------------------------------------------------------------
/.gitbook/assets/GCM-Galois_Counter_Mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/GCM-Galois_Counter_Mode.png
--------------------------------------------------------------------------------
/.gitbook/assets/HMAC-calculation-AES.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/HMAC-calculation-AES.png
--------------------------------------------------------------------------------
/.gitbook/assets/HMAC-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/HMAC-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/HMAC-original-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/HMAC-original-msg.png
--------------------------------------------------------------------------------
/.gitbook/assets/MAC-message-authentication-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/MAC-message-authentication-code.png
--------------------------------------------------------------------------------
/.gitbook/assets/MyEtherWallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/MyEtherWallet.png
--------------------------------------------------------------------------------
/.gitbook/assets/PBKDF2-calculator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/PBKDF2-calculator.png
--------------------------------------------------------------------------------
/.gitbook/assets/Practical-Cryptography-for-Developers-Book-Nakov-front-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Practical-Cryptography-for-Developers-Book-Nakov-front-cover.png
--------------------------------------------------------------------------------
/.gitbook/assets/Scrypt-key-derivation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Scrypt-key-derivation.png
--------------------------------------------------------------------------------
/.gitbook/assets/SoftUni-banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/SoftUni-banner.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/Svetlin-Nakov-photo-face.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/Svetlin-Nakov-photo-face.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/aes-decrypt-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/aes-decrypt-msg.png
--------------------------------------------------------------------------------
/.gitbook/assets/aes-encryption-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/aes-encryption-process.png
--------------------------------------------------------------------------------
/.gitbook/assets/aes-input-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/aes-input-output.png
--------------------------------------------------------------------------------
/.gitbook/assets/aesencryption.net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/aesencryption.net.png
--------------------------------------------------------------------------------
/.gitbook/assets/argon2-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/argon2-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/asymmetric-encryption-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/asymmetric-encryption-diagram.png
--------------------------------------------------------------------------------
/.gitbook/assets/asymmetric-encryption-online-demo-jsencrypt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/asymmetric-encryption-online-demo-jsencrypt.png
--------------------------------------------------------------------------------
/.gitbook/assets/bcrypt-online-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/bcrypt-online-example.png
--------------------------------------------------------------------------------
/.gitbook/assets/bitaddress-entropy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/bitaddress-entropy.png
--------------------------------------------------------------------------------
/.gitbook/assets/bitcoin-elliptic-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/bitcoin-elliptic-curve.png
--------------------------------------------------------------------------------
/.gitbook/assets/checksum-download-openssl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/checksum-download-openssl.png
--------------------------------------------------------------------------------
/.gitbook/assets/compare-encryption-decryption-mac.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/compare-encryption-decryption-mac.png
--------------------------------------------------------------------------------
/.gitbook/assets/crypto-hash-function-examples.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/crypto-hash-function-examples.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/crypto-hash-function.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/crypto-hash-function.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/ctr-block-mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ctr-block-mode.png
--------------------------------------------------------------------------------
/.gitbook/assets/diffie-hellman-key-exchange-protocol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/diffie-hellman-key-exchange-protocol.png
--------------------------------------------------------------------------------
/.gitbook/assets/diffie-hellman-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/diffie-hellman-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/ec-generator-f17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ec-generator-f17.png
--------------------------------------------------------------------------------
/.gitbook/assets/ecc-multiply-point-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ecc-multiply-point-example.png
--------------------------------------------------------------------------------
/.gitbook/assets/ecc-visualization-tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ecc-visualization-tool.png
--------------------------------------------------------------------------------
/.gitbook/assets/ecies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/ecies.png
--------------------------------------------------------------------------------
/.gitbook/assets/edwards-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/edwards-curve.png
--------------------------------------------------------------------------------
/.gitbook/assets/elliptic-curve-general-case.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/elliptic-curve-general-case.png
--------------------------------------------------------------------------------
/.gitbook/assets/elliptic-curve-over-f17-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/elliptic-curve-over-f17-example.png
--------------------------------------------------------------------------------
/.gitbook/assets/elliptic-curve-over-f17-points-per-y-coordinate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/elliptic-curve-over-f17-points-per-y-coordinate.png
--------------------------------------------------------------------------------
/.gitbook/assets/elliptic-curve-subgroups.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/elliptic-curve-subgroups.png
--------------------------------------------------------------------------------
/.gitbook/assets/encrypt-decrypt-live-demo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/encrypt-decrypt-live-demo.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/gcm-galois_counter_mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/gcm-galois_counter_mode.png
--------------------------------------------------------------------------------
/.gitbook/assets/git-commit-logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/git-commit-logs.png
--------------------------------------------------------------------------------
/.gitbook/assets/hash-function.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hash-function.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/hash-functions-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hash-functions-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/hmac-calculation-aes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hmac-calculation-aes.png
--------------------------------------------------------------------------------
/.gitbook/assets/hmac-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hmac-online.png
--------------------------------------------------------------------------------
/.gitbook/assets/hmac-original-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hmac-original-msg.png
--------------------------------------------------------------------------------
/.gitbook/assets/hybrid-decryption (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hybrid-decryption (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/hybrid-decryption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hybrid-decryption.png
--------------------------------------------------------------------------------
/.gitbook/assets/hybrid-encryption (1).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hybrid-encryption (1).png
--------------------------------------------------------------------------------
/.gitbook/assets/hybrid-encryption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/hybrid-encryption.png
--------------------------------------------------------------------------------
/.gitbook/assets/insecure-rnd-python-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/insecure-rnd-python-demo.png
--------------------------------------------------------------------------------
/.gitbook/assets/key-exchange-by-color-mixing-part-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/key-exchange-by-color-mixing-part-1.png
--------------------------------------------------------------------------------
/.gitbook/assets/key-exchange-by-color-mixing-part-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/key-exchange-by-color-mixing-part-2.png
--------------------------------------------------------------------------------
/.gitbook/assets/linux-shadow-encrypted-passwords.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/linux-shadow-encrypted-passwords.png
--------------------------------------------------------------------------------
/.gitbook/assets/mac-message-authentication-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/mac-message-authentication-code.png
--------------------------------------------------------------------------------
/.gitbook/assets/more-cryptographic-concepts-OTP-secret-QR-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/more-cryptographic-concepts-OTP-secret-QR-code.png
--------------------------------------------------------------------------------
/.gitbook/assets/more-cryptographic-concepts-otp-secret-qr-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/more-cryptographic-concepts-otp-secret-qr-code.png
--------------------------------------------------------------------------------
/.gitbook/assets/myetherwallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/myetherwallet.png
--------------------------------------------------------------------------------
/.gitbook/assets/one-time-passwords-otp-example-qr-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/one-time-passwords-otp-example-qr-code.png
--------------------------------------------------------------------------------
/.gitbook/assets/password-kdf-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/password-kdf-key.png
--------------------------------------------------------------------------------
/.gitbook/assets/pbkdf2-calculator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/pbkdf2-calculator.png
--------------------------------------------------------------------------------
/.gitbook/assets/points-on-elliptic-curve-over-finite-field.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/points-on-elliptic-curve-over-finite-field.png
--------------------------------------------------------------------------------
/.gitbook/assets/practical-cryptography-for-developers-book-nakov-front-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/practical-cryptography-for-developers-book-nakov-front-cover.png
--------------------------------------------------------------------------------
/.gitbook/assets/pseudo-random-function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/pseudo-random-function.png
--------------------------------------------------------------------------------
/.gitbook/assets/public-key-cryptography-encrypt-decrypt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/public-key-cryptography-encrypt-decrypt.png
--------------------------------------------------------------------------------
/.gitbook/assets/public-key-cryptography-sign-verify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/public-key-cryptography-sign-verify.png
--------------------------------------------------------------------------------
/.gitbook/assets/scrypt-key-derivation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/scrypt-key-derivation.png
--------------------------------------------------------------------------------
/.gitbook/assets/signature-sign-verify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/signature-sign-verify.png
--------------------------------------------------------------------------------
/.gitbook/assets/softuni-banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/softuni-banner.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/svetlin-nakov-photo-face.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/svetlin-nakov-photo-face.jpg
--------------------------------------------------------------------------------
/.gitbook/assets/symmetric-encryption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/symmetric-encryption.png
--------------------------------------------------------------------------------
/.gitbook/assets/symmetric-key-encryption-decryption.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/.gitbook/assets/symmetric-key-encryption-decryption.gif
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node rules:
2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
3 | .grunt
4 |
5 | ## Dependency directory
6 | ## Commenting this out is preferred by some people, see
7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git
8 | node_modules
9 |
10 | # Book build output
11 | _book
12 |
13 | # eBook build output
14 | *.epub
15 | *.mobi
16 | *.pdf
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Svetlin Nakov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Welcome
2 |
3 | > **Warning**: this book is **not finished**! I am still working on some of the chapters. Once it is completed, I will publish it as PDF and EPUB. Be patient.
4 |
5 | [](https://cryptobook.nakov.com)
6 |
7 | A modern **practical book** about **cryptography for developers** with code examples, covering core concepts like: **hashes** (like SHA-3 and BLAKE2), **MAC codes** (like HMAC and GMAC), **key derivation functions** (like Scrypt, Argon2), **key agreement protocols** (like DHKE, ECDH), **symmetric ciphers** (like AES and ChaCha20, cipher block modes, authenticated encryption, AEAD, AES-GCM, ChaCha20-Poly1305), **asymmetric ciphers** and **public-key cryptosystems** (RSA, ECC, ECIES), **elliptic curve cryptography** (ECC, secp256k1, curve25519), **digital signatures** (ECDSA and EdDSA), **secure random numbers** (PRNG, CSRNG) and **quantum-safe cryptography**, along with crypto **libraries** and developer tools, with a lots of **code examples** in Python and other languages.
8 |
9 | Author: **Svetlin Nakov**, PhD - [https://nakov.com](https://nakov.com)
10 |
11 | Contributors: Milen Stefanov, Marina Shideroff
12 |
13 | Sponsor: **SoftUni** (Software University) - [https://softuni.org](https://softuni.org)
14 |
15 | ISBN: **978-619-00-0870-5** (9786190008705)
16 |
17 | This book is free and open-source, published under the [**MIT license**](https://opensource.org/licenses/MIT).
18 |
19 | Official Web site: [https://cryptobook.nakov.com](https://cryptobook.nakov.com)
20 |
21 | Official **GitHub** repo: [https://github.com/nakov/practical-cryptography-for-developers-book](https://github.com/nakov/practical-cryptography-for-developers-book).
22 |
23 | Sofia, November 2018
24 |
25 | Tags: cryptography, free, book, Nakov, Svetlin Nakov, hashes, hash function, SHA-256, SHA3, BLAKE2, RIPEMD, MAC, message authentication code, HMAC, KDF, key derivation, key derivation function, PBKDF2, Scrypt, Bcrypt, Argon2, password hashing, random generator, pseudo-random numbers, CSPRNG, secure random generator, key exchange, key agreement, Diffie-Hellman, DHKE, ECDH, symmetric ciphers, asymmetric ciphers, public key cryptosystems, symmetric cryptography, AES, Rijndael, cipher block mode, AES-CTR, AES-GCM, ChaCha20-Poly1305, authenticated encryption, encryption scheme, public key cryptography, RSA, ECC, elliptic curves, secp256k1, curve25519, EC points, EC domain parameters, ECDH key agreement, asymmetric encryption scheme, hybrid encryption, ECIES, digital signature, RSA signature, DSA, ECDSA, EdDSA, ElGammal signature, Schnorr signature, quantum-safe cryptography, digital certificates, TLS, OAuth, multi-factor authentication, crypto libraries, Python cryptography, JavaScript cryptography, C# cryptography, Java cryptography, C++ cryptography, PHP cryptography.
26 |
--------------------------------------------------------------------------------
/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Table of contents
2 |
3 | * [Welcome](README.md)
4 | * [Preface](preface.md)
5 | * [Cryptography - Overview](cryptography-overview.md)
6 | * [Hash Functions](cryptographic-hash-functions/README.md)
7 | * [Crypto Hashes and Collisions](cryptographic-hash-functions/crypto-hashes-and-collisions.md)
8 | * [Hash Functions: Applications](cryptographic-hash-functions/hash-functions-applications.md)
9 | * [Secure Hash Algorithms](cryptographic-hash-functions/secure-hash-algorithms.md)
10 | * [Hash Functions - Examples](cryptographic-hash-functions/hash-functions-examples.md)
11 | * [Exercises: Calculate Hashes](cryptographic-hash-functions/exercises-calculate-hashes.md)
12 | * [Proof-of-Work Hash Functions](cryptographic-hash-functions/proof-of-work-hash-functions.md)
13 | * [MAC and Key Derivation](mac-and-key-derivation/README.md)
14 | * [HMAC and Key Derivation](mac-and-key-derivation/hmac-and-key-derivation.md)
15 | * [HMAC Calculation - Examples](mac-and-key-derivation/hmac-calculation-examples.md)
16 | * [Exercises: Calculate HMAC](mac-and-key-derivation/exercises-calculate-hmac.md)
17 | * [KDF: Deriving Key from Password](mac-and-key-derivation/kdf-deriving-key-from-password.md)
18 | * [PBKDF2](mac-and-key-derivation/pbkdf2.md)
19 | * [Modern Key Derivation Functions](mac-and-key-derivation/modern-key-derivation-functions.md)
20 | * [Scrypt](mac-and-key-derivation/scrypt.md)
21 | * [Bcrypt](mac-and-key-derivation/bcrypt.md)
22 | * [Linux crypt\(\)](mac-and-key-derivation/linux-crypt.md)
23 | * [Argon2](mac-and-key-derivation/argon2.md)
24 | * [Secure Password Storage](mac-and-key-derivation/password-encryption.md)
25 | * [Exercises: Password Encryption](mac-and-key-derivation/exercises-password-encryption.md)
26 | * [Secure Random Generators](secure-random-generators/README.md)
27 | * [Pseudo-Random Numbers - Examples](secure-random-generators/pseudo-random-numbers-examples.md)
28 | * [Secure Random Generators \(CSPRNG\)](secure-random-generators/secure-random-generators-csprng.md)
29 | * [Exercises: Pseudo-Random Generator](secure-random-generators/exercises-pseudo-random-generator.md)
30 | * [Key Exchange and DHKE](key-exchange/README.md)
31 | * [Diffie–Hellman Key Exchange](key-exchange/diffie-hellman-key-exchange.md)
32 | * [DHKE - Examples](key-exchange/dhke-examples.md)
33 | * [Exercises: DHKE Key Exchange](key-exchange/exercises-dhke-key-exchange.md)
34 | * [Encryption: Symmetric and Asymmetric](encryption-symmetric-and-asymmetric.md)
35 | * [Symmetric Key Ciphers](symmetric-key-ciphers/README.md)
36 | * [Cipher Block Modes](symmetric-key-ciphers/cipher-block-modes.md)
37 | * [Popular Symmetric Algorithms](symmetric-key-ciphers/popular-symmetric-algorithms.md)
38 | * [The AES Cipher - Concepts](symmetric-key-ciphers/aes-cipher-concepts.md)
39 | * [AES Encrypt / Decrypt - Examples](symmetric-key-ciphers/aes-encrypt-decrypt-examples.md)
40 | * [Ethereum Wallet Encryption](symmetric-key-ciphers/ethereum-wallet-encryption.md)
41 | * [Exercises: AES Encrypt / Decrypt](symmetric-key-ciphers/exercises-aes-encrypt-decrypt.md)
42 | * [ChaCha20-Poly1305](symmetric-key-ciphers/chacha20-poly1305.md)
43 | * [Exercises: ChaCha20-Poly1305](symmetric-key-ciphers/exercises-chacha20-poly1305.md)
44 | * [Asymmetric Key Ciphers](asymmetric-key-ciphers/README.md)
45 | * [The RSA Cryptosystem - Concepts](asymmetric-key-ciphers/the-rsa-cryptosystem-concepts.md)
46 | * [RSA Encrypt / Decrypt - Examples](asymmetric-key-ciphers/rsa-encrypt-decrypt-examples.md)
47 | * [Exercises: RSA Encrypt / Decrypt](asymmetric-key-ciphers/exercises-rsa-encrypt-decrypt.md)
48 | * [Elliptic Curve Cryptography \(ECC\)](asymmetric-key-ciphers/elliptic-curve-cryptography-ecc.md)
49 | * [ECDH Key Exchange](asymmetric-key-ciphers/ecdh-key-exchange.md)
50 | * [ECDH Key Exchange - Examples](asymmetric-key-ciphers/ecdh-key-exchange-examples.md)
51 | * [Exercises: ECDH Key Exchange](asymmetric-key-ciphers/exercises-ecdh-key-exchange.md)
52 | * [ECC Encryption / Decryption](asymmetric-key-ciphers/ecc-encryption-decryption.md)
53 | * [ECIES Hybrid Encryption Scheme](asymmetric-key-ciphers/ecies-public-key-encryption.md)
54 | * [ECIES Encryption - Example](asymmetric-key-ciphers/ecies-example.md)
55 | * [Exercises: ECIES Encrypt / Decrypt](asymmetric-key-ciphers/exercises-ecies-encrypt-decrypt.md)
56 | * [Digital Signatures](digital-signatures/README.md)
57 | * [RSA Signatures](digital-signatures/rsa-signatures.md)
58 | * [RSA: Sign / Verify - Examples](digital-signatures/rsa-sign-verify-examples.md)
59 | * [Exercises: RSA Sign and Verify](digital-signatures/exercises-rsa-sign-and-verify.md)
60 | * [ECDSA: Elliptic Curve Signatures](digital-signatures/ecdsa-sign-verify-messages.md)
61 | * [ECDSA: Sign / Verify - Examples](digital-signatures/ecdsa-sign-verify-examples.md)
62 | * [Exercises: ECDSA Sign and Verify](digital-signatures/exercises-secp256k1-sign-verify.md)
63 | * [EdDSA and Ed25519](digital-signatures/eddsa-and-ed25519.md)
64 | * [EdDSA: Sign / Verify - Examples](digital-signatures/eddsa-sign-verify-examples.md)
65 | * [Exercises: EdDSA Sign and Verify](digital-signatures/exercises-eddsa-sign-and-verify.md)
66 | * [Quantum-Safe Cryptography](quantum-safe-cryptography/README.md)
67 | * [Quantum-Safe Signatures - Example](quantum-safe-cryptography/quantum-safe-signatures-example.md)
68 | * [Quantum-Safe Key Exchange - Example](quantum-safe-cryptography/quantum-safe-key-exchange-example.md)
69 | * [Quantum-Safe Asymmetric Encryption - Example](quantum-safe-cryptography/quantum-safe-asymmetric-encryption-example.md)
70 | * [More Cryptographic Concepts](more-cryptographic-concepts/README.md)
71 | * [Digital Certificates - Example](more-cryptographic-concepts/digital-certificates-example.md)
72 | * [TLS - Example](more-cryptographic-concepts/tls-example.md)
73 | * [One-Time Passwords \(OTP\) - Example](more-cryptographic-concepts/one-time-passwords-otp-example.md)
74 | * [Crypto Libraries for Developers](crypto-libraries-for-developers/README.md)
75 | * [JavaScript Crypto Libraries](crypto-libraries-for-developers/javascript-crypto-libraries.md)
76 | * [Python Crypto Libraries](crypto-libraries-for-developers/python-crypto-libraries.md)
77 | * [C\# Crypto Libraries](crypto-libraries-for-developers/c-crypto-libraries.md)
78 | * [Java Crypto Libraries](crypto-libraries-for-developers/java-crypto-libraries.md)
79 | * [Conclusion](conclusion.md)
80 |
81 |
--------------------------------------------------------------------------------
/assets/AES-decrypt-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/AES-decrypt-msg.png
--------------------------------------------------------------------------------
/assets/AES-encryption-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/AES-encryption-process.png
--------------------------------------------------------------------------------
/assets/AES-input-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/AES-input-output.png
--------------------------------------------------------------------------------
/assets/Argon2-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Argon2-online.png
--------------------------------------------------------------------------------
/assets/CTR-block-mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/CTR-block-mode.png
--------------------------------------------------------------------------------
/assets/Compare-encryption-decryption-MAC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Compare-encryption-decryption-MAC.png
--------------------------------------------------------------------------------
/assets/Diffie-Hellman-Key-Exchange-Protocol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Diffie-Hellman-Key-Exchange-Protocol.png
--------------------------------------------------------------------------------
/assets/Diffie-Hellman-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Diffie-Hellman-online.png
--------------------------------------------------------------------------------
/assets/ECC-multiply-point-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/ECC-multiply-point-example.png
--------------------------------------------------------------------------------
/assets/ECIES.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/ECIES.png
--------------------------------------------------------------------------------
/assets/Edwards-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Edwards-curve.png
--------------------------------------------------------------------------------
/assets/GCM-Galois_Counter_Mode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/GCM-Galois_Counter_Mode.png
--------------------------------------------------------------------------------
/assets/HMAC-calculation-AES.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/HMAC-calculation-AES.png
--------------------------------------------------------------------------------
/assets/HMAC-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/HMAC-online.png
--------------------------------------------------------------------------------
/assets/HMAC-original-msg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/HMAC-original-msg.png
--------------------------------------------------------------------------------
/assets/MAC-message-authentication-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/MAC-message-authentication-code.png
--------------------------------------------------------------------------------
/assets/MyEtherWallet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/MyEtherWallet.png
--------------------------------------------------------------------------------
/assets/PBKDF2-calculator.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/PBKDF2-calculator.png
--------------------------------------------------------------------------------
/assets/Practical-Cryptography-for-Developers-Book-Nakov-front-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Practical-Cryptography-for-Developers-Book-Nakov-front-cover.png
--------------------------------------------------------------------------------
/assets/Scrypt-key-derivation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Scrypt-key-derivation.png
--------------------------------------------------------------------------------
/assets/SoftUni-banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/SoftUni-banner.jpg
--------------------------------------------------------------------------------
/assets/Svetlin-Nakov-photo-face.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/Svetlin-Nakov-photo-face.jpg
--------------------------------------------------------------------------------
/assets/aesencryption.net.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/aesencryption.net.png
--------------------------------------------------------------------------------
/assets/asymmetric-encryption-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/asymmetric-encryption-diagram.png
--------------------------------------------------------------------------------
/assets/asymmetric-encryption-online-demo-jsencrypt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/asymmetric-encryption-online-demo-jsencrypt.png
--------------------------------------------------------------------------------
/assets/bcrypt-online-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/bcrypt-online-example.png
--------------------------------------------------------------------------------
/assets/bitaddress-entropy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/bitaddress-entropy.png
--------------------------------------------------------------------------------
/assets/bitcoin-elliptic-curve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/bitcoin-elliptic-curve.png
--------------------------------------------------------------------------------
/assets/checksum-download-openssl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/checksum-download-openssl.png
--------------------------------------------------------------------------------
/assets/crypto-hash-function-examples.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/crypto-hash-function-examples.jpg
--------------------------------------------------------------------------------
/assets/crypto-hash-function.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/crypto-hash-function.jpg
--------------------------------------------------------------------------------
/assets/ec-generator-f17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/ec-generator-f17.png
--------------------------------------------------------------------------------
/assets/ecc-visualization-tool.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/ecc-visualization-tool.png
--------------------------------------------------------------------------------
/assets/elliptic-curve-general-case.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/elliptic-curve-general-case.png
--------------------------------------------------------------------------------
/assets/elliptic-curve-over-f17-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/elliptic-curve-over-f17-example.png
--------------------------------------------------------------------------------
/assets/elliptic-curve-over-f17-points-per-y-coordinate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/elliptic-curve-over-f17-points-per-y-coordinate.png
--------------------------------------------------------------------------------
/assets/elliptic-curve-subgroups.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/elliptic-curve-subgroups.png
--------------------------------------------------------------------------------
/assets/encrypt-decrypt-live-demo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/encrypt-decrypt-live-demo.jpg
--------------------------------------------------------------------------------
/assets/git-commit-logs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/git-commit-logs.png
--------------------------------------------------------------------------------
/assets/hash-function.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/hash-function.jpg
--------------------------------------------------------------------------------
/assets/hash-functions-online.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/hash-functions-online.png
--------------------------------------------------------------------------------
/assets/hybrid-decryption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/hybrid-decryption.png
--------------------------------------------------------------------------------
/assets/hybrid-encryption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/hybrid-encryption.png
--------------------------------------------------------------------------------
/assets/insecure-rnd-python-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/insecure-rnd-python-demo.png
--------------------------------------------------------------------------------
/assets/js/repl.it-code-runner.js:
--------------------------------------------------------------------------------
1 | gitbook.events.bind("page.change", function() {
2 | let runCodeLinks = $("p:contains('Run the above code example:') a");
3 | for (let link of runCodeLinks) {
4 | if (typeof(link.href) == "string" && link.href.startsWith("https://repl.it/")) {
5 | // A repl.it link is found --> check for code box above it
6 | let codeBox = $(link).parent().prev();
7 | if (codeBox.is("pre")) {
8 | // A code box is found just before the code link --> inject the [Run] button
9 | let runButton = $("Run");
10 | let loadingBox = $("Loading …");
11 | runButton.click(function() {
12 | // Replace the code box with the embedded REPL box
13 | loadingBox.show();
14 | let replBox = $('');
15 | replBox.attr("src", link.href + "?lite=true");
16 | replBox.on("load", function(event) {
17 | loadingBox.hide();
18 | });
19 | if (codeBox.next().is("iframe")) {
20 | // We have already the iframe with the Repl.it -> first remove it
21 | codeBox.next().remove();
22 | }
23 | codeBox.after(replBox);
24 | return false;
25 | });
26 | codeBox.prepend(runButton);
27 | codeBox.prepend(loadingBox);
28 |
29 | // Delete the original REPL hyperlink from the DOM
30 | $(link).parent().remove();
31 | }
32 | }
33 | }
34 | });
35 |
36 | // Sample usage: put the below text in your Markdown book source code:
37 | // Run the above code example: [https://repl.it/@nakov/Scrypt](https://repl.it/@nakov/Scrypt).
38 |
--------------------------------------------------------------------------------
/assets/key-exchange-by-color-mixing-part-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/key-exchange-by-color-mixing-part-1.png
--------------------------------------------------------------------------------
/assets/key-exchange-by-color-mixing-part-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/key-exchange-by-color-mixing-part-2.png
--------------------------------------------------------------------------------
/assets/linux-shadow-encrypted-passwords.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/linux-shadow-encrypted-passwords.png
--------------------------------------------------------------------------------
/assets/more-cryptographic-concepts-OTP-secret-QR-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/more-cryptographic-concepts-OTP-secret-QR-code.png
--------------------------------------------------------------------------------
/assets/one-time-passwords-otp-example-qr-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/one-time-passwords-otp-example-qr-code.png
--------------------------------------------------------------------------------
/assets/password-kdf-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/password-kdf-key.png
--------------------------------------------------------------------------------
/assets/points-on-elliptic-curve-over-finite-field.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/points-on-elliptic-curve-over-finite-field.png
--------------------------------------------------------------------------------
/assets/pseudo-random-function.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/pseudo-random-function.png
--------------------------------------------------------------------------------
/assets/public-key-cryptography-encrypt-decrypt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/public-key-cryptography-encrypt-decrypt.png
--------------------------------------------------------------------------------
/assets/public-key-cryptography-sign-verify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/public-key-cryptography-sign-verify.png
--------------------------------------------------------------------------------
/assets/signature-sign-verify.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/signature-sign-verify.png
--------------------------------------------------------------------------------
/assets/symmetric-encryption.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/symmetric-encryption.png
--------------------------------------------------------------------------------
/assets/symmetric-key-encryption-decryption.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/assets/symmetric-key-encryption-decryption.gif
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/ecc-encrypt-decrypt-examples.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/asymmetric-key-ciphers/ecc-encrypt-decrypt-examples.md
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/ecdh-key-exchange-examples.md:
--------------------------------------------------------------------------------
1 | # ECDH Key Exchange - Examples
2 |
3 | Now let's implement the **ECDH** algorithm (Elliptic Curve Diffie–Hellman Key Exchange) in Python.
4 |
5 | We shall use the `tinyec` library for ECC in Python:
6 |
7 | ```python
8 | pip install tinyec
9 | ```
10 |
11 | Now, let's generate two public-private **key pairs**, exchange the **public keys** and calculate the **shared secret**:
12 |
13 | ```python
14 | from tinyec import registry
15 | import secrets
16 |
17 | def compress(pubKey):
18 | return hex(pubKey.x) + hex(pubKey.y % 2)[2:]
19 |
20 | curve = registry.get_curve('brainpoolP256r1')
21 |
22 | alicePrivKey = secrets.randbelow(curve.field.n)
23 | alicePubKey = alicePrivKey * curve.g
24 | print("Alice public key:", compress(alicePubKey))
25 |
26 | bobPrivKey = secrets.randbelow(curve.field.n)
27 | bobPubKey = bobPrivKey * curve.g
28 | print("Bob public key:", compress(bobPubKey))
29 |
30 | print("Now exchange the public keys (e.g. through Internet)")
31 |
32 | aliceSharedKey = alicePrivKey * bobPubKey
33 | print("Alice shared key:", compress(aliceSharedKey))
34 |
35 | bobSharedKey = bobPrivKey * alicePubKey
36 | print("Bob shared key:", compress(bobSharedKey))
37 |
38 | print("Equal shared keys:", aliceSharedKey == bobSharedKey)
39 | ```
40 |
41 | Run the above code example: [https://repl.it/@nakov/ECDH-Key-Exchange-in-Python](https://repl.it/@nakov/ECDH-Key-Exchange-in-Python).
42 |
43 | The **elliptic curve** used for the ECDH calculations is **256-bit** named curve `brainpoolP256r1`. The **private keys** are **256-bit** (64 hex digits) and are generated randomly. The **public keys** will be **257 bits** (65 hex digits), due to **key compression**.
44 |
45 | The **output** of the above code looks like this:
46 |
47 | ```
48 | Alice public key: 0x66c808e6b5be6d6620934bc6ffa2b8b47f9786c002bfb06d53a0c27535641a5d1
49 | Bob public key: 0x7d15195432d1ac7f38aeb054d07d9b2e1faa913b78ad04d5efdd4a1ee8d9a3191
50 | Now exchange the public keys (e.g. through Internet)
51 | Alice shared key: 0x90f5a1cf2ed1dbb0322178df6bb0dd72c541884618b2989a3e5e663198667a621
52 | Bob shared key: 0x90f5a1cf2ed1dbb0322178df6bb0dd72c541884618b2989a3e5e663198667a621
53 | Equal shared keys: True
54 | ```
55 |
56 | Due to randomization, if you run the above code, the **keys will be different**, but the calculated **shared secret** for Alice and Bob at the end will always be **the same**. The generated **shared secret** is a **257-bit** integer (compressed EC point for 256-bit curve, encoded as 65 hex digits).
57 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/ecdh-key-exchange.md:
--------------------------------------------------------------------------------
1 | # ECDH Key Exchange
2 |
3 | The [**ECDH**](https://en.wikipedia.org/wiki/Elliptic-curve\_Diffie%E2%80%93Hellman) (Elliptic Curve Diffie–Hellman Key Exchange) is **anonymous key agreement scheme**, which allows two parties, each having an elliptic-curve public–private key pair, to establish a **shared secret** over an insecure channel. **ECDH** is very similar to the classical **DHKE** (Diffie–Hellman Key Exchange) algorithm, but it uses **ECC point multiplication** instead of **modular exponentiations**. ECDH is based on the following property of EC points:
4 |
5 | * (_**a**_ \* **G**) \* _**b**_ = (_**b**_ \* **G**) \* _**a**_
6 |
7 | If we have two **secret numbers** _**a**_ and _**b**_ (two **private keys**, belonging to Alice and Bob) and an ECC elliptic curve with generator point **G**, we can exchange over an insecure channel the values (_**a**_ \* **G**) and (_**b**_ \* **G**) (the **public keys** of Alice and Bob) and then we can derive a shared secret: _**secret**_ = (_**a**_ \* **G**) \* _**b**_ = (_**b**_ \* **G**) \* _**a**_. Pretty simple. The above equation takes the following form:
8 |
9 | * alicePubKey \* bobPrivKey = bobPubKey \* alicePrivKey = _**secret**_
10 |
11 | The **ECDH** algorithm (Elliptic Curve Diffie–Hellman Key Exchange) is trivial:
12 |
13 | 1. **Alice** generates a **random** ECC key pair: {**alicePrivKey**, **alicePubKey** = alicePrivKey \* G}
14 | 2. **Bob** generates a **random** ECC key pair: {**bobPrivKey**, **bobPubKey** = bobPrivKey \* G}
15 | 3. Alice and Bob **exchange their public keys** through the insecure channel (e.g. over Internet)
16 | 4. **Alice** calculates **sharedKey** = bobPubKey \* alicePrivKey
17 | 5. **Bob** calculates **sharedKey** = alicePubKey \* bobPrivKey
18 | 6. Now both **Alice** and **Bob** have the same **sharedKey** == bobPubKey \* alicePrivKey == alicePubKey \* bobPrivKey
19 |
20 | In the next section, we shall implement the ECDH algorithm and demonstrate it with code example.
21 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/ecies-example.md:
--------------------------------------------------------------------------------
1 | # ECIES Encryption - Example
2 |
3 | Now, let's demonstrate how the **ECIES encryption scheme** works in practice in **Python**. We shall use a Python library [`eciespy`](https://kigawas.me/eciespy/):
4 |
5 | ```python
6 | pip install eciespy
7 | ```
8 |
9 | A sample Python code to generate public / private **key pair** and **encrypt** and **decrypt** a message using ECIES is:
10 |
11 | ```python
12 | from ecies.utils import generate_eth_key
13 | from ecies import encrypt, decrypt
14 | import binascii
15 |
16 | privKey = generate_eth_key()
17 | privKeyHex = privKey.to_hex()
18 | pubKeyHex = privKey.public_key.to_hex()
19 | print("Encryption public key:", pubKeyHex)
20 | print("Decryption private key:", privKeyHex)
21 |
22 | plaintext = b'Some plaintext for encryption'
23 | print("Plaintext:", plaintext)
24 |
25 | encrypted = encrypt(pubKeyHex, plaintext)
26 | print("Encrypted:", binascii.hexlify(encrypted))
27 |
28 | decrypted = decrypt(privKeyHex, encrypted)
29 | print("Decrypted:", decrypted)
30 | ```
31 |
32 | Run the above code example: [https://repl.it/@nakov/ECIES-in-Python](https://repl.it/@nakov/ECIES-in-Python).
33 |
34 | The above code is pretty simple: just generate ECC **public + private key pair** using `ecies.utils.generate_eth_key()` and call the `ecies.encrypt(pubKey, msg)` and `decrypt(privKey, encryptedMsg)` functions from the `eciespy` library.
35 |
36 | The **output** form the above code looks like this:
37 |
38 | ```
39 | Encryption public key: 0x0dc8e06c055b45ecf110258ed5c0261ce2019b1bd0f8f226dcd010dade448b8f304a0915c68cdf7ddded8e4021d28fb92e27d08df695f48a0d2c41ddee750fc7
40 | Decryption private key: 0x487fd8b53c471e3c38484a0fbe4751ace67a9ed28e60ea6b0b44c445b881f99d
41 | Plaintext: b'Some plaintext for encryption'
42 | Encrypted: b'045699078bbd101e270572d0d68e87a8f7b6cc377ebeeffb60d2fcac5dc7bdd86a26d7f79d13b92e923a0e2cdbe418a7856b27157ef150d5c72f4f8f312467d13221ebe7049b7ed2f0ed253bce13117129a7b01bb881b8dfbf004ff11f3ebed4c732744bc49ea03230c2d1b2ec80774e79c075431d2019464d3de97ceb96'
43 | Decrypted: b'Some plaintext for encryption'
44 | ```
45 |
46 | The Python `eciespy` library internally uses **ECC** cryptography over the **secp256k1** curve + **AES-256-GCM** authenticated encryption. Note that the above encrypted message holds together 4 values: `{cipherPubKey, AES-nonce, authTag, AES-ciphertext}`, packed in binary form and not directly visible from the above output.
47 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/ecies-public-key-encryption.md:
--------------------------------------------------------------------------------
1 | # ECIES Hybrid Encryption Scheme
2 |
3 | A hybrid encryption scheme similar to the previously demonstrated code is standardized under the name **Elliptic Curve Integrated Encryption Scheme** (**ECIES**) in many crypto standards like [SECG SEC-1](http://www.secg.org/sec1-v2.pdf), [ISO/IEC 18033-2](https://www.shoup.net/iso/std4.pdf), [IEEE 1363a](http://grouper.ieee.org/groups/1722/contributions/2012/1722a-butterworth-ieee1363.pdf) and [ANSI X9.63](ftp://ftp.iks-jena.de/mitarb/lutz/standards/ansi/X9/x963-7-5-98.pdf). **ECIES** is a public-key authenticated encryption scheme, which works similarly to the above code examples, but uses a **KDF** (key-derivation function) for deriving separate **MAC key** and symmetric **encryption key** from the ECDH shared secret. It has many variants.
4 |
5 | The **ECIES standard** combines ECC-based **asymmetric cryptography** with **symmetric ciphers** to provide data encryption by EC private key and decryption by the corresponding EC public key. The **ECIES** encryption scheme uses **ECC** cryptography (public key cryptosystem) + key-derivation function (**KDF**) + **symmetric encryption** algorithm + **MAC** algorithm, combined together like it is shown on the figure below:
6 |
7 | 
8 |
9 | The input of the **ECIES encryption** consists of recipient's **public key** + **plain text message**. The output consists of sender's ephemeral public key (**ciphertext public key**) + **encrypted message** (ciphertext + symmetric algorithm parameters) + **authentication tag** (MAC code):
10 |
11 | * `ECIES-encrypt(recipientPublicKey, plaintextMessage)` ➔ `{ cipherTextPublicKey, encryptedMessage, authTag }`
12 |
13 | The **ECIES decryption** takes the output from the encryption + the **recipient's private key** and produces the original plaintext message or detects a problem (e.g. integrity / authentication error):
14 |
15 | * `ECIES-decrypt(cipherTextPublicKey, encryptedMessage, authTag, recipientPrivateKey, )` ➔ `plaintextMessage`
16 |
17 | The ECIES encryption scheme is a **framework**, not a concrete algorithm. It can be implemented by plugging different algorithms, e.g. the **secp256k1** or **P-521** elliptic curve for the public-key calculations + **PBKDF2** or **Scrypt** for KDF function + **AES-CTR** or **AES-GCM** or **ChaCha20-Poly1305** for symmetric cipher and authentication tag + **HMAC-SHA512** for MAC algorithm (in case of unauthenticated encryption).
18 |
19 | In the next section we shall demonstrate through a **code example** how to use ECIES in practice.
20 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/exercises-ecdh-key-exchange.md:
--------------------------------------------------------------------------------
1 | # Exercises: ECDH Key Exchange
2 |
3 | ...
4 |
5 | TODO
6 |
7 | ...
8 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/exercises-ecies-encrypt-decrypt.md:
--------------------------------------------------------------------------------
1 | # Exercises: ECIES Encrypt / Decrypt
2 |
3 | Write a program to **encrypt** / **decrypt** a **message** by public / private key using [**ECIES**](https://en.wikipedia.org/wiki/Integrated\_Encryption\_Scheme) (Elliptic Curve Integrated Encryption Scheme). The **encryption** will require an EC **public key** and **decryption** will require the corresponding EC **private key**. Internally, use ECC cryptography based on a **256-bit elliptic curve** by choice (e.g. `brainpoolP256t1`) and **symmetric encryption** by choice (e.g. AES-256-CTR + MAC, AES-128-GCM or ChaCha20-Poly1305), along with **key-derivation function** by choice (e.g. PBKDF2).
4 |
5 | You are free to choose between writing your **own ECIES implementation**, following the [SECG-SEC-1](http://www.secg.org/sec1-v2.pdf) standard or use a **standard ECIES library** for your language, e.g.
6 |
7 | * Python: [https://pypi.org/project/eciespy](https://pypi.org/project/eciespy/)
8 | * JavaScript: [https://github.com/bitchan/eccrypto](https://github.com/bitchan/eccrypto)
9 | * C#: [https://github.com/VirgilSecurity/virgil-sdk-crypto-net](https://github.com/VirgilSecurity/virgil-sdk-crypto-net)
10 | * Java: [https://github.com/Arryboom/smartbox-ecies-java](https://github.com/Arryboom/smartbox-ecies-java)
11 | * C, C++, PHP, Perl: [https://github.com/jedisct1/libsodium](https://github.com/jedisct1/libsodium)
12 |
13 | ## ECIES Encryption
14 |
15 | Write a program to **encrypt a message** using the **ECIES** hybrid encryption scheme and a **256-bit ECC public key** (2 \* 256 bits).
16 |
17 | * The **input** consists of the **public key in hex** (at the first line, uncompressed, 128 hex digits) + **plaintext message** for encryption (at the second line).
18 | * The **output** is the **hex-encoded encrypted message**. It may hold the ECC ciphertext public key + the ciphertext + MAC code + the symmetric key algorithm parameters, but this depends very much on the underlying algorithms and implementation.
19 |
20 | **Sample input:**
21 |
22 | ```
23 | 552e2b308514b38e4989d71ed263e0af6376f65ba81a94ebb74f6fadc223ee80aa8fb710cfb445e0871cd1c1a0c1f2adb2b6eedc2a0470b04244548c5be518c8
24 | Sample text for ECIES encryption.
25 | ```
26 |
27 | **Sample output:**
28 |
29 | It will be different for each program execution due to the randomness in the encryption scheme:
30 |
31 | ```
32 | 0442e2fba3fddba1ba9207f3276e141809782dc72529523aa1fcf35b15c4c22a9333ddacd7d64de4abd0a36138d430c50be7a98d5512cb8c2fe36ca45a0bbd7927c150ae3637c45093207531ce75e3841d4808ced85e82305d8da891708c20479388f6d4a7cde213bb36bf860c5df0077358a942eeb9a4c23e89bcc11f11
33 | ```
34 |
35 | ## ECIES Decryption
36 |
37 | Write a program to **decrypt an encrypted message** created by the program from the previous example, using the **ECIES** hybrid encryption scheme and a **256-bit ECC private key**.
38 |
39 | * The **input** consists of the **private key in hex** (at the first line, 64 hex digits) + **encrypted message** for decryption (at the second line).
40 | * The **output** is the **decrypted plaintext message**. In case or **decryption problem** (e.g. incorrect decryption key or broken encrypted message), display `Error: cannot decrypt the message`.
41 |
42 | **Sample input:**
43 |
44 | ```
45 | 27f07d3251dee39ec2c5ff800641f4d839e6f8065033e9a710ea2e519473bdd7
46 | 0442e2fba3fddba1ba9207f3276e141809782dc72529523aa1fcf35b15c4c22a9333ddacd7d64de4abd0a36138d430c50be7a98d5512cb8c2fe36ca45a0bbd7927c150ae3637c45093207531ce75e3841d4808ced85e82305d8da891708c20479388f6d4a7cde213bb36bf860c5df0077358a942eeb9a4c23e89bcc11f11
47 | ```
48 |
49 | **Sample output:**
50 |
51 | ```
52 | Sample text for ECIES encryption.
53 | ```
54 |
55 | **Sample input:**
56 |
57 | This example holds an incorrect decryption private key:
58 |
59 | ```
60 | 9ab686c269b2c58f0fca699dde09cf24e23353e56bd60095d681b23709cb0dc3
61 | 0442e2fba3fddba1ba9207f3276e141809782dc72529523aa1fcf35b15c4c22a9333ddacd7d64de4abd0a36138d430c50be7a98d5512cb8c2fe36ca45a0bbd7927c150ae3637c45093207531ce75e3841d4808ced85e82305d8da891708c20479388f6d4a7cde213bb36bf860c5df0077358a942eeb9a4c23e89bcc11f11
62 | ```
63 |
64 | **Sample output:**
65 |
66 | ```
67 | Error: cannot decrypt the message
68 | ```
69 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/exercises-rsa-encrypt-decrypt.md:
--------------------------------------------------------------------------------
1 | # Exercises: RSA Encrypt / Decrypt
2 |
3 | In this exercise you shall **encrypt** and **decrypt** messages using the **RSA** public-key cryptosystem.
4 |
5 | ## Encrypt Message with RSA-OAEP
6 |
7 | You are given a **text message** and a **RSA public key** (in PEM format). Write a program to **encrypt the message**, using the [**RSA-OAEP**](https://en.wikipedia.org/wiki/Optimal\_asymmetric\_encryption\_padding) encryption scheme (RSA + PKCS#1 OAEP padding).
8 |
9 | **Input**:
10 |
11 | * First line: the input **message**
12 | * Next few lines: the **RSA public key** (in the [PKCS#8](https://en.wikipedia.org/wiki/PKCS\_8) [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced\_Mail) [ASN.1](https://en.wikipedia.org/wiki/Abstract\_Syntax\_Notation\_One) format)
13 | * The public key length can be 512 bits, 1024 bits, 2048 bits, 3072 bits or 4096 bits.
14 |
15 | **Output**:
16 |
17 | * The **encrypted message**, printed as **hex** string.
18 |
19 | Write your code in programming language of choice.
20 |
21 | **Sample input**:
22 |
23 | ```
24 | Secret message
25 | -----BEGIN PUBLIC KEY-----
26 | MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMYhCcGpfoebriBbFaUMMwH3B5t7udir
27 | ODJehnQTPlWLf9SVfQdx0v9ATJ2Rs5kQjdJ/wZYunMBVq6/FhgPZexsCAwEAAQ==
28 | -----END PUBLIC KEY-----
29 | ```
30 |
31 | The above input uses a **512-bit RSA public key** and a small plain text message, that can fit inside the key length (after the OAEP padding).
32 |
33 | **Sample output** (for the above input):
34 |
35 | ```
36 | 218dd78c5e14b4d58efd10575b521db46c0caa5c699134abf18bbeeac170cfe446e25d0d82257082539e4ccd3e0aa8bffc1b07d2bde9e635a7b9b7fc6cf4c266
37 | ```
38 |
39 | Note: the above output should be **different at each execution** due to the randomness injected by the OAEP padding algorithm.
40 |
41 | ## Decrypt a Message with RSA-OAEP
42 |
43 | You are given a RSA-OAEP-encrypted ciphertext (as hex string) and a **RSA private key** (in PEM format). Write a program to **decrypt the message**, using the [**RSA-OAEP**](https://en.wikipedia.org/wiki/Optimal\_asymmetric\_encryption\_padding) encryption scheme (RSA + PKCS#1 OAEP padding).
44 |
45 | **Input**:
46 |
47 | * First line: the **ciphertext** (the encrypted message), given as **hex** string
48 | * Next few lines: the **RSA private key** (in the [PKCS#8](https://en.wikipedia.org/wiki/PKCS\_8) [PEM](https://en.wikipedia.org/wiki/Privacy-Enhanced\_Mail) [ASN.1](https://en.wikipedia.org/wiki/Abstract\_Syntax\_Notation\_One) format)
49 |
50 | **Output**:
51 |
52 | * Print the **decrypted message** as plain text
53 | * Print `Decryption failed!` in case of problem
54 |
55 | Write your code in programming language of choice.
56 |
57 | **Sample input**:
58 |
59 | ```
60 | 218dd78c5e14b4d58efd10575b521db46c0caa5c699134abf18bbeeac170cfe446e25d0d82257082539e4ccd3e0aa8bffc1b07d2bde9e635a7b9b7fc6cf4c266
61 | -----BEGIN RSA PRIVATE KEY-----
62 | MIIBOgIBAAJBAMYhCcGpfoebriBbFaUMMwH3B5t7udirODJehnQTPlWLf9SVfQdx
63 | 0v9ATJ2Rs5kQjdJ/wZYunMBVq6/FhgPZexsCAwEAAQJAbNSzBkTzMswqHq3Juupz
64 | jk3CSP7ye/i5Grnfgx0a7WOGpVrEDQNo0iihEf5pRAfaazEdfJX2Tj+auuv06392
65 | kQIhAOeJahRwOt8cYroLZzHHf7LWQglRaTbtKShqmbLdBZMzAiEA2xADyA3xGXcl
66 | txN0DOfSycwFyqkdlfsuyAwKibPteHkCIQDJ1P6UzHR1UwA434HYYejOU3mDN+V4
67 | zOoI4kwTIBohAwIgLrqv09EFiUUdSnxf2RDqqhlXcu+4W/IE/K904AL9uSECICeT
68 | tkAnJHB7k6fvox6ErJV53w06bUF1jGw8yHuaCcHX
69 | -----END RSA PRIVATE KEY-----
70 | ```
71 |
72 | The above input uses a **512-bit RSA private key** and an encrypted **ciphertext** of the same length.
73 |
74 | **Sample output** (for the above input):
75 |
76 | ```
77 | Secret message
78 | ```
79 |
80 | Another **sample input** (wrong 512-bit private key):
81 |
82 | ```
83 | 218dd78c5e14b4d58efd10575b521db46c0caa5c699134abf18bbeeac170cfe446e25d0d82257082539e4ccd3e0aa8bffc1b07d2bde9e635a7b9b7fc6cf4c266
84 | -----BEGIN RSA PRIVATE KEY-----
85 | MIIBOQIBAAJBAJd0kbrC4AxpcqBgWVPpb8IoI/kdQkF1twrfQtoMkHgB71vpY6Sg
86 | 68CUA7Ejq/dbAHlvFdXqwEK9vXH3kFpc8pcCAwEAAQJAaFrlXm2Pun2dgWthoTOi
87 | 0YCe6LKESF43dMJIab1mfYiltrSpGaoTXLvHR+NaAgqcr9KAH24Mi05ttUBcWRsI
88 | QQIhAOLTSyeDZnq5rqdwBlU8p6USpeImRhWRNcCHA/QLxcaPAiEAqu+O1p1YB3Mp
89 | GKgB9PvZE3TZqmlgtEFmSMYinF3g13kCIF9FjpCXMYkkysZLWG2e32+HaKOXneJb
90 | Lq+iRjfQZg7jAiBcm6D1YRV6I8gWFZ/JzFBVHC95BdJgljYGI2JI+QuBcQIgLJjH
91 | IPctSCUtukz+7fdeOdw/0FINcUGvnQyuEK34UxE=
92 | -----END RSA PRIVATE KEY-----
93 | ```
94 |
95 | The corresponding **output** should be:
96 |
97 | ```
98 | Decryption failed!
99 | ```
100 |
101 | Note that the **RSA-OAEP** padding algorithm has built-in checksum, which allows to detect incorrect decryption attempts, but it is not an authenticated encryption scheme.
102 |
103 | ## \* Implement Hybrid Encryption / Decryption with RSA-KEM
104 |
105 | Write a program to **encrypt** a large message (bigger than the RSA key length, e.g. a PDF document) using the **RSA-KEM** hybrid encryption scheme with **AES** symmetric encryption (use block mode of choice, e.g. **GCM** or **CTR**).
106 |
107 | **Hint**:
108 |
109 | * Check this example first: [https://github.com/digitalbazaar/forge#rsakem](https://github.com/digitalbazaar/forge#rsakem).
110 | * Note that in some languages it is hard to find and **RSA-KEM** implementation, so you can skip this exercise or use another **hybrid encryption scheme** (e.g. RSA + AES + HMAC).
111 |
112 | **Input**:
113 |
114 | * The **message** for encryption
115 | * RSA **public key** (in PEM format)
116 |
117 | **Output**:
118 |
119 | * The encrypted **ciphertext** (hex string)
120 | * The random **IV** salt for the AES cipher (hex string)
121 | * The authentication **tag** / **MAC** for the encrypted message (hex string)
122 | * The **encapsulated secret key** for the AES algorithm (hex string)
123 |
124 | Write a program to **decrypt** given encrypted message, produced by the previous exercise, using the **RSA-KEM** hybrid encryption scheme with **AES** symmetric encryption (use block mode of choice, e.g. **GCM** or **CTR**).
125 |
126 | **Input**:
127 |
128 | * The encrypted **ciphertext** (hex string)
129 | * The random **IV** salt for the AES cipher (hex string)
130 | * The authentication **tag** / **MAC** for the encrypted message (hex string)
131 | * The **encapsulated secret key** for the AES algorithm (hex string)
132 |
133 | **Output**:
134 |
135 | * The decrypted original plaintext **message**
136 | * Print `Decryption failed!` if the message decryption is not successful (e.g. wrong password)
137 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/rsa-encrypt-decrypt-examples.md:
--------------------------------------------------------------------------------
1 | # RSA Encrypt / Decrypt - Examples
2 |
3 | Now let's demonstrate how the RSA algorithms works by a simple **example in Python**. The below code will generate **random RSA key-pair**, will **encrypt** a short message and will **decrypt** it back to its original form, using the [**RSA-OAEP**](https://en.wikipedia.org/wiki/Optimal\_asymmetric\_encryption\_padding) padding scheme.
4 |
5 | First, install the `pycryptodome` package, which is a powerful Python library of low-level cryptographic primitives (hashes, MAC codes, key-derivation, symmetric and asymmetric ciphers, digital signatures):
6 |
7 | ```
8 | pip install pycryptodome
9 | ```
10 |
11 | ## RSA Key Generation
12 |
13 | Now, let's write the Python code. First, **generate the RSA keys** (1024-bit) and print them on the console (as hex numbers and in the PKCS#8 PEM ASN.1 format):
14 |
15 | ```python
16 | from Crypto.PublicKey import RSA
17 | from Crypto.Cipher import PKCS1_OAEP
18 | import binascii
19 |
20 | keyPair = RSA.generate(3072)
21 |
22 | pubKey = keyPair.publickey()
23 | print(f"Public key: (n={hex(pubKey.n)}, e={hex(pubKey.e)})")
24 | pubKeyPEM = pubKey.exportKey()
25 | print(pubKeyPEM.decode('ascii'))
26 |
27 | print(f"Private key: (n={hex(pubKey.n)}, d={hex(keyPair.d)})")
28 | privKeyPEM = keyPair.exportKey()
29 | print(privKeyPEM.decode('ascii'))
30 | ```
31 |
32 | Run the above code example: [https://repl.it/@nakov/RSA-Key-Generation-in-Python](https://repl.it/@nakov/RSA-Key-Generation-in-Python).
33 |
34 | We use short key length to keep the sample input short, but in a real world scenario it is recommended to use 3072-bit or 4096-bit keys.
35 |
36 | ## RSA Encryption
37 |
38 | Next, **encrypt the message** using **RSA-OAEP** encryption scheme (RSA with PKCS#1 OAEP padding) with the RSA **public key**:
39 |
40 | ```python
41 | msg = b'A message for encryption'
42 | encryptor = PKCS1_OAEP.new(pubKey)
43 | encrypted = encryptor.encrypt(msg)
44 | print("Encrypted:", binascii.hexlify(encrypted))
45 | ```
46 |
47 | Run the above code example: [https://repl.it/@nakov/RSA-encryption-in-Python](https://repl.it/@nakov/RSA-encryption-in-Python).
48 |
49 | ## RSA Decryption
50 |
51 | ## Finally, **decrypt the message** using using **RSA-OAEP** with the RSA **private key**:
52 |
53 | ```python
54 | decryptor = PKCS1_OAEP.new(keyPair)
55 | decrypted = decryptor.decrypt(encrypted)
56 | print('Decrypted:', decrypted)
57 | ```
58 |
59 | Run the above code example: [https://repl.it/@nakov/RSA-decryption-in-Python](https://repl.it/@nakov/RSA-decryption-in-Python).
60 |
61 | ## Sample Output
62 |
63 | A **sample output** of the code execution for the entire example is given below:
64 |
65 | ```
66 | Public key: (n=0x9a11485bccb9569410a848fb1afdf2a81b17c1fa9f9eb546fd1deb873b49b693a4edf20eb8362c085cd5b28ba109dbad2bd257a013f57f745402e245b0cc2d553c7b2b8dbba57ebda7f84cfb32b7d9c254f03dbd0188e4b8e40c47b64c1bd2572834b936ffc3da9953657ef8bee80c49c2c12933c8a34804a00eb4c81248e01f, e=0x10001)
67 | -----BEGIN PUBLIC KEY-----
68 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCaEUhbzLlWlBCoSPsa/fKoGxfB
69 | +p+etUb9HeuHO0m2k6Tt8g64NiwIXNWyi6EJ260r0legE/V/dFQC4kWwzC1VPHsr
70 | jbulfr2n+Ez7MrfZwlTwPb0BiOS45AxHtkwb0lcoNLk2/8PamVNlfvi+6AxJwsEp
71 | M8ijSASgDrTIEkjgHwIDAQAB
72 | -----END PUBLIC KEY-----
73 | Private key: (n=0x9a11485bccb9569410a848fb1afdf2a81b17c1fa9f9eb546fd1deb873b49b693a4edf20eb8362c085cd5b28ba109dbad2bd257a013f57f745402e245b0cc2d553c7b2b8dbba57ebda7f84cfb32b7d9c254f03dbd0188e4b8e40c47b64c1bd2572834b936ffc3da9953657ef8bee80c49c2c12933c8a34804a00eb4c81248e01f, d=0x318ab12be3cf0d4a1b7921cead454fcc42ba070462639483394d6fb9529547827e9c8d23b294a8e01f8a1019da34e350f2307740e06a270bef1fe646e6ad213e31b528fdd5f5d03e633c07c44755ed622a629d79e822c095ebdf9cc80e517b5566dd3d3e5b16ec737987337a0e497fdba4b5ad97af41c1c3cdd87542a4637d81)
74 | -----BEGIN RSA PRIVATE KEY-----
75 | MIICXAIBAAKBgQCaEUhbzLlWlBCoSPsa/fKoGxfB+p+etUb9HeuHO0m2k6Tt8g64
76 | NiwIXNWyi6EJ260r0legE/V/dFQC4kWwzC1VPHsrjbulfr2n+Ez7MrfZwlTwPb0B
77 | iOS45AxHtkwb0lcoNLk2/8PamVNlfvi+6AxJwsEpM8ijSASgDrTIEkjgHwIDAQAB
78 | AoGAMYqxK+PPDUobeSHOrUVPzEK6BwRiY5SDOU1vuVKVR4J+nI0jspSo4B+KEBna
79 | NONQ8jB3QOBqJwvvH+ZG5q0hPjG1KP3V9dA+YzwHxEdV7WIqYp156CLAlevfnMgO
80 | UXtVZt09PlsW7HN5hzN6Dkl/26S1rZevQcHDzdh1QqRjfYECQQDGDUIQXlOiAcGo
81 | d5YqAGpWe0wzJ0UypeqZcqS9MVe9OkjjopCkkYntifdN/1oG7S/1KUMtLoGHqntb
82 | c428zOO/AkEAxyV0cmuJbFdfM0x2XhZ+ge/7putIx76RHDOjBpM6VQXpLEFj54kB
83 | qGLAB7SXr7P4AFrEjfckJOp2YMI5BreboQJAb3EUZHt/WeDdJLutzpKPQ3x7oykM
84 | wfQkbxXYZvD16u96BkT6WO/gCb6hXs05zj32x1/hgfHyRvGCGjKKZdtwpwJBAJ74
85 | y0g7h+wwoxJ0S1k4Y6yeQikxUVwCSBxXLCCnjr0ohsaJPJMrz2L30YtVInFkHOlL
86 | i/Q4AWZmtDDxWkx+bYECQG8e6bGoszuX5xjvhEBslIws9+nMzMuYBR8HvhLo58B5
87 | N8dk3nIsLs3UncKLiiWubMAciU5jUxZoqWpRXXwECKE=
88 | -----END RSA PRIVATE KEY-----
89 | Encrypted: b'99b331c4e1c8f3fa227aacd57c85f38b7b7461574701b427758ee4f94b1e07d791ab70b55d672ff55dbe133ac0bea16fc23ea84636365f605a9b645e0861ee11d68a7550be8eb35e85a4bde6d73b0b956d000866425511c7920cdc8a3786a4f1cb1986a875373975e158d74e11ad751594de593a35de765fe329c0d3dfbbfedc'
90 | Decrypted: b'A message for encryption'
91 | ```
92 |
93 | **Notes**:
94 |
95 | * If you run the above example, your output will be different, because it generates different **random RSA key-pair** at each execution.
96 | * Even if you **encrypt the same message several times** with the same public key, you will get **different output**. This is because the **OAEP** padding algorithm injects some randomness with the padding.
97 | * If you try to **encrypt larger messages**, you will get and exception, because the **1024-bit key limits** the maximum message length.
98 |
99 | Now **play with the above code**, modify it and run it to learn how RSA works in action.
100 |
--------------------------------------------------------------------------------
/asymmetric-key-ciphers/rsa-or-ecc-which-is-better.md:
--------------------------------------------------------------------------------
1 | # RSA or ECC? Which is Better?
2 |
3 | It is disputable whether **ECC** or **RSA** is better in the space of the **public-key cryptosystems**, so we shall present their strong and weak sides. Both cryptosystems \(RSA and elliptic-curve cryptography\) work with private and public keys and provide similar capabilities like key generation, digital signatures, key agreement schemes and encryption schemes.
4 |
5 | Generally, it is considered that **ECC is the modern and the more preferable public-key cryptosystem** because of smaller keys, shorter signatures and better performance, but some people disagree. Today both cryptosystems are widely used. For example \(as of Nov 2018\) Facebook and Google protect their primary Web sites with 256-bit ECC private keys, while Amazon and Apple protect their primary Web sites with 2048-bit RSA private keys.
6 |
7 | ## Advantages of ECC
8 |
9 | The **Elliptic-curve cryptography \(ECC\)** has the following advantages over RSA:
10 |
11 | * **Smaller keys, ciphertexts and signatures**. Typically for 128-bit encryption, a 256-bit EC private key is used. Signatures typically consist of 2 times the private key-length or longer \(depends on the encoding scheme\). By contract, in RSA for 128-bit security, a 3072-bit private key is needed. Ciphertext length has typically the same length as the unencrypted plain-text.
12 | * **Very fast key generation**. In the ECC cryptosystems, key generation consists of random number generation + EC point multiplication and is extremely fast, even for the most heavy curves used in practice. By contrast, in RSA key generation may be slow, especially for long keys \(e.g. 4096-bit and longer keys\), due to prime number generation process.
13 | * **Fast signatures**. Signing messages and verifying ECC signatures is very fast: just few EC point calculations.
14 | * **Fast key agreement**. Key agreement \(ECDH\) is as simple as multiplying an EC point by an integer and is very fast.
15 | * **Fast encryption and decryption**. In fact the encryption is as fast as the underlying symmetric key encryption \(due to the ECIES encryption scheme\) + the little slow-down from the ECDH key agreement.
16 |
17 | ## Disadvantages of ECC
18 |
19 | The **Elliptic-curve cryptography \(ECC\)** has some disadvantages:
20 |
21 | * ECC is a **more complicated** and tricky to implement securely than RSA. This is not necessarily a problem is you use proven cryptographic libraries from trusted vendors.
22 | * Signing with a **broken random number generator** compromises the signer's private key. Signing two times with the same random number directly reveals signer's private key. Some signature schemes avoid randomness and has no such potential problem \(e.g. deterministic ECDSA\).
23 | * Not all **standardised curves** are considered secure. You should know how to select a strong curve for your ECC calculations.
24 |
25 | ## Advantages of RSA
26 |
27 | The RSA cryptosystem has the following advantages:
28 |
29 | * RSA is **easier to implement** than ECC. Unless you implement the algorithms yourself, this may not be so important.
30 | * RSA is **easier to understand** than ECC. Signing and decryption are similar; encryption and verification are similar. This simplifies understanding. Simplicity is more important if you implement the algorithms yourself instead of using a well-known library.
31 | * RSA provides very **fast **and simple **encryption **and **signature **algorithms. This is due to the small public exponent.
32 | * Some cryptographers believe that **RSA with very large keys** \(e.g. 16384 bits\) is generally stronger than ECC.
33 |
34 | ## Disadvantages of RSA
35 |
36 | The RSA cryptosystem has the following disadvantages:
37 |
38 | * In the RSA cryptosystem **key generation is very slow** \(especially for large key-length\). It may take a **few minutes** on a modern laptop to generate a 16384-bit RSA key-pair!
39 | * In the RSA cryptosystem **signing** and **decryption** are slow \(for big private keys\), which are slightly tricky to implement securely. Typically, in the RSA cryptosystem the public exponent is small \(e.g. 65537 or 3\), so the calculations to encrypt a message or verify a signature are fast. In the same time, the private exponent is typically large \(e.g. 4096-bit integer\), so the calculations to sign or decrypt a message are slow.
40 | * RSA produces **large signatures** \(of the same length, like the private key\). This is unacceptable for many systems, which keep a lot of signatures, e.g. public blockchains.
41 |
42 | As a conclusion, the author of this book, as well as most cryptographers **recommend ECC over RSA in the general case** due to its smaller key length and smaller signature length and high performance, especially with some highly optimized curves.
43 |
44 |
--------------------------------------------------------------------------------
/book.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": [
3 | "ga",
4 | "meta",
5 | "anchors",
6 | "expandable-chapters-small",
7 | "katex",
8 | "sitemap",
9 | "scripts"
10 | ],
11 | "pluginsConfig": {
12 | "ga": {
13 | "token": "UA-11309924-27"
14 | },
15 | "meta-single": {
16 | "name": "google-site-verification",
17 | "content": "66TqznOaEKbY6hOL9vg_iv28RqZNGQY7xKSuB639n-E"
18 | },
19 | "sitemap": {
20 | "hostname": "https://cryptobook.nakov.com/"
21 | },
22 | "scripts": {
23 | "files": [
24 | "./assets/js/repl.it-code-runner.js"
25 | ]
26 | }
27 | },
28 | "pdf": {
29 | "paperSize": "a4",
30 | "margin": {
31 | "top": 48,
32 | "bottom": 48,
33 | "left": 36,
34 | "right": 36
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/conclusion.md:
--------------------------------------------------------------------------------
1 | # Conclusion
2 |
3 | ...
4 |
--------------------------------------------------------------------------------
/cover.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/cover.jpg
--------------------------------------------------------------------------------
/crypto-libraries-for-developers/README.md:
--------------------------------------------------------------------------------
1 | # Crypto Libraries for Developers
2 |
3 | ## Cryptographic Libraries for JavaScript, Python, C# and Java
4 |
5 | * Cryptography in **JavaScript**
6 | * ECDSA, elliptic.js, js-sha3.js
7 | * Cryptography libraries in **Python**
8 | * ECDSA, eth\_keys
9 | * C# and **.NET** cryptography
10 | * Bouncy Castle .NET, Nethereum
11 | * **Java** cryptography
12 | * JCA, Bouncy Castle, Web3j
13 | * **C** and **C++** cryptography
14 | * Crypto++, OpenSSL bindings, Nettle, libgcrypt
15 |
16 | TODO:
17 |
18 | * **OpenSSL** - [https://en.wikipedia.org/wiki/OpenSSL](https://en.wikipedia.org/wiki/OpenSSL)
19 | * **LibSodium**
20 | * **Crypto++**
21 | * **Lingcrypt** - [https://en.wikipedia.org/wiki/Libgcrypt](https://en.wikipedia.org/wiki/Libgcrypt)
22 | * **Bouncy Castle**
23 | * **Nettle** - [https://git.lysator.liu.se/nettle/nettle](https://git.lysator.liu.se/nettle/nettle)
24 | * **Botan** - [https://botan.randombit.net](https://botan.randombit.net)
25 | * **Others...**
26 |
27 | ## Summary
28 |
29 | * **JavaScript** and **Python** provide simple cryptography libraries
30 | * Hashes, ECC, ECDSA, AES, and many more
31 | * Cryptography is **C#** is heavy
32 | * Use **Bouncy Castle .NET** for general crypto
33 | * Or **Nethereum** for simplified secp256k1
34 | * Cryptography in **Java** is heavy
35 | * **JCA** and **Bouncy Castle** are hard to use
36 | * **Web3j** is simplifies library for secp256k1
37 |
38 | ...
39 |
--------------------------------------------------------------------------------
/crypto-libraries-for-developers/c-crypto-libraries.md:
--------------------------------------------------------------------------------
1 | # C# Crypto Libraries
2 |
3 | ## C# Crypto Libraries
4 |
5 | ...
6 |
7 | ## Cryptography in C# and .NET
8 |
9 | * Bouncy Castle .NET and Nethereum:Hashes, ECC and ECDSA
10 |
11 | ## .NET Cryptography and Bouncy Castle .NET
12 |
13 | * Cryptography in C# and .NET is based on:
14 | * The build-in libraries: **System.Security.Cryptography**
15 | * The **Bouncy Castle .NET**– a powerful C# cryptography library
16 | * [http://www.bouncycastle.org/csharp](http://www.bouncycastle.org/csharp)
17 | * **Nethereum** – a simplified library for Ethereum and secp256k1
18 | * Nethereum – [https://github.com/Nethereum](https://github.com/Nethereum)
19 | * The cryptographic functionality is in Nethereum.Signer
20 | * Nethereum also includes the Bouncy Castle .NET library
21 |
22 | ## ECDSA in C#: Initialize the Application
23 |
24 | Install the "**Nethereum.Signer**" package from **NuGet**
25 |
26 | ```csharp
27 | dotnet add package Nethereum.Signer
28 | ```
29 |
30 | Import the **Nethereum Signer** namespaces:
31 |
32 | ```csharp
33 | using Nethereum.Signer;
34 | using Nethereum.Signer.Crypto;
35 | using Nethereum.Util;
36 | using Nethereum.Hex.HexConvertors.Extensions;
37 | ```
38 |
39 | The **Bouncy Castle** namespaces will also be available, e.g.
40 |
41 | ```csharp
42 | Org.BouncyCastle.Math.EC.ECPoint p = …;
43 | ```
44 |
45 | ### ECDSA in C#: Generate / Load Keys
46 |
47 | ```csharp
48 | // var privKey = EthECKey.GenerateKey(); // Random private key
49 | var privKey = new EthECKey( "97ddae0f3a25b92268175400149d65d6887b9cefaf28ea2c078e05cdc15a3c0a");
50 | byte[] pubKeyCompressed = new ECKey(
51 | privKey.GetPrivateKeyAsBytes(), true).GetPubKey(true);
52 | Console.WriteLine("Private key: {0}",
53 | privKey.GetPrivateKey().Substring(4));
54 | Console.WriteLine("Public key: {0}",
55 | privKey.GetPubKey().ToHex().Substring(2));
56 | Console.WriteLine("Public key (compressed): {0}",
57 | pubKeyCompressed.ToHex());
58 | ```
59 |
60 | Complete example:[https://gist.github.com/nakov/f2a579eb9893b29338b11e063d6f80c2](https://gist.github.com/nakov/f2a579eb9893b29338b11e063d6f80c2)
61 |
62 | ### ECDSA in C#: Sign Message
63 |
64 | ```csharp
65 | string msg = "Message for signing";
66 | byte[] msgBytes = Encoding.UTF8.GetBytes(msg);
67 | byte[] msgHash = new Sha3Keccack().CalculateHash(msgBytes);
68 | var signature = privKey.SignAndCalculateV(msgHash);
69 |
70 | Console.WriteLine("Msg: {0}", msg);
71 | Console.WriteLine("Msg hash: {0}", msgHash.ToHex());
72 | Console.WriteLine("Signature: [v = {0}, r = {1}, s = {2}]",
73 | signature.V[0] - 27,
74 | signature.R.ToHex(),
75 | signature.S.ToHex());
76 | ```
77 |
78 | Complete example:[https://gist.github.com/nakov/f2a579eb9893b29338b11e063d6f80c2](https://gist.github.com/nakov/f2a579eb9893b29338b11e063d6f80c2)
79 |
80 | ### ECDSA in C#: Verify Message
81 |
82 | ```csharp
83 | var pubKeyRecovered =
84 | EthECKey.RecoverFromSignature(signature, msgHash);
85 | Console.WriteLine("Recovered pubKey: {0}",
86 | pubKeyRecovered.GetPubKey().ToHex().Substring(2));
87 |
88 | bool validSig = pubKeyRecovered.Verify(msgHash, signature);
89 | Console.WriteLine("Signature valid? {0}", validSig);
90 | ```
91 |
92 | Complete example:[https://gist.github.com/nakov/f2a579eb9893b29338b11e063d6f80c2](https://gist.github.com/nakov/f2a579eb9893b29338b11e063d6f80c2)
93 |
--------------------------------------------------------------------------------
/crypto-libraries-for-developers/java-crypto-libraries.md:
--------------------------------------------------------------------------------
1 | # Java Crypto Libraries
2 |
3 | ## Java Crypto Libraries
4 |
5 | ...
6 |
7 | ## Cryptography in Java
8 |
9 | * JCA, Bouncy Castle and Web3j:Hashes, ECC and ECDSA
10 |
11 | ## JCA, Bouncy Castle and Web3j
12 |
13 | * Cryptography in Java is based on the Java Cryptography Architecture (JCA)
14 | * Typical Java style: lot of boilerplate code
15 | * **Bouncy Castle** is the leading Java cryptography library
16 | * Docs: [https://www.bouncycastle.org/documentation.html](https://www.bouncycastle.org/documentation.html)
17 | * **Web3j** – a simplified library for Ethereum and secp256k1
18 | * Web3j – [https://github.com/web3j](https://github.com/web3j)
19 | * The cryptographic functionality is in web3j/crypto
20 |
21 | ## ECDSA in Java: Install the Crypto Libraries
22 |
23 | * This **Maven** dependency will install the following libraries:
24 | * **org.web3j.crypto**– Ethereum style secp256k1 EC cryptography
25 | * **org.bouncycastle**– BouncyCastle crypto provider for Java
26 |
27 | ```markup
28 |
29 | org.web3j
30 | crypto
31 | 3.3.1
32 |
33 | ```
34 |
35 | ## ECDSA in Java: Initialize the Application
36 |
37 | ```java
38 | import org.bouncycastle.util.encoders.Hex;
39 | import org.web3j.crypto.*;
40 | import java.math.BigInteger;
41 | ```
42 |
43 | ## ECDSA in Java: Generate / Load Keys
44 |
45 | ```java
46 | // Generate random private key
47 | // BigInteger privKey = Keys.createEcKeyPair().getPrivateKey();
48 |
49 | BigInteger privKey = new BigInteger(
50 | "97ddae0f3a25b92268175400149d65d6887b9cefaf28ea2c078e05cdc15a3c0a", 16);
51 | BigInteger pubKey = Sign.publicKeyFromPrivate(privKey);
52 | ECKeyPair keyPair = new ECKeyPair(privKey, pubKey);
53 |
54 | System.out.println("Private key: " + privKey.toString(16));
55 | System.out.println("Public key: " + pubKey.toString(16));
56 | System.out.println("Public key (compressed): " +
57 | compressPubKey(pubKey));
58 | ```
59 |
60 | ## ECDSA in Java: Sign Message
61 |
62 | ```java
63 | String msg = "Message for signing";
64 | byte[] msgHash = Hash.sha3(msg.getBytes());
65 | Sign.SignatureData signature =
66 | Sign.signMessage(msgHash, keyPair, false);
67 |
68 | System.out.println("Msg: " + msg);
69 | System.out.println("Msg hash: " + Hex.toHexString(msgHash));
70 | System.out.printf(
71 | "Signature: [v = %d, r = %s, s = %s]\n",
72 | signature.getV() - 27,
73 | Hex.toHexString(signature.getR()),
74 | Hex.toHexString(signature.getS()));
75 | ```
76 |
77 | ## ECDSA in Java: Verify Signature
78 |
79 | ```java
80 | BigInteger pubKeyRecovered =
81 | Sign.signedMessageToKey(msg.getBytes(), signature);
82 | System.out.println("Recovered public key: " +
83 | pubKeyRecovered.toString(16));
84 |
85 | boolean validSig = pubKey.equals(pubKeyRecovered);
86 | System.out.println("Signature valid? " + validSig);
87 | ```
88 |
--------------------------------------------------------------------------------
/crypto-libraries-for-developers/javascript-crypto-libraries.md:
--------------------------------------------------------------------------------
1 | # JavaScript Crypto Libraries
2 |
3 | ## JavaScript Crypto Libraries
4 |
5 | ...
6 |
7 | ## Cryptography in JavaScript
8 |
9 | * ECDSA with elliptic.js and js-sha3
10 |
11 | ### ECDSA in JavaScript: Generate / Load Keys
12 |
13 | ```javascript
14 | npm install elliptic
15 | npm install js-sha3
16 | ```
17 |
18 | ...
19 |
20 | ```javascript
21 | let elliptic = require('elliptic');
22 | let sha3 = require('js-sha3');
23 | let ec = new elliptic.ec('secp256k1');
24 |
25 | // let keyPair = ec.genKeyPair(); // Generate random keys
26 | let keyPair = ec.keyFromPrivate(
27 | "97ddae0f3a25b92268175400149d65d6887b9cefaf28ea2c078e05cdc15a3c0a");
28 | let privKey = keyPair.getPrivate("hex");
29 | let pubKey = keyPair.getPublic();
30 | console.log(`Private key: ${privKey}`);
31 | console.log("Public key :", pubKey.encode("hex").substr(2));
32 | console.log("Public key (compressed):",
33 | pubKey.encodeCompressed("hex"));
34 | ```
35 |
36 | Run the above code example: [https://repl.it/@nakov/ECDSA-in-JS](https://repl.it/@nakov/ECDSA-in-JS).
37 |
38 | ECDSA in JavaScript: Sign Message
39 |
40 | ```javascript
41 | let msg = 'Message for signing';
42 | let msgHash = sha3.keccak256(msg);
43 | let signature =
44 | ec.sign(msgHash, privKey, "hex", {canonical: true});
45 |
46 | console.log(`Msg: ${msg}`);
47 | console.log(`Msg hash: ${msgHash}`);
48 | console.log("Signature:", signature);
49 | ```
50 |
51 | Run the above code example: [https://repl.it/@nakov/ECDSA-sign-verify-in-JS](https://repl.it/@nakov/ECDSA-sign-verify-in-JS).
52 |
53 | Complete example: [https://gist.github.com/nakov/1dcbe26988e18f7a4d013b65d8803ffc](https://gist.github.com/nakov/1dcbe26988e18f7a4d013b65d8803ffc).
54 |
55 | ### ECDSA in JavaScript: Verify Signature
56 |
57 | ```javascript
58 | let hexToDecimal = (x) => ec.keyFromPrivate(x, "hex")
59 | .getPrivate().toString(10);
60 | let pubKeyRecovered = ec.recoverPubKey(
61 | hexToDecimal(msgHash), signature,
62 | signature.recoveryParam, "hex");
63 | console.log("Recovered pubKey:",
64 | pubKeyRecovered.encodeCompressed("hex"));
65 | let validSig = ec.verify(
66 | msgHash, signature, pubKeyRecovered);
67 | console.log("Signature valid?", validSig);
68 | ```
69 |
70 | Run the above code example: [https://repl.it/@nakov/ECDSA-sign-verify-in-JS](https://repl.it/@nakov/ECDSA-sign-verify-in-JS).
71 |
72 | Complete example: [https://gist.github.com/nakov/1dcbe26988e18f7a4d013b65d8803ffc](https://gist.github.com/nakov/1dcbe26988e18f7a4d013b65d8803ffc)
73 |
--------------------------------------------------------------------------------
/crypto-libraries-for-developers/python-crypto-libraries.md:
--------------------------------------------------------------------------------
1 | # Python Crypto Libraries
2 |
3 | ## Python Crypto Libraries
4 |
5 | ...
6 |
7 | ## Cryptography in Python
8 |
9 | * Hashes, ECC and ECDSA, eth\_keys Library
10 |
11 | ## ECDSA in Python: Generate / Load Keys
12 |
13 | ```python
14 | import eth_keys, eth_utils, binascii, os
15 |
16 | # privKey = eth_keys.keys.PrivateKey(os.urandom(32))
17 | privKey = eth_keys.keys.PrivateKey(binascii.unhexlify(
18 | '97ddae0f3a25b92268175400149d65d6887b9cefaf28ea2c078e05cdc15a3c0a'))
19 | pubKey = privKey.public_key
20 | pubKeyCompressed = '0' + str(2 + int(pubKey) % 2) + str(pubKey)[2:66]
21 | address = pubKey.to_checksum_address()
22 | print('Private key (64 hex digits):', privKey)
23 | print('Public key (plain, 128 hex digits):', pubKey)
24 | print('Public key (compressed):', pubKeyCompressed)
25 | print('Signer address:', address)
26 | ```
27 |
28 | ## ECDSA in Python: Sign Message
29 |
30 | ```python
31 | msg = b'Message for signing'
32 | msgHash = eth_utils.keccak(msg)
33 | signature = privKey.sign_msg(msg)
34 |
35 | print('Msg:', msg)
36 | print('Msg hash:', binascii.hexlify(msgHash))
37 | print('Signature: [v = {0}, r = {1}, s = {2}]'.format(
38 | hex(signature.v), hex(signature.r), hex(signature.s)))
39 | print('Signature (130 hex digits):', signature)
40 | ```
41 |
42 | ## ECDSA in Python: Verify Signature
43 |
44 | ```python
45 | msg = b'Message for signing'
46 | msgSigner = '0xa44f70834a711F0DF388ab016465f2eEb255dEd0'
47 | signature = eth_keys.keys.Signature(binascii.unhexlify(
48 | '6f0156091cbe912f2d5d1215cc3cd81c0963c8839b93af60e0921b61a19c54300c71006dd93f3508c432daca21db0095f4b16542782b7986f48a5d0ae3c583d401'))
49 | signerPubKey = signature.recover_public_key_from_msg(msg)
50 | print('Signer public key (recovered):', signerPubKey)
51 | signerAddress = signerPubKey.to_checksum_address()
52 | print('Signer address:', signerAddress)
53 | print('Signature valid?:', signerAddress == msgSigner)
54 | ```
55 |
--------------------------------------------------------------------------------
/cryptographic-hash-functions/README.md:
--------------------------------------------------------------------------------
1 | # Hash Functions
2 |
3 | In computer programming **hash functions** map text (or other data) to integer numbers. Usually different inputs maps to different outputs, but sometimes a **collision** may happen (different input with the same output).
4 |
5 | **Cryptographic hash** functions transform text or binary data to fixed-length **hash value** and are known to be **collision-resistant** and **irreversible**. Example of cryptographic hash function is **SHA3-256**:
6 |
7 | ```
8 | SHA3-256("hello") = "3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392"
9 | ```
10 |
11 | The above SHA3-256 hash calculation can be coded in Python like this:
12 |
13 | ```python
14 | import hashlib, binascii
15 | sha3_256hash = hashlib.sha3_256(b'hello').digest()
16 | print("SHA3-256('hello') =", binascii.hexlify(sha3_256hash))
17 | ```
18 |
19 | Run the above code example: [https://repl.it/@nakov/SHA3-256-hello-in-Python](https://repl.it/@nakov/SHA3-256-hello-in-Python).
20 |
21 | The same SHA3-256 hash calculation can be coded in JavaScript like this (after `npm install js-sha3`):
22 |
23 | ```javascript
24 | sha3 = require('js-sha3');
25 | let sha3_256hash = sha3.sha3_256('hello').toString();
26 | console.log("SHA3-256('hello') =", sha3_256hash);
27 | ```
28 |
29 | Run the above code example: [https://repl.it/@nakov/SHA3-256-hello-in-JS](https://repl.it/@nakov/SHA3-256-hello-in-JS).
30 |
31 | ## Hashing (in Software Engineering)
32 |
33 | The process of calculating the value of certain hash function is called "**hashing**".
34 |
35 | 
36 |
37 | In the above example the text `John Smith` is hashed to the hash value `02` and `Lisa Smith` is hashed to `01`. The input texts `John Smith` and `Sandra Dee` both are hashed to `02` and this is called "**collision**".
38 |
39 | Hash functions are **irreversible by design**, which means that there is no fast algorithm to restore the input message from its hash value.
40 |
41 | In programming **hash functions** are used in the implementation of the data structure "**hash-table**" (associative array) which maps values of certain input type to values of another type, e.g. map product name (text) to product price (decimal number).
42 |
43 | A **naive hash function** is just to sum the bytes of the input data / text. It causes a lot of collisions, e.g. `hello` and `ehllo` will have the same hash code. **Better hash functions** may use the [Merkle–Damgård construction](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd\_construction) scheme, which takes the first byte as **state**, then **transforms the state** (e.g. multiplies it by a prime number like 31), then **adds the next byte** to the state, then again transforms the state and adds the next byte, etc. This significantly reduces the rate of collisions and produces better distribution.
44 |
45 | ## Cryptographic Hash Functions
46 |
47 | In cryptography, **hash functions** transform **input data** of arbitrary size (e.g. a text message) to a **result** of fixed size (e.g. 256 bits), which is called **hash value** (or hash code, message digest, or simply hash). Hash functions (hashing algorithms) used in computer cryptography are known as "**cryptographic hash functions**". Examples of such functions are **SHA-256** and **SHA3-256**, which transform arbitrary input to 256-bit output.
48 |
49 | 
50 |
51 | ### Cryptographic Hash Functions - Examples
52 |
53 | As an **example**, we can take the cryptographic hash function `SHA-256` and calculate the hash value of certain text message `hello`:
54 |
55 | ```
56 | SHA-256("hello") = "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"
57 | ```
58 |
59 | The above SHA-256 calculation can be coded in Python like this:
60 |
61 | ```python
62 | import hashlib, binascii
63 |
64 | sha256hash = hashlib.sha256(b'hello').digest()
65 | print("SHA-256('hello') = ", binascii.hexlify(sha256hash))
66 | ```
67 |
68 | Run the above code example: [https://repl.it/@nakov/SHA-256-hello-in-Python](https://repl.it/@nakov/SHA-256-hello-in-Python).
69 |
70 | There is no efficient algorithm to find the input message (in the above example `hello`) from its hash value (in the above example `2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824`). It is well-known that cryptographic hash functions **cannot be reversed** back, so they are used widely to encode an input without revealing it (e.g. encode a private key to a blockchain address without revealing the key).
71 |
72 | As another **example**, we can take the cryptographic hash function `SHA3-512` and calculate the hash value of the same text message `hello`:
73 |
74 | ```
75 | SHA3-512("hello") = "75d527c368f2efe848ecf6b073a36767800805e9eef2b1857d5f984f036eb6df891d75f72d9b154518c1cd58835286d1da9a38deba3de98b5a53e5ed78a84976"
76 | ```
77 |
78 | ### Cryptographic Hash Functions - Live Demo
79 |
80 | **Play** with most popular cryptographic hash functions **online**: [https://www.fileformat.info/tool/hash.htm](https://www.fileformat.info/tool/hash.htm).
81 |
82 | 
83 |
84 | **Cryptographic hash functions** are widely used in cryptography, in computer programming and in blockchain systems.
85 |
--------------------------------------------------------------------------------
/cryptographic-hash-functions/crypto-hashes-and-collisions.md:
--------------------------------------------------------------------------------
1 | # Crypto Hashes and Collisions
2 |
3 | **Different input** messages are expected to produce **different output** hash values (message digest).
4 |
5 | 
6 |
7 | ## Hash Collisions
8 |
9 | A **collision** means the same hash value for two different inputs. For simple hash functions it is easy to reach a collision. For example, assume a hash function `h(text)` sums of all character codes in a text. It will produce the same hash value (collision) for texts holding the same letters in different order, i.e. `h('abc') == h('cab') == h('bca')`. To avoid collisions, cryptographers have designed **collision-resistant** hash functions.
10 |
11 | ## Cryptographic Hash Functions: No Collisions
12 |
13 | **Collisions** in the cryptographic hash functions are **extremely unlikely** to be found, so crypto **hashes** are considered to almost uniquely identify their corresponding input. Moreover, it is extremely hard to find an input message that hashes to given value.
14 |
15 | Cryptographic hash functions are **one-way hash functions**, which are **infeasible to invert**. The chance to find a collision (by brute force) for a strong cryptographic hash function (like SHA-256) is extremely little. Let's define this in more details:
16 |
17 | * Let's have hash value `h`=`hash(p)` for certain strong cryptographic hash function `hash`.
18 | * It is expected to be **extremely hard** to find an input `p'`, such that `hash(p')`=`h`.
19 | * For most modern strong cryptographic hash functions there are **no known collisions**.
20 |
21 | The **ideal cryptographic hash function** should have the following properties:
22 |
23 | * **Deterministic**: the same input message should always result in the same hash value.
24 | * **Quick**: it should be fast to compute the hash value for any given message.
25 | * **Hard to analyze**: a small change to the input message should totally change the output hash value.
26 | * **Irreversible**: generating a valid input message from its hash value should be **infeasible**. This means that there should be no significantly better way than brute force (try all possible input messages).
27 | * **No collisions**: it should be extremely hard (or practically impossible) to find two different messages with the same hash.
28 |
29 | Modern cryptographic hash functions (like SHA2 and SHA3) match the above properties and are used widely in cryptography.
30 |
--------------------------------------------------------------------------------
/cryptographic-hash-functions/exercises-calculate-hashes.md:
--------------------------------------------------------------------------------
1 | # Exercises: Calculate Hashes
2 |
3 | In this exercise session, you are assigned to write some code to **calculate cryptographic hashes**. Write a program to **calculate hashes** of given text message: **SHA-224**, **SHA-256**, **SHA3-224**, **SHA3-384**, **Keccak-384** and **Whirlpool**. Write your code in programming language of choice.
4 |
5 | ## Calculate **SHA-224 Hash**
6 |
7 | | | |
8 | | --------- | -------------------------------------------------------- |
9 | | **Input** | **Output** |
10 | | hello | ea09ae9cc6768c50fcee903ed054556e5bfc8347907f12598aa24193 |
11 |
12 | ## Calculate **SHA-256 Hash**
13 |
14 | | | |
15 | | --------- | ---------------------------------------------------------------- |
16 | | **Input** | **Output** |
17 | | hello | 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 |
18 |
19 | ## Calculate **SHA3-224 Hash**
20 |
21 | | | |
22 | | --------- | -------------------------------------------------------- |
23 | | **Input** | **Output** |
24 | | hello | b87f88c72702fff1748e58b87e9141a42c0dbedc29a78cb0d4a5cd81 |
25 |
26 | ## Calculate **SHA3-384 Hash**
27 |
28 | | | |
29 | | --------- | ------------------------------------------------------------------------------------------------ |
30 | | **Input** | **Output** |
31 | | hello | 720aea11019ef06440fbf05d87aa24680a2153df3907b23631e7177ce620fa1330ff07c0fddee54699a4c3ee0ee9d887 |
32 |
33 | ## Calculate **Keccak-384 Hash**
34 |
35 | | | |
36 | | --------- | ------------------------------------------------------------------------------------------------ |
37 | | **Input** | **Output** |
38 | | hello | dcef6fb7908fd52ba26aaba75121526abbf1217f1c0a31024652d134d3e32fb4cd8e9c703b8f43e7277b59a5cd402175 |
39 |
40 | ## Calculate **Whirlpool (512 Bit) Hash**
41 |
42 | | | |
43 | | --------- | -------------------------------------------------------------------------------------------------------------------------------- |
44 | | **Input** | **Output** |
45 | | hello | 0a25f55d7308eca6b9567a7ed3bd1b46327f0f1ffdc804dd8bb5af40e88d78b88df0d002a89e2fdbd5876c523f1b67bc44e9f87047598e7548298ea1c81cfd73 |
46 |
47 | **Hints**: follow the Python examples, given earlier in this section or search in Internet.
48 |
--------------------------------------------------------------------------------
/cryptographic-hash-functions/hash-functions-applications.md:
--------------------------------------------------------------------------------
1 | # Hash Functions: Applications
2 |
3 | **Cryptographic hash functions** (like SHA-256 and SHA3-256) are used in many scenarios. Let's review their most common applications.
4 |
5 | ## Document Integrity
6 |
7 | Verifying the **integrity** of files / documents / messages. E.g. a **SHA256 checksum** may confirm that certain file is original (not modified after its checksum was calculated).
8 |
9 | 
10 |
11 | The above screenshot demonstrates how the **SHA256 checksums** ensure the **integrity** of the OpenSSL files at the official Web site of OpenSSL.
12 |
13 | ## Storing Passwords
14 |
15 | Storing **passwords** and verification of passwords. Instead of keeping a plain-text password in the database, developers usually keep **password hashes** or more complex values derived from the password (e.g. **Scrypt**-derived value).
16 |
17 | 
18 |
19 | The above example comes from the `/etc/shadow` file in a modern Linux system. The above passwords are stored as multiple-round SHA-512 hashes with salt.
20 |
21 | ## Generate Unique ID
22 |
23 | Generate an (**almost**) **unique ID** of certain document / message. Cryptographic hash functions almost uniquely identify documents based on their content. In theory **collisions are possible** with any cryptographic hash function, but are very unlikely to happen, so most systems (like **Git**) assume that the hash function they use is **collistion free**.
24 |
25 | Usually a document is **hashed** and the **document ID** (hash value) is used later to prove the existence of the document, or to retrieve the document from a storage system. Example of hash-based unique IDs are the commit hashes in **Git** and **GitHub**, based on the content of the commit (e.g. `3c3be25bc1757ca99aba55d4157596a8ea217698`) and the **Bitcoin** addresses (e.g. `1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2`).
26 |
27 | 
28 |
29 | In the above example the SHA-1 unique ID identifies a certain commit in GitHub.
30 |
31 | ## Pseudorandom Number Generation
32 |
33 | **Pseudorandom generation** and key derivation. Hash values can serve as random numbers. A simple way to generate a random sequence is like this: start from a **random seed** (entropy collected from random events, such like keyboard clicks or mouse moves). Append "**1**" and calculate the hash to obtain the first random number, then append "**2**" and calculate the hash to obtain the second random number, etc. We shall give a Python example, implementing the described idea.
34 |
35 | ## Proof-of-Work Algorithms
36 |
37 | **Proof-of-work** (PoW) algorithms. Most proof-of-work algorithms calculate a hash value which is bigger than certain value (known as mining difficulty). To find this hash value, miners calculate billions of different hashes and take the biggest of them, because hash numbers are unpredictable. For example, the proof of work problem might be defined as follows: find a number `p`, such that `hash(x + p)` holds 10 zero bits at its beginning.
38 |
39 | ## Cryptographic Hashes are Part of Modern Programming
40 |
41 | **Cryptographic hash functions** are so widely used, that they are often implemented as **build-in functions** in the standard libraries for the modern programming languages and platforms.
42 |
--------------------------------------------------------------------------------
/cryptographic-hash-functions/hash-functions-examples.md:
--------------------------------------------------------------------------------
1 | # Hash Functions - Examples
2 |
3 | In this section we shall provide a few **examples** about calculating cryptographic hash functions in Python.
4 |
5 | ## Calculating Cryptographic Hash Functions in Python
6 |
7 | We shall use the standard Python library `hashlib`. The input data for hashing should be given as **bytes sequence** (bytes object), so we need to **encode the input string** using some text encoding, e.g. `utf8`. The produced **output data** is also a bytes sequence, which can be printed as hex digits using `binascii.hexlify()` as shown below:
8 |
9 | ```python
10 | import hashlib, binascii
11 |
12 | text = 'hello'
13 | data = text.encode("utf8")
14 |
15 | sha256hash = hashlib.sha256(data).digest()
16 | print("SHA-256: ", binascii.hexlify(sha256hash))
17 |
18 | sha3_256 = hashlib.sha3_256(data).digest()
19 | print("SHA3-256: ", binascii.hexlify(sha3_256))
20 |
21 | blake2s = hashlib.new('blake2s', data).digest()
22 | print("BLAKE2s: ", binascii.hexlify(blake2s))
23 |
24 | ripemd160 = hashlib.new('ripemd160', data).digest()
25 | print("RIPEMD-160:", binascii.hexlify(ripemd160))
26 | ```
27 |
28 | Run the above code example: [https://repl.it/@nakov/Hashes-SHA2-SHA3-BLAKE2-RIPEMD-in-Python](https://repl.it/@nakov/Hashes-SHA2-SHA3-BLAKE2-RIPEMD-in-Python).
29 |
30 | The expected **output** from the above example looks like this:
31 |
32 | ```
33 | SHA-256: b'2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824'
34 | SHA3-256: b'3338be694f50c5f338814986cdf0686453a888b84f424d792af4b9202398f392'
35 | BLAKE2s: b'19213bacc58dee6dbde3ceb9a47cbb330b3d86f8cca8997eb00be456f140ca25'
36 | RIPEMD-160: b'108f07b8382412612c048d07d13f814118445acd'
37 | ```
38 |
39 | Calculating `Keccak-256` hashes (the hash function used in the Ethereum blockchain) requires non-standard Python functions. In the below example we use the `pycryptodome` package available from PyPI: [https://pypi.org/project/pycryptodome](https://pypi.org/project/pycryptodome).
40 |
41 | First install "pycryptodome" ([https://www.pycryptodome.org](https://www.pycryptodome.org))
42 |
43 | ```python
44 | pip install pycryptodome
45 | ```
46 |
47 | Now write some Python code to calculate a **Keccak-256** hash:
48 |
49 | ```
50 | from Crypto.Hash import keccak
51 | import binascii
52 |
53 | keccak256 = keccak.new(data=b'hello', digest_bits=256).digest()
54 | print("Keccak256:", binascii.hexlify(keccak256))
55 | ```
56 |
57 | Run the above code example: [https://repl.it/@nakov/Keccak256-in-Python](https://repl.it/@nakov/Keccak256-in-Python).
58 |
59 | The **output** from the above examples is:
60 |
61 | ```
62 | Keccak256: b'1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8'
63 | ```
64 |
--------------------------------------------------------------------------------
/cryptographic-hash-functions/proof-of-work-hash-functions.md:
--------------------------------------------------------------------------------
1 | # Proof-of-Work Hash Functions
2 |
3 | Blockchain **proof-of-work mining** algorithms use a special class of hash functions which are **computational-intensive** and **memory-intensive**. These hash functions are designed to consume a lot of computational resources and a lot of memory and to be very hard to be implemented in a hardware devices (such as [FPGA](https://en.wikipedia.org/wiki/Field-programmable\_gate\_array) integrated circuits or [ASIC](https://en.wikipedia.org/wiki/Application-specific\_integrated\_circuit) miners). Such hash functions are known as "**ASIC-resistant**".
4 |
5 | Many hash functions are designed for proof-of-work mining algorithms, e.g. **ETHash**, **Equihash**, **CryptoNight** and **Cookoo Cycle**. These hash functions are **slow to calculate**, and usually use **GPU** hardware ([rigs](https://en.bitcoin.it/wiki/Mining\_rig) of graphics cards like NVIDIA GTX 1080) or powerful **CPU** hardware (like Intel Core i7-8700K) and a lot of fast **RAM** memory (like DDR4 chips). The goal of these mining algorithms is to **minimize the centralization of mining** by stimulating the small miners (home users and small mining farms) and limit the power of big players in the mining industry (who can afford to build giant mining facilities and data centers). A big number of **small players means better decentralization** than a small number of big players.
6 |
7 | The main weapon in the hands of the big mining corporations is considered the [ASIC miners](https://en.bitcoin.it/wiki/Mining\_hardware\_comparison), so the design of modern cryptocurrencies and usually includes proof-of-work mining using an **ASIC-resistant hashing algorithm** or **proof-of-stake** consensus protocol.
8 |
9 | ## ETHash
10 |
11 | Let's explain in brief the idea behind the **ETHash** proof-of-work mining hash function used in the Ethereum blockchain.
12 |
13 | * **ETHash** is the proof-of-work hash function in the Ethereum blockchain. It is **memory-intensive** hash-function (requires a lot of RAM to be calculated fast), so it is believed to be **ASIC-resistant**.
14 |
15 | How does ETHash work?
16 |
17 | * A "**seed**" is computed for each block (based on the entire chain until the current block).
18 | * From the seed, a **16 MB pseudorandom cache** is computed.
19 | * From the cache, a **1 GB dataset** is extracted to be used in mining.
20 | * Mining involves hashing together random slices of the dataset.
21 |
22 | Learn more about **ETHash** at: [https://github.com/ethereum/wiki/wiki/Ethash](https://github.com/ethereum/wiki/wiki/Ethash), [https://github.com/lukovkin/ethash](https://github.com/lukovkin/ethash).
23 |
24 | ## Equihash
25 |
26 | Let's explain in briefly the idea behind the **Equihash** proof-of-work mining hash function used in Zcash, Bitcoin Gold and a few other blockchains.
27 |
28 | * **Equihash** is the proof-of-work hash function in the Zcash and Bitcoin Gold blockchains. It is **memory-intensive** hash-function (requires a lot of RAM for fast calculation), so it is believed to be **ASIC-resistant**.
29 |
30 | How does **Equihash** work?
31 |
32 | * Uses **BLAKE2b** to compute **50 MB hash dataset** from the previous blocks in the blockchain (until the current block).
33 | * Solves the "**Generalized Birthday Problem**" over the generated hash dataset (pick 512 different strings from 2097152, such that the binary XOR of them is zero). The best known solution (Wagner's algorithm) runs in exponential time, so it requires a lot of memory-intensive and computing-intensive calculations.
34 | * **Double SHA256** the solution to compute the final hash.
35 |
36 | Learn more about **Equihash** at: [https://www.cryptolux.org/images/b/b9/Equihash.pdf](https://www.cryptolux.org/images/b/b9/Equihash.pdf), [https://github.com/tromp/equihash](https://github.com/tromp/equihash).
37 |
38 | ## More about ASIC-Resistant Hash Functions
39 |
40 | Lear more about the **ASIC-resistant hash functions** at: [https://github.com/ifdefelse/ProgPOW](https://github.com/ifdefelse/ProgPOW).
41 |
--------------------------------------------------------------------------------
/digital-signatures/eddsa-and-ed25519.md:
--------------------------------------------------------------------------------
1 | # EdDSA and Ed25519
2 |
3 | **EdDSA** (Edwards-curve Digital Signature Algorithm) is a modern and secure digital signature algorithm based on performance-optimized elliptic curves, such as the 255-bit curve [**Curve25519**](https://en.wikipedia.org/wiki/Curve25519) and the 448-bit curve [**Curve448-Goldilocks**](https://en.wikipedia.org/wiki/Curve448). The EdDSA signatures use the **Edwards form** of the elliptic curves (for performance reasons), respectively `edwards25519` and `edwards448`. The **EdDSA** algorithm is based on the [**Schnorr signature algorithm**](https://en.wikipedia.org/wiki/Schnorr\_signature) and relies on the difficulty of the **ECDLP problem**.
4 |
5 | The **EdDSA** signature algorithm and its variants **Ed25519** and **Ed448** are technically described in the [RFC 8032](https://tools.ietf.org/html/rfc8032).
6 |
7 | ## EdDSA Key Generation
8 |
9 | **Ed25519** and **Ed448** use small **private keys** (32 or 57 bytes respectively), small **public keys** (32 or 57 bytes) and **small signatures** (64 or 114 bytes) with **high security level** at the same time (128-bit or 224-bit respectively).
10 |
11 | Assume the elliptic curve for the EdDSA algorithm comes with a generator point **G** and a subgroup order _**q**_ for the EC points, generated from **G**.
12 |
13 | The **EdDSA key-pair** consists of:
14 |
15 | * **private key** (integer): _**privKey**_
16 | * **public key** (EC point): _**pubKey**_ = _**privKey**_ \* **G**
17 |
18 | The **private key** is generated from a **random integer**, known as _**seed**_ (which should have similar bit length, like the curve order). The _**seed**_ is first hashed, then the last few bits, corresponding to the curve **cofactor** (8 for Ed25519 and 4 for X448) are cleared, then the highest bit is cleared and the second highest bit is set. These transformations guarantee that the private key will always belong to the same subgroup of EC points on the curve and that the private keys will always have similar bit length (to protect from timing-based side-channel attacks). For **Ed25519** the private key is 32 bytes. For **Ed448** the private key is 57 bytes.
19 |
20 | The public key _**pubKey**_ is a point on the elliptic curve, calculated by the EC point multiplication: _**pubKey**_ = _**privKey**_ \* **G** (the private key, multiplied by the generator point **G** for the curve). The public key is encoded as **compressed** EC point: the **y**-coordinate, combined with the lowest bit (the parity) of the **x**-coordinate. For **Ed25519** the public key is 32 bytes. For **Ed448** the public key is 57 bytes.
21 |
22 | ## EdDSA Sign
23 |
24 | The **EdDSA signing** algorithm ([RFC 8032](https://tools.ietf.org/html/rfc8032#page-13)) takes as input a text message _**msg**_ + the signer's EdDSA **private key** _**privKey**_ and produces as output a pair of integers {_**R**_, _**s**_}. EdDSA signing works as follows (with minor simplifications):
25 |
26 | `EdDSA_sign(msg, privKey) --> { R, s }`
27 |
28 | 1. Calculate _**pubKey**_ = _**privKey**_ \* **G**
29 | 2. Deterministically generate a secret integer _**r**_ = hash(hash(_**privKey**_) + _**msg**_) mod _**q**_ (this is a bit simplified)
30 | 3. Calculate the public key point behind _**r**_ by multiplying it by the curve generator: _**R**_ = _**r**_ \* **G**
31 | 4. Calculate _**h**_ = hash(_**R**_ + _**pubKey**_ + _**msg**_) mod _**q**_
32 | 5. Calculate _**s**_ = (_**r**_ + _**h**_ \* _**privKey**_) mod _**q**_
33 | 6. Return the **signature** { _**R**_, _**s**_ }
34 |
35 | The produced **digital signature** is 64 bytes (32 + 32 bytes) for **Ed25519** and 114 bytes (57 + 57 bytes) for **Ed448**. It holds a compressed point _**R**_ + the integer _**s**_ (confirming that the signer knows the _**msg**_ and the _**privKey**_).
36 |
37 | ## EdDSA Verify Signature
38 |
39 | The **EdDSA signature verification** algorithm ([RFC 8032](https://tools.ietf.org/html/rfc8032#page-13)) takes as input a text message _**msg**_ + the signer's EdDSA **public key** _**pubKey**_ + the EdDSA signature {_**R**_, _**s**_} and produces as output a boolean value (valid or invalid signature). EdDSA verification works as follows (with minor simplifications):
40 |
41 | `EdDSA_signature_verify(msg, pubKey, signature { R, s } ) --> valid / invalid`
42 |
43 | 1. Calculate _**h**_ = hash(_**R**_ + _**pubKey**_ + _**msg**_) mod _**q**_
44 | 2. Calculate _**P1**_ = _**s**_ \* **G**
45 | 3. Calculate _**P2**_ = _**R**_ + _**h**_ \* _**pubKey**_
46 | 4. Return _**P1**_ == _**P2**_
47 |
48 | ## How Does it Work?
49 |
50 | During the verification the point _**P1**_ is calculated as: _**P1**_ = _**s**_ \* **G**.
51 |
52 | During the signing _**s**_ = (_**r**_ + _**h**_ \* _**privKey**_) mod _**q**_. Now replace _**s**_ in the above equation:
53 |
54 | * _**P1**_ = _**s**_ \* **G =** (_**r**_ + _**h**_ \* _**privKey**_) mod _**q**_ \* **G** = _**r**_ \* **G** + _**h**_ \* _**privKey**_ \* **G** = _**R**_ + _**h**_ \* _**pubKey**_
55 |
56 | The above is exactly the other point _**P2**_. If these points _**P1**_ and _**P2**_ are the same EC point, this proves that the point _**P1**_, calculated by the private key matches the point _**P2**_, created by its corresponding public key.
57 |
58 | ## ECDSA vs EdDSA
59 |
60 | If we compare the signing and verification for EdDSA, we shall find that **EdDSA is simpler than ECDSA**, easier to understand and to implement. Both signature algorithms have **similar security strength** for curves with similar key lengths. For the most popular curves (liked `edwards25519` and `edwards448`) the **EdDSA algorithm is slightly faster than ECDSA**, but this highly depends on the curves used and on the certain implementation. Unlike ECDSA the EdDSA signatures do not provide a way to **recover the signer's public key** from the signature and the message. Generally, it is considered that EdDSA is recommended for most modern apps.
61 |
--------------------------------------------------------------------------------
/digital-signatures/exercises-eddsa-sign-and-verify.md:
--------------------------------------------------------------------------------
1 | # Exercises: EdDSA Sign and Verify
2 |
3 | In this exercise we shall **sign** and **verify** messages using the **EdDSA** digital signature algorithm and the `edwards25519` curve, following the technical specification from [RFC 8032](https://tools.ietf.org/html/rfc8032#page-9). The **Ed25519** digital signature algorithm can be found as library for the most programming languages.
4 |
5 | The Ed25519 **private key** is encoded as 64 hex digits (32 bytes). The corresponding Ed25519 **public key** is encoded also as 64 hex digits (32 bytes). The EdDSA-Ed25519 **signature** {_**R**_, _**s**_} consists of 32 + 32 bytes (64 bytes, 128 hex digits).
6 |
7 | ## EdDSA-Ed25519: Sign Message
8 |
9 | Write a program to sign given text **message** with given **private key**. The input consists of 2 text lines. The **first line holds** the input **message** for signing. The **second line** holds the private key as **hex string**. Print the **output** as JSON document, holding the input **message** + the **public key** of the signer (as hex string, uncompressed) + the Ed25519 **digital signature** (as hex string).
10 |
11 | Sample input:
12 |
13 | ```
14 | Message for Ed25519 signing
15 | de6d730f36a8607b8bfdaa79b3b1127291f1d50552c2fe05c5254a9719105c4a
16 | ```
17 |
18 | Sample output:
19 |
20 | ```
21 | {
22 | "msg": "Message for Ed25519 signing",
23 | "pubKey":"7721a5832cb70cce1a960cf236d50a0e862555ccad400b5fee0bcf777f7ab476",
24 | "signature":"6c4adbba332b5db520c0ec95433ea136f70fe2d50e8955a7049d216626a3491c0e5cbfefb8d779687cc9811311ccaf7cd07a0e96a570fb3a4b680a4ead60c602"
25 | }
26 | ```
27 |
28 | ## EdDSA-Ed25519: Verify Signature
29 |
30 | Write a program to **validate the Ed25519 digital signature**, created by the previous exercise. The **input** comes as JSON document, holding the **message** + the **public key** (uncompressed, hex string) + the **signature**. Print as **output** a single word: "**valid**' or "**invalid**".
31 |
32 | Sample input (correctly signed message):
33 |
34 | ```
35 | {
36 | "msg": "Message for Ed25519 signing",
37 | "pubKey":"7721a5832cb70cce1a960cf236d50a0e862555ccad400b5fee0bcf777f7ab476",
38 | "signature":"6c4adbba332b5db520c0ec95433ea136f70fe2d50e8955a7049d216626a3491c0e5cbfefb8d779687cc9811311ccaf7cd07a0e96a570fb3a4b680a4ead60c602"
39 | }
40 | ```
41 |
42 | Sample output:
43 |
44 | ```
45 | valid
46 | ```
47 |
48 | Sample input (tampered message):
49 |
50 | ```
51 | {
52 | "msg": "Tampered msg",
53 | "pubKey":"7721a5832cb70cce1a960cf236d50a0e862555ccad400b5fee0bcf777f7ab476",
54 | "signature":"6c4adbba332b5db520c0ec95433ea136f70fe2d50e8955a7049d216626a3491c0e5cbfefb8d779687cc9811311ccaf7cd07a0e96a570fb3a4b680a4ead60c602"
55 | }
56 | ```
57 |
58 | Sample output:
59 |
60 | ```
61 | invalid
62 | ```
63 |
--------------------------------------------------------------------------------
/digital-signatures/exercises-secp256k1-sign-verify.md:
--------------------------------------------------------------------------------
1 | # Exercises: ECDSA Sign and Verify
2 |
3 | In this exercise we shall **sign** and **verify** messages using the **ECDSA** digital signature algorithm and the NIST **P-521** curve. The NIST P-521 elliptic curve, known also as `secp521r1` is 521-bit ECC curve, suitable for ECDSA digital signatures and ECDH key agreement. It uses **521-bit private keys** (encoded as 65-66 bytes, 130-132 hex digits) and **1042-bit public keys** (uncompressed, encoded as 130-131 bytes, 260-261 hex digits). The produced **signature** is 132 bytes (264 hex digits).
4 |
5 | ## Sign a Message with ECDSA / P-521
6 |
7 | Write a program to **sign a message** by given **private key**. The **input** consists of 2 text lines: message and private key. The message is given as **text** and the private key is given as **hex** string (130-132 hex digits). Use the **ECDSA deterministic signing** (following [RFC 6979](https://tools.ietf.org/html/rfc6979)) and the curve NIST **P-521**, which also known as **secp521r1**. Print the **output** as JSON document, holding the input **message** + the **public key** of the signer (as hex string, uncompressed) + the ECDSA **digital signature** (as hex string).
8 |
9 | Sample input:
10 |
11 | ```
12 | Message for ECDSA-NIST-521p signing
13 | 00135799f9d1f033af26168780bf2503313acff854c44031321d7a29bba96edb3c1b93b9deea55229b1de058196ad69a79c01463e3281d9fcc82afd73aac7fdfa4af
14 | ```
15 |
16 | Sample output:
17 |
18 | ```
19 | {
20 | "msg": "Message for ECDSA-NIST-521p signing",
21 | "pubKey":"0078a6bb6732cb3134d2ca3912b2876fe005b20027037512cf972605f58ce5908471a1f9817c8d24290fcc943951f3113a7ee3716bd95f0b9c7326843a833ac6a0750021f08f88a6bd397525068300801521d2d97fea32f2c8b0c74dc8e231a4dd73252c4a7398e25ab20dba0a9df3df0c256617e004a9623676b9f3f9a3aa21f57c90ce",
22 | "signature":"00202029ab1a3326fe7d1e9ec36d7fab048e833c6c3cad37e1d5294695d28e9fd5583c23edaeecb596782a4c85bac27780623c1a9216202f3828991cbeebbeb049d9008270ea623d8d26c5ab89b621bac12c7fa8e9193e4057e16617f80cfc4279537f45169fb949deb3f9936400a130f6859aaa9c929e47c66610e59cc71a9f7ea79e81"
23 | }
24 | ```
25 |
26 | ## Verify Message Signature with ECDSA / P-521
27 |
28 | Write a program to **validate the ECDSA digital signature**, created by the previous exercise. The **input** comes as JSON document, holding the **message** + the **public key** (uncompressed, hex string) + the **signature**. Use the P-521 elliptic curve (`secp521r1`). Print as **output** a single word: "**valid**' or "**invalid**".
29 |
30 | Sample input (correctly signed message):
31 |
32 | ```
33 | {
34 | "msg": "Message for ECDSA-NIST-521p signing",
35 | "pubKey":"0078a6bb6732cb3134d2ca3912b2876fe005b20027037512cf972605f58ce5908471a1f9817c8d24290fcc943951f3113a7ee3716bd95f0b9c7326843a833ac6a0750021f08f88a6bd397525068300801521d2d97fea32f2c8b0c74dc8e231a4dd73252c4a7398e25ab20dba0a9df3df0c256617e004a9623676b9f3f9a3aa21f57c90ce",
36 | "signature":"00202029ab1a3326fe7d1e9ec36d7fab048e833c6c3cad37e1d5294695d28e9fd5583c23edaeecb596782a4c85bac27780623c1a9216202f3828991cbeebbeb049d9008270ea623d8d26c5ab89b621bac12c7fa8e9193e4057e16617f80cfc4279537f45169fb949deb3f9936400a130f6859aaa9c929e47c66610e59cc71a9f7ea79e81"
37 | }
38 | ```
39 |
40 | Sample output:
41 |
42 | ```
43 | valid
44 | ```
45 |
46 | Sample input (tampered message):
47 |
48 | ```
49 | {
50 | "msg": "Tampered message",
51 | "pubKey":"0078a6bb6732cb3134d2ca3912b2876fe005b20027037512cf972605f58ce5908471a1f9817c8d24290fcc943951f3113a7ee3716bd95f0b9c7326843a833ac6a0750021f08f88a6bd397525068300801521d2d97fea32f2c8b0c74dc8e231a4dd73252c4a7398e25ab20dba0a9df3df0c256617e004a9623676b9f3f9a3aa21f57c90ce",
52 | "signature":"00202029ab1a3326fe7d1e9ec36d7fab048e833c6c3cad37e1d5294695d28e9fd5583c23edaeecb596782a4c85bac27780623c1a9216202f3828991cbeebbeb049d9008270ea623d8d26c5ab89b621bac12c7fa8e9193e4057e16617f80cfc4279537f45169fb949deb3f9936400a130f6859aaa9c929e47c66610e59cc71a9f7ea79e81"
53 | }
54 | ```
55 |
56 | Sample output:
57 |
58 | ```
59 | invalid
60 | ```
61 |
--------------------------------------------------------------------------------
/digital-signatures/rsa-signatures.md:
--------------------------------------------------------------------------------
1 | # RSA Signatures
2 |
3 | The **RSA** public-key cryptosystem provides a **digital signature scheme** (sign + verify), based on the math of the **modular exponentiations** and discrete logarithms and the computational difficulty of [**the RSA problem**](https://en.wikipedia.org/wiki/RSA\_problem) (and its related integer factorization problem). The [**RSA sign / verify**](https://en.wikipedia.org/wiki/RSA\_\(cryptosystem\)#Signing\_messages) algorithm works as described below.
4 |
5 | ## Key Generation
6 |
7 | The RSA algorithm uses **keys** of size 1024, 2048, 4096, ..., 16384 bits. RSA supports also longer keys (e.g. 65536 bits), but the performance is too slow for practical use (some operations may take several minutes or even hours). For 128-bit security level, a 3072-bit key is required.
8 |
9 | The **RSA key-pair** consists of:
10 |
11 | * public key {_**n**_, _**e**_}
12 | * private key {_**n**_, _**d**_}
13 |
14 | The numbers _**n**_ and _**d**_ are typically big integers (e.g. 3072 bits), while _**e**_ is small, typically 65537.
15 |
16 | By definition, the RSA key-pairs has the following property:
17 |
18 | $$(m^e)^d \equiv (m^d)^e \equiv m \pmod n$$ for all _**m**_ in the range \[0..._**n**_)
19 |
20 | ## RSA Sign
21 |
22 | **Signing** a message _**msg**_ with the private key exponent _**d**_:
23 |
24 | 1. Calculate the message hash: _**h**_ = hash(_**msg**_)
25 | 2. Encrypt _**h**_ to calculate the signature: $$s = h^d \pmod n$$
26 |
27 | The hash _**h**_ should be in the range \[0..._**n**_). The obtained **signature** _**s**_ is an integer in the range \[0..._**n**_).
28 |
29 | ## RSA Verify Signature
30 |
31 | **Verifying** a signature _**s**_ for the message _**msg**_ with the public key exponent _**e**_:
32 |
33 | 1. Calculate the message hash: _**h**_ = hash(_**msg**_)
34 | 2. Decrypt the signature: $$h' = s^e \pmod n$$
35 | 3. Compare _**h**_ with _**h'**_ to find whether the signature is valid or not
36 |
37 | If the signature is correct, then the following will be true:
38 |
39 | $$h' = s^e \pmod n = (h^d)^e \pmod n = h$$
40 |
41 | The **RSA sign / verify algorithm** is pretty simple. Let's implement it with some code.
42 |
--------------------------------------------------------------------------------
/key-agreement-protocols.md:
--------------------------------------------------------------------------------
1 | # Key Agreement Protocols and Diffie-Hellman Key Exchange
2 |
3 | ...
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/key-exchange/README.md:
--------------------------------------------------------------------------------
1 | # Key Exchange and DHKE
2 |
3 | In cryptography [**key establishment**](http://cacr.uwaterloo.ca/hac/about/chap12.pdf) (**key exchange**, **key negotiation**) is a process or protocol, whereby a **shared secret** becomes available to two parties, for subsequent cryptographic use, typically for encrypted communication. Establishment techniques can be **key agreement** or **key transport** schemes.
4 |
5 | * In a **key agreement** scheme both parties contribute to the negotiation of the shared secret. Examples of key agreement schemes are Diffie-Hellman (**DHKE**) and Elliptic-Curve Diffie-Hellman (**ECDH**).
6 | * In a **key transport** scheme only one of the parties contributes to the shared secret and the other party obtains the secret from it. Key transport schemes are typically implemented through **public-key cryptography**, e.g. in the **RSA key exchange** the client encrypts a random session key by its private key and sends it to the server, where it is decrypted using the client's public key.
7 |
8 | By design [**key exchange**](https://en.wikipedia.org/wiki/Key\_exchange) schemes securely exchange cryptographic keys between two parties, in a way that noone else can obtain a copy of the keys. Typically, at the start of an **encrypted conversation** (e.g. during the **TLS handshake** phase), the parties first negotiate about the encryption keys (the shared secret) to be used during the conversation. **Key exchange schemes** are really important topic in the modern cryptography, because keys are exchanged hundreds of times by million devices and servers in Internet.
9 |
10 | A **key negotiation** (**key establishment**) scheme is executed every time when a laptop connects to the Wi-Fi network or a Web browser opens a Web site through the `https://` protocol. The key negotiation can be based on a annonymous key-exchange protocol (like DHKE), a password or pre-shared key (PSK), a digital certificate or a combination of many elements together. Some communication protocols establish a shared secret key once only, while others constantly change the secret key over the time.
11 |
12 | **Authenticated Key Exchange** (AKE) is the exchange of session key in a key exchange protocol which also **authenticates the identities** of the involved parties (e.g. through a password, public key or digital certificate). For example, if you connect to a password-protected WiFi network, an authenticated key agreement protocol is used, in most cases **password-authenticated key agreement** (PAKE). If you connect to a public WiFi network, **anonymous key agreement** is conducted.
13 |
14 | ## Key Exchange / Key Agreement Algorithms
15 |
16 | Many **cryptographic algorithms** exist for key exchange and key establishment. Some use public-key cryptosystems, others use simple key-exchange schemes (like the Diffie–Hellman Key Exchange), some involve server authentication, some involve client authentication, some use passwords, some use digital certificates or other authentication mechanisms.
17 |
18 | Examples of key exchange schemes are: [**Diffie–Hellman key exchange** (**DHКЕ**)](https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman\_key\_exchange) and [**Elliptic-curve Diffie–Hellman** (**ECDH**)](https://en.wikipedia.org/wiki/Elliptic-curve\_Diffie%E2%80%93Hellman), [**RSA-OAEP**](https://en.wikipedia.org/wiki/Optimal\_asymmetric\_encryption\_padding) and [**RSA-KEM**](https://tools.ietf.org/html/rfc5990) (RSA key transport), [**PSK** (pre-shared key)](https://en.wikipedia.org/wiki/Pre-shared\_key), [**SRP** (Secure Remote Password protocol)](https://en.wikipedia.org/wiki/Secure\_Remote\_Password\_protocol), [**FHMQV**](https://www.cryptopp.com/wiki/Fully\_Hashed\_Menezes-Qu-Vanstone) (Fully Hashed Menezes-Qu-Vanstone), [**ECMQV**](https://www.cryptopp.com/wiki/Elliptic\_Curve\_Menezes-Qu-Vanstone) (Ellictic-Curve Menezes-Qu-Vanstone) and [**CECPQ1**](https://en.wikipedia.org/wiki/CECPQ1) (quantum-safe key agreement).
19 |
20 | Let's start from the classical **Diffie–Hellman Key Exchange** (DHКЕ) scheme, which was one of the first public key protocols.
21 |
--------------------------------------------------------------------------------
/key-exchange/exercises-dhke-key-exchange.md:
--------------------------------------------------------------------------------
1 | # Exercises: DHKE Key Exchange
2 |
3 | ...
4 |
5 | TODO
6 |
7 | ...
8 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/README.md:
--------------------------------------------------------------------------------
1 | # MAC and Key Derivation
2 |
3 | **Message authentication codes** (**MAC**), **HMAC** (hash-based message authentication code) and **KDF** (key derivation functions) play important role in cryptography. Let's explain when we need **MAC**, how to calculate **HMAC** and how it is related to key derivation functions.
4 |
5 | ## Message Authentication Code (MAC)
6 |
7 | **M**essage **A**uthentication **C**ode (**MAC**) is cryptographic code, calculated by given **key** and given **message**:
8 |
9 | ```
10 | auth_code = MAC(key, msg)
11 | ```
12 |
13 | Typically, it behaves **like a hash function**: a minor change in the message or in the key results to totally different **MAC value**. It should be practically infeasible to change the key or the message and get the same **MAC value**. MAC codes, like hashes, are **irreversible**: it is impossible to recover the original message or the key from the MAC code. MAC algorithms are also known as "**keyed hash functions**", because they behave like a hash function with a key.
14 |
15 | For example, the MAC code can be calculated by the **HMAC-SHA256** algorithm like this:
16 |
17 | ```
18 | HMAC-SHA256('key', 'some msg') = 32885b49c8a1009e6d66662f8462e7dd5df769a7b725d1d546574e6d5d6e76ad
19 | ```
20 |
21 | The above HMAC-SHA256 calculation can be coded in Python like this:
22 |
23 | ```python
24 | import hashlib, hmac, binascii
25 |
26 | mac = hmac.new(b'key', b'some msg', hashlib.sha256).digest()
27 | print(binascii.hexlify(mac))
28 | ```
29 |
30 | Run the above code example: [https://repl.it/@nakov/HMAC-SHA256-in-Python](https://repl.it/@nakov/HMAC-SHA256-in-Python).
31 |
32 | The MAC code is **digital authenticity code**, like a **digital signature**, but with **pre-shared key**. We shall learn more about digital signing and digital signatures later.
33 |
34 | ## MAC Algorithms
35 |
36 | Many **algorithms** for calculating message authentication codes (MAC) exist in modern cryptography. The most popular are based on **hashing** algorithms, like [**HMAC**](https://en.wikipedia.org/wiki/HMAC) (Hash-based MAC, e.g. HMAC-SHA256) and [**KMAC**](https://www.cryptosys.net/manapi/api\_kmac.html) (Keccak-based MAC). Others are based on **symmetric ciphers**, like [**CMAC**](https://en.wikipedia.org/wiki/One-key\_MAC) (Cipher-based MAC), [**GMAC**](https://en.wikipedia.org/wiki/Galois/Counter\_Mode) (Galois MAC) and [**Poly1305**](https://en.wikipedia.org/wiki/Poly1305) (Bernstein's one-time authenticator). Other MAC algorithms include [**UMAC**](https://en.wikipedia.org/wiki/UMAC) (based on universal hashing), [**VMAC**](https://en.wikipedia.org/wiki/VMAC) (high-performance block cipher-based MAC) and [**SipHash**](https://en.wikipedia.org/wiki/SipHash) (simple, fast, secure MAC).
37 |
38 | ## When We Need MAC Codes?
39 |
40 | A sample scenario for using MAC codes is like this:
41 |
42 | * Two parties exchange somehow a certain secret **MAC key** (pre-shared **key**).
43 | * We receive a **msg** + **auth\_code** from somewhere (e.g. from Internet, from the blockchain, or from email message).
44 | * We want to be sure that the **msg** is **not tampered**, which means that both the **key** and **msg** are correct and match the MAC code.
45 | * In case of **tampered message**, the MAC code will be incorrect.
46 |
47 | 
48 |
49 | ## Authenticated Encryption: Encrypt / Decrypt Messages using MAC
50 |
51 | Another scenario to use **MAC codes** is for [**authenticated encryption**](https://en.wikipedia.org/wiki/Authenticated\_encryption)**:** when we **encrypt a message** and we want to be sure the **decryption password is correct** and the decrypted message is the same like the original message before encryption.
52 |
53 | * First, we **derive a key** from the password. We can use this key for the MAC calculation algorithm (directly or hashed for better security).
54 | * Next, we **encrypt the message** using the derived key and store the ciphertext in the output.
55 | * Finally, we calculate the **MAC code** using the derived key and the original message and we append it to the output.
56 |
57 | When we **decrypt the encrypted message** (ciphertext + MAC), we proceed as follows:
58 |
59 | * First, we **derive a key** from the password, entered by the user. It might be the correct password or wrong. We shall find out later.
60 | * Next, we **decrypt the message** using the derived key. It might be the original message or incorrect message (depends on the password entered).
61 | * Finally, we calculate a **MAC code** using the derived key + the decrypted message.
62 | * If the calculated MAC code matches the MAC code in the encrypted message, the **password is correct**.
63 | * Otherwise, it will be proven that the decrypted message is not the original message and this means that the **password is incorrect**
64 |
65 | Some **authenticated encryption algorithms** (such as **AES-GCM** and **ChaCha20-Poly1305**) integrate the MAC calculation into the encryption algorithm and the MAC verification into the decryption algorithm. We shall learn more about these algorithms later.
66 |
67 | The MAC is stored along with the ciphertext and it **does not reveal** the password or the original message. Storing the MAC code, visible to anyone is safe, and after decryption, we know whether the message is the original one or not (wrong password).
68 |
69 | ## MAC-Based Pseudo-Random Generator
70 |
71 | Another application of MAC codes is for **pseudo-random generator** functions. We can start from certain **salt** (constant number or the current date and time or some other randomness) and some **seed** number (last random number generated, e.g. **0**). We can calculate the **next\_seed** as follows:
72 |
73 | ```
74 | next_seed = MAC(salt, seed)
75 | ```
76 |
77 | This **next pseudo-random number** is "randomly changed" after each calculation of the above formula and we can use it to generate the next random number in certain range. We shall demonstrated a fully working example in the "[Secure Random Generators](../secure-random-generators/pseudo-random-numbers-examples.md)" chapter.
78 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/argon2.md:
--------------------------------------------------------------------------------
1 | # Argon2
2 |
3 | [**Argon2**](https://en.wikipedia.org/wiki/Argon2) is modern **ASIC-resistant** and **GPU-resistant** secure key derivation function. It has better password cracking resistance (when configured correctly) than **PBKDF2**, **Bcrypt** and **Scrypt** (for similar configuration parameters for CPU and RAM usage).
4 |
5 | ## Variants of Argon2
6 |
7 | The **Argon2** function has several variants:
8 |
9 | * **Argon2d** – provides strong GPU resistance, but has potential side-channel attacks (possible in very special situations).
10 | * **Argon2i** – provides less GPU resistance, but has no side-channel attacks.
11 | * **Argon2id** – **recommended** (combines the Argon2d and Argon2i).
12 |
13 | ## Config Parameters of Argon2
14 |
15 | **Argon2** has the following **config parameters**, which are very similar to Scrypt:
16 |
17 | * **password** `P`: the password (or message) to be hashed
18 | * **salt** `S`: random-generated salt (16 bytes recommended for password hashing)
19 | * **iterations** `t`: number of iterations to perform
20 | * **memorySizeKB** `m`: amount of memory (in kilobytes) to use
21 | * **parallelism** `p`: degree of parallelism (i.e. number of threads)
22 | * **outputKeyLength** `T`: desired number of returned bytes
23 |
24 | ## Argon2 - Example
25 |
26 | You can **play with the Argon2** password to key derivation function online here: [http://antelle.net/argon2-browser](http://antelle.net/argon2-browser).
27 |
28 | 
29 |
30 | ## Argon2 Calculation in Python - Example
31 |
32 | Now, we shall write some **code in Python** to derive a key from a password using the **Argon2** algorithm.
33 |
34 | First, install the Python package `argon2_cffi` using the command:
35 |
36 | ```
37 | pip install argon2_cffi
38 | ```
39 |
40 | Now, write the Python code to calculate Argon2:
41 |
42 | ```python
43 | import argon2, binascii
44 |
45 | hash = argon2.hash_password_raw(
46 | time_cost=16, memory_cost=2**15, parallelism=2, hash_len=32,
47 | password=b'password', salt=b'some salt', type=argon2.low_level.Type.ID)
48 | print("Argon2 raw hash:", binascii.hexlify(hash))
49 |
50 | argon2Hasher = argon2.PasswordHasher(
51 | time_cost=16, memory_cost=2**15, parallelism=2, hash_len=32, salt_len=16)
52 | hash = argon2Hasher.hash("password")
53 | print("Argon2 hash (random salt):", hash)
54 |
55 | verifyValid = argon2Hasher.verify(hash, "password")
56 | print("Argon2 verify (correct password):", verifyValid)
57 |
58 | try:
59 | argon2Hasher.verify(hash, "wrong123")
60 | except:
61 | print("Argon2 verify (incorrect password):", False)
62 | ```
63 |
64 | Run the above code example:[https://repl.it/@nakov/Argon2-in-Python](https://repl.it/@nakov/Argon2-in-Python).
65 |
66 | The above code first derives a "**raw hash**" (256-bit key), which is argon2-based key derivation, just like with scrypt. It also derives a "**argon2 hash**", which holds the algorithm parameters, along with random salt and derived key. The later is used for password storing and verification. Finally, the calculated hashes are tested agains a correct and wrong password.
67 |
68 | The **Argon2** calculation takes several **input configuration settings**: **time\_cost** (number of iterations), **memory\_cost** (memory to use in KB), **parallelism** (how many parallel threads to use), **hash\_len** (the size of the derived key), **salt\_len** (the size of the random generated salt, typically 128 bits / 16 bytes).
69 |
70 | Sample **output** from the above code execution:
71 |
72 | ```
73 | Argon2 raw hash: b'157f21dd3fdf7bafb76d2923ccaffa0b7be7cbae394709474d2bc66ee7b09d3e'
74 | Argon2 hash (random salt): $argon2id$v=19$m=32768,t=16,p=2$Rfy6J41W9idBU+n/8sZc6Q$i3QYYPtoogIAw78I2qqlUQ8vjzUXGG1V6QsBOq2NIp4
75 | Argon2 verify (correct password): True
76 | Argon2 verify (incorrect password): False
77 | ```
78 |
79 | Note that the **argon2 hash** in the above output is written in a standardized format, which holds the Argon2 algorithm config **parameters** + the derived **key** + the random **salt**. By design, the salt and the derived key _should be different at each code execution_.
80 |
81 | Try to **execute the above code several times** to ensure that the **derived key** will be the same (because the salt is fixed) and the derived **argon2 hash** will be different at each execution (because a random salt is generated internally by the algorithm).
82 |
83 | Try to change the **time\_cost** or the **memory\_cost** settings and see how they affect the **execution time** for the key derivation.
84 |
85 | ## Storing Algorithm Settings + Salt + Hash Together
86 |
87 | In many applications, frameworks and tools, **Argon2 encrypted passwords are stored together with the algorithm settings and salt**, into a single string (in certain format, like it was shown above), consisting of several parts, separated by `$` character. For example, the password `p@ss~123` can be stored in the Argon2 standard format like this (several examples are given, to make the pattern apparent):
88 |
89 | ```
90 | $argon2d$v=19$m=1024,t=16,p=4$c2FsdDEyM3NhbHQxMjM$2dVtFVPCezhvjtyu2PaeXOeBR+RUZ6SqhtD/+QF4F1o
91 | $argon2d$v=19$m=1024,t=16,p=4$YW5vdGhlcnNhbHRhbm90aGVyc2FsdA$KB7Nj7kK21YdGeEBQy7R3vKkYCz1cdR/I3QcArMhl/Q
92 | $argon2i$v=19$m=8192,t=32,p=1$c21hbGxzYWx0$lmO1aPPy3x0CcvrKpFLi1TL/uSVJ/eO5hPHiWZFaWvY
93 | ```
94 |
95 | All the above hashes hold the same password, but with different algotihm settings and different salt.
96 |
97 | ## When to Use Argon2?
98 |
99 | When configured properly **Argon2** is considered a highly secure KDF function, **one of the best** available in the industry, so you can use it as general purpose password to key derivation algorithm, e.g. to when encrypting wallets, documents, files or app passwords. In the general case **Argon2 is recommended** over **Scrypt**, **Bcrypt** and **PBKDF2**.
100 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/bcrypt.md:
--------------------------------------------------------------------------------
1 | # Bcrypt
2 |
3 | [**Bcrypt**](https://en.wikipedia.org/wiki/Bcrypt) is another cryptographic KDF function, **older than Scrypt**, and is **less resistant** to ASIC and GPU attacks. It provides configurable iterations count, but uses constant memory, so it is easier to build hardware-accelerated password crackers.
4 |
5 | ## Bcrypt - Example
6 |
7 | You can play with **Bcrypt** here: [https://www.dailycred.com/article/bcrypt-calculator](https://www.dailycred.com/article/bcrypt-calculator).
8 |
9 | 
10 |
11 | ## Storing Algorithm Settings + Salt + Hash Together
12 |
13 | In many applications, frameworks and tools (e.g. in the database of WordPress sites), **Bcrypt encrypted passwords are stored together with the algorithm settings and salt**, into a single string (in certain format), consisting of several parts, separated by `$` character. For example, the password `p@ss~123` can be stored in the Bcrypt encrypted format like this (several examples are given, to make the pattern apparent):
14 |
15 | ```
16 | $2a$07$wHirdrK4OLB0vk9r3fiseeYjQaCZ0bIeKY9qLsNep/I2nZAXbOb7m
17 | $2a$12$UqBxs0PN/u106Fio1.FnDOhSRJztLz364AwpGemp1jt8OnJYNsr.e
18 | $2a$12$8Ov4lfmZZbv8O5YKrXXCu.mdH9Dq9r72C5GnhVZbGNsIzTr8dSUfm
19 | ```
20 |
21 | ## When to Use Bcrypt?
22 |
23 | When configured properly **Bcrypt** is considered a **secure KDF function** and is widely used in practice. It is considered that **Scrypt is more secure than Bcrypt,** so modern applications should **prefer Scrypt** (or **Argon2**) instead of **Bcrypt**. Still, this recommendation is disputable, but I personally prefer **Argon2**.
24 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/exercises-calculate-hmac.md:
--------------------------------------------------------------------------------
1 | # Exercises: Calculate HMAC
2 |
3 | Write a program to **calculate HMAC-SHA-384** of given text **message** by given **key**. Write your code in programming language of choice.
4 |
5 | | | |
6 | | ---------------------------------------- | ------------------------------------------------------------------------------------------------ |
7 | | **Input** | **Output** |
8 | | **Message**: hello **Key**: cryptography | 83d1c3d3774d8a32b8ea0460330c16d1b2e3e5c0ea86ccc2d70e603aa8c8151d675dfe339d83f3f495fab226795789d4 |
9 | | **Message**: hello **Key**: again | 4c549a549aa037e0fb651569bf271faa23cfa20e8a9d21438a6ff5bf6be916bebdbaa48001e0cd6941ec74cd02be70e5 |
10 |
11 | **Hints**: follow the Python examples, given earlier in this section or search in Internet.
12 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/exercises-password-encryption.md:
--------------------------------------------------------------------------------
1 | # Exercises: Password Encryption
2 |
3 | In this exercise you will design a **user authentication system** for modern a Web or mobile app, following the industry's best practices. Implement user **register** / **login** / **change password** functionality, using the **Argon2** secure password hashing with **random salt**. Keep the **usernames** and their corresponding Argon2 hashed **passwords** (along with the Argon2 algorithm parameters and the random salt) as key-value pairs in the form **username:argon2hash**, in a simple JSON document. In the real world you may use a **database** instead of **JSON** document, but let's keep the exercise simple.
4 |
5 | ...
6 |
7 | **TODO**
8 |
9 | ...
10 |
11 | ## Implement "Register User"
12 |
13 | Input: username + password + JSON holding all current accounts.
14 |
15 | Output: modified JSON file or "user exists" exception.
16 |
17 | ...
18 |
19 | **TODO**
20 |
21 | ...
22 |
23 | ## Implement "User Login"
24 |
25 | Input: username + password + JSON holding all current accounts.
26 |
27 | Output: correct / incorrect login.
28 |
29 | ...
30 |
31 | **TODO**
32 |
33 | ...
34 |
35 | ## Implement "Change Password"
36 |
37 | Input: username + old password + new password + JSON holding all current accounts.
38 |
39 | Output: modified JSON file or "user exists" exception.
40 |
41 | ...
42 |
43 | **TODO**
44 |
45 | ...
46 |
47 | ## Implement "Reset Password"
48 |
49 | Input: username + new password + JSON holding all current accounts.
50 |
51 | Output: modified JSON file or "user exists" exception.
52 |
53 | ...
54 |
55 | **TODO**
56 |
57 | ...
58 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/exercises-scrypt-key-derivation.md:
--------------------------------------------------------------------------------
1 | # Exercises: Scrypt Key Derivation and Password Hashing
2 |
3 | In this exercise, we shall use **Scrypt** to derive keys by password.
4 |
5 | ## Derive a Key by Password using Scrypt
6 |
7 | Write a program to **calculate 128-bit key** by given string **password** and **salt** \(in hex\), using the **Scrypt** algorithm. Use the following Scrypt settings: **16384** iterations, block size **16**, parallel factor **1**. The output from your algorithm is the **derived-key** \(in hex\). Write your code in programming language of choice.
8 |
9 | | **Input** | **Output** |
10 | | :--- | :--- |
11 | | **Password:** p@ss~123**
Salt:** 546865207175696a | ce6e7b86490db184499f82639298dee3 |
12 | | **Password:** p@ss~123**
Salt:** 8ac8ccf364f234fa | baa1de36036d8a69b7340d314fcd7895 |
13 |
14 | **Notes**: if you use **Python** and **`pip install scrypt`**, you might need to install first [**OpenSSL**](https://www.openssl.org/).
15 |
16 | **Hint**: modify the Python code from the Scrypt example.
17 |
18 | ## Scrypt: Encrypt a Password
19 |
20 | Write a program to encrypt given string password using the **Scrypt** algorithm (**16384** iterations, block size **16**, parallel factor **1**, using **random 64-bit salt**, derived key length = **256 bits**). Print the output in the following format:
21 | ```
22 | $scrypt$16384$16$1$salt$hash
23 | ```
24 |
25 | Sample input and output are given below. Note that due to the **randomness in the salt**, your code will produce similar, but different result:
26 |
27 | | **Input** | **Output** |
28 | | :--- | :--- |
29 | | p@ss~123 | $scrypt$16384$16$1$546865207175696a$ce6e7b86490db184499f82639298dee38087470c11e01236f10740545ea54bd2 |
30 | | p@ss~123 | $scrypt$16384$16$1$8ac8ccf364f234fa$baa1de36036d8a69b7340d314fcd78954dc4e8fb271b0733396047a71651bb0e |
31 | | hello^123 | $scrypt$16384$16$1$1122334455667788$b1d1c1340ff958f09cfa37d35f4fb6edb65ca40b9abfbc19e0dad509236b38fe |
32 |
33 | **Hint**: modify the Python code from the Scrypt example and format the code as shown in the sample output.
34 |
35 | ## Scrypt: Verify a Password
36 |
37 | Write a program to **verify a password** against given encrypted **Scrypt** password in the following format:
38 | ```
39 | $scrypt$16384$16$1$salt$hash
40 | ```
41 |
42 | Take as input the **Scrypt encrypted password string** + the **password** for verification. Print as output either `true` or `false`. Use this program to verify the encrypted passwords from your previous program.
43 |
44 | Sample input and output:
45 |
46 | | **Input** | **Output** |
47 | | :--- | :--- |
48 | |p@ss~123
$scrypt$16384$16$1$546865207175696a$ce6e7b86490db184499f82639298dee38087470c11e01236f10740545ea54bd2 |true|
49 | |wrong!pass
$scrypt$16384$16$1$546865207175696a$ce6e7b86490db184499f82639298dee38087470c11e01236f10740545ea54bd2|false|
50 | |hello^123
$scrypt$16384$16$1$1122334455667788$b1d1c1340ff958f09cfa37d35f4fb6edb65ca40b9abfbc19e0dad509236b38fe |true|
51 |
52 | **Hints**:
53 | * Read the **Scrypt** algorithm settings from the input encrypted string.
54 | * Using the algorithm settings and the **salt** from the input, derive a **256-bit key** from the **input password**.
55 | * Compare the **derived key** with the **hash** from the input.
56 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/hmac-and-key-derivation.md:
--------------------------------------------------------------------------------
1 | # HMAC and Key Derivation
2 |
3 | Simply calculating `hash_func(key + msg)` to obtain a MAC (message authentication code) is considered **insecure** (see the [details](https://en.wikipedia.org/wiki/HMAC#Design\_principles)). It is recommended to use the **HMAC algorithm instead**, e.g. `HMAC-SHA256` or `HMAC-SHA3-512` or other secure MAC algorithm.
4 |
5 | ## What is HMAC?
6 |
7 | [**HMAC**](https://en.wikipedia.org/wiki/HMAC) = **H**ash-based **M**essage **A**uthentication **C**ode (MAC code, calculated using a cryptographic hash function):
8 |
9 | ```
10 | HMAC(key, msg, hash_func) -> hash
11 | ```
12 |
13 | The results MAC code is a **message hash** mixed with a secret key. It has the cryptographic properties of hashes: **irreversible**, **collision resistant**, etc.
14 |
15 | The `hash_func` can be any cryptographic hash function like `SHA-256`, `SHA-512`, `RIPEMD-160`, `SHA3-256` or `BLAKE2s`.
16 |
17 | **HMAC** is used for message **authenticity**, message **integrity** and sometimes for **key derivation**.
18 |
19 | ## Key Derivation Functions (KDF)
20 |
21 | **Key derivation function** (KDF) is a function which transforms a variable-length password to fixed-length key (sequence of bits):
22 |
23 | ```
24 | function(password) -> key
25 | ```
26 |
27 | As **very simple KDF function**, we can use SHA256: just hash the password. Don't do this, because it is **insecure**. Simple hashes are vulnerable to **dictionary attacks**.
28 |
29 | As more complicated KDF function, you can derive a password by calculating **HMAC(salt, msg, SHA256)** using some random value called "**salt**", which is stored along with the derived key and used later to derive the same key again from the password.
30 |
31 | Using **HKDF (HMAC-based key derivation)** for key derivation is **less secure** than modern KDFs, so experts recommend using stronger key derivation functions like [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2), [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [Scrypt](https://en.wikipedia.org/wiki/Scrypt) and [Argon2](https://en.wikipedia.org/wiki/Argon2). We shall discuss all these KDF functions later.
32 |
33 | ## HMAC Calculation - Example
34 |
35 | To get a better idea of **HMAC** and how it is calculated, try this online tool: [https://www.freeformatter.com/hmac-generator.html](https://www.freeformatter.com/hmac-generator.html)
36 |
37 | 
38 |
39 | Play with calculating **HMAC('sample message', '12345', 'SHA256')**:
40 |
41 | ```
42 | HMAC('sample message', '12345', 'SHA256') =
43 | 'ee40ca7bc90df844d2f5b5667b27361a2350fad99352d8a6ce061c69e41e5d32'
44 | ```
45 |
46 | Try the above example yourself.
47 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/hmac-calculation-examples.md:
--------------------------------------------------------------------------------
1 | # HMAC Calculation - Examples
2 |
3 | In **Python** we can **calculate HMAC** codes as follows (using the `hashlib` and `hmac` libraries):
4 |
5 | ```python
6 | import hashlib, hmac, binascii
7 |
8 | def hmac_sha256(key, msg):
9 | return hmac.new(key, msg, hashlib.sha256).digest()
10 |
11 | key = b"12345"
12 | msg = b"sample message"
13 | print(binascii.hexlify(hmac_sha256(key, msg)))
14 | ```
15 |
16 | Run the above code example: \*\*\*\*[https://repl.it/@nakov/HMAC-SHA256-Examples](https://repl.it/@nakov/HMAC-SHA256-Examples-in-Python).
17 |
18 | The above code will calculate and print the expected HMAC code (like in our previous example):
19 |
20 | ```
21 | ee40ca7bc90df844d2f5b5667b27361a2350fad99352d8a6ce061c69e41e5d32
22 | ```
23 |
24 | Try the code yourself and play with it.
25 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/kdf-deriving-key-from-password.md:
--------------------------------------------------------------------------------
1 | # KDF: Deriving Key from Password
2 |
3 | Now let's explain in details how to **securely derive a key from a password** and the most popular **key derivation functions** (**KDFs**) used in practice: [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2), [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [Scrypt](https://en.wikipedia.org/wiki/Scrypt) and [Argon2](https://en.wikipedia.org/wiki/Argon2).
4 |
5 | **\[TODO: explain the Linux crypt: SHA-512 key derivation]**
6 |
7 | We shall discuss the strong and weak sides of the above mentioned KDFs and when to use them.
8 |
9 | ## Key Derivation Functions - Concepts
10 |
11 | In cryptography we often use **passwords** instead of **binary keys**, because passwords are easier to remember, to write down and can be shorter.
12 |
13 | When a certain algorithm needs a **key** (e.g. for encryption or for digital signing) a **key derivation function** (password -> key) is needed.
14 |
15 | We already noted that using `SHA-256(password)` as key-derivation is insecure! It is vulnerable to many attacks: **brute-forcing**, **dictionary attacks**, **rainbow attacks** and others, which may reverse the hash in practice and attacker can obtain the password.
16 |
17 | ## Cryptographic Key Derivation Functions
18 |
19 | [PBKDF2](https://en.wikipedia.org/wiki/PBKDF2), [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [Scrypt](https://en.wikipedia.org/wiki/Scrypt) and [Argon2](https://en.wikipedia.org/wiki/Argon2) are significantly stronger key derivation functions and are designed to survive password guessing (brute force) attacks.
20 |
21 | By design **secure key derivation functions** use **salt** (random number, which is different for each key derivation) + **many iterations** (to speed-down eventual password guessing process). This is a process, known as [**key stretching**](https://en.wikipedia.org/wiki/Key\_stretching).
22 |
23 | To calculate a secure KDF it takes some **CPU time** to derive the key (e.g. 0.2 sec) + some **memory (RAM)**. Thus deriving the key is "computationally expensive", so password cracking will also be computationally expensive.
24 |
25 | When a modern KDF function is used with appropriate config parameters, **cracking passwords** will be **slow** (e.g. 5-10 attempts per second, instead of thousands or millions attempts per second).
26 |
27 | All of the above mentioned key-derivation algorithms ([PBKDF2](https://en.wikipedia.org/wiki/PBKDF2), [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt), [Scrypt](https://en.wikipedia.org/wiki/Scrypt) and [Argon2](https://en.wikipedia.org/wiki/Argon2)) are not patented and **royalty-free** for public use.
28 |
29 | Let's learn more about these modern KDF.
30 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/linux-crypt.md:
--------------------------------------------------------------------------------
1 | # Linux crypt()
2 |
3 | ... ...
4 |
5 | **\[TODO: write a few words about the crypt() function in Linux]**
6 |
7 | See [https://en.wikipedia.org/wiki/Crypt\_(C](https://en.wikipedia.org/wiki/Crypt\_\(C))
8 |
9 | ... ...
10 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/modern-key-derivation-functions.md:
--------------------------------------------------------------------------------
1 | # Modern Key Derivation Functions
2 |
3 | **PBKDF2** has a major weakness: it is **not GPU-resistant** and **not ASIC-resistant**, because it uses relatively small amount of RAM and can be efficiently implemented on GPU (graphics cards) or **ASIC** (specialized hardware).
4 |
5 | Modern key-derivation functions (KDF) like [**Scrypt**](https://en.wikipedia.org/wiki/Scrypt) and [**Argon2**](https://en.wikipedia.org/wiki/Argon2) are designed to be **resistant** to **dictionary attacks**, **GPU attacks** and **ASIC attacks**. These functions derive a key (of fixed length) from a password (text) and need a lot memory (RAM), which does not allow fast parallel computations on GPU or ASIC hardware.
6 |
7 | Algorithms like **Bcrypt**, **Scrypt** and **Argon2** are considered more **secure** KDF functions. They use **salt** + many **iterations** + a lot of **CPU** + a lot of **RAM** memory and this makes very hard to design a custom hardware to significantly speed up password cracking.
8 |
9 | It takes a lot of **CPU time** to derive the key (e.g. 0.2 sec) + a lot of **RAM memory** (e.g. 1GB). The calculation process is memory-dependent, so **the memory access is the bottleneck** of the calculations. Faster RAM access will speed-up the calculations.
10 |
11 | When a lot of CPU and RAM is used to derive the key from given password, **cracking passwords is slow** and inefficient (e.g. 5-10 attempts / second), even when using very good password cracking hardware and software. The goal of the modern KDF functions is to make practically infeasible to perform a brute-force attack to reverse the password from its hash.
12 |
13 | Let's discuss in more details **Scrypt**, **Bcrypt** and **Argon2**.
14 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/pbkdf2.md:
--------------------------------------------------------------------------------
1 | # PBKDF2
2 |
3 | **PBKDF2** is a simple cryptographic key derivation function, which is resistant to [dictionary attacks](https://en.wikipedia.org/wiki/Dictionary\_attack) and [rainbow table attacks](https://en.wikipedia.org/wiki/Rainbow\_table). It is based on iteratively deriving **HMAC** many times with some padding. The **PBKDF2** algorithm is described in the Internet standard [RFC 2898 (PKCS #5)](http://ietf.org/rfc/rfc2898.txt).
4 |
5 | **PBKDF2** takes several **input parameters** and produces the derived **key** as output:
6 |
7 | ```
8 | key = pbkdf2(password, salt, iterations-count, hash-function, derived-key-len)
9 | ```
10 |
11 | Technically, the **input data** for **PBKDF2** consists of:
12 |
13 | * `password` – array of bytes / string, e.g. "_p@$Sw0rD\~3_" (8-10 chars minimal length is recommended)
14 | * `salt` – securely-generated random bytes, e.g. "_df1f2d3f4d77ac66e9c5a6c3d8f921b6_" (minimum 64 bits, 128 bits is recommended)
15 | * `iterations-count`, e.g. 1024 iterations
16 | * `hash-function` for calculating **HMAC**, e.g. `SHA256`
17 | * `derived-key-len` for the output, e.g. 32 bytes (256 bits)
18 |
19 | The **output data** is the **derived key** of requested length (e.g. 256 bits).
20 |
21 | ## PBKDF2 and Number of Iterations
22 |
23 | **PBKDF2** allows to configure the number of **iterations** and thus to configure the time required to derive the key.
24 |
25 | * **Slower key derivation** means high login time / slower decryption / etc. and **higher resistance** to password cracking attacks.
26 | * **Faster key derivation** means short login time / faster decryption / etc. and **lower resistance** to password cracking attacks.
27 | * **PBKDF2** is **not resistant** to [GPU attacks](https://security.stackexchange.com/questions/118147/how-are-gpus-used-in-brute-force-attacks) (parallel password cracking using video cards) and to [ASIC attacks](https://en.wikipedia.org/wiki/Custom\_hardware\_attack) (specialized password cracking hardware). This is the main motivation behind more modern KDF functions.
28 |
29 | ## PBKDF2 - Example
30 |
31 | Try **PBKDF2 key derivation** online here: [https://asecuritysite.com/encryption/PBKDF2z](https://asecuritysite.com/encryption/PBKDF2z).
32 |
33 | 
34 |
35 | Try to **increase the iterations count** to see how this affects the speed of key derivation.
36 |
37 | ## PBKDF2 Calculation in Python - Example
38 |
39 | Now, we shall write some **code in Python** to derive a key from a password using the **PBKDF2** algorithm.
40 |
41 | Firstly, install the Python package `backports.pbkdf2` using the command:
42 |
43 | ```
44 | pip install backports.pbkdf2
45 | ```
46 |
47 | Now, write the Python code to calculate PBKDF2:
48 |
49 | ```python
50 | import os, binascii
51 | from backports.pbkdf2 import pbkdf2_hmac
52 |
53 | salt = binascii.unhexlify('aaef2d3f4d77ac66e9c5a6c3d8f921d1')
54 | passwd = "p@$Sw0rD~1".encode("utf8")
55 | key = pbkdf2_hmac("sha256", passwd, salt, 50000, 32)
56 | print("Derived key:", binascii.hexlify(key))
57 | ```
58 |
59 | Run the above code example: [https://repl.it/@nakov/PBKDF2-in-Python](https://repl.it/@nakov/PBKDF2-in-Python).
60 |
61 | The **PBKDF2** calculation function takes several **input parameters**: **hash function** for the HMAC, the **password** (bytes sequence), the **salt** (bytes sequence), **iterations** count and the output **key length** (number of bytes for the derived key).
62 |
63 | The **output** from the above code execution is the following:
64 |
65 | ```
66 | Derived key: b'52c5efa16e7022859051b1dec28bc65d9696a3005d0f97e506c42843bc3bdbc0'
67 | ```
68 |
69 | Try to change the number of **iterations** and see whether and how the **execution time** changes.
70 |
71 | ## When to Use PBKDF2?
72 |
73 | Today **PBKDF2** is considered old-fashioned and less secure than modern KDF functions, so it is recommended to use **Bcrypt**, **Scrypt** or **Argon2** instead. We shall explain all these KDF functions in details later in this section.
74 |
--------------------------------------------------------------------------------
/mac-and-key-derivation/scrypt.md:
--------------------------------------------------------------------------------
1 | # Scrypt
2 |
3 | [**Scrypt**](https://en.wikipedia.org/wiki/Scrypt) ([RFC 7914](https://tools.ietf.org/html/rfc7914.html)) is a strong cryptographic key-derivation function (KDF). It is memory-intensive, designed to prevent **GPU**, **ASIC** and **FPGA** attacks (highly efficient password cracking hardware).
4 |
5 | The **Scrypt** algorithm takes several **input parameters** and produces the derived **key** as output:
6 |
7 | ```
8 | key = Scrypt(password, salt, N, r, p, derived-key-len)
9 | ```
10 |
11 | ## Scrypt Parameters
12 |
13 | The **Scrypt config parameters** are:
14 |
15 | * `N` – iterations count (affects memory and CPU usage), e.g. 16384 or 2048
16 | * `r` – block size (affects memory and CPU usage), e.g. 8
17 | * `p` – parallelism factor (threads to run in parallel - affects the memory, CPU usage), usually 1
18 | * `password`– the input password (8-10 chars minimal length is recommended)
19 | * `salt` – securely-generated random bytes (64 bits minimum, 128 bits recommended)
20 | * `derived-key-length` - how many bytes to generate as output, e.g. 32 bytes (256 bits)
21 |
22 | The **memory** in Scrypt is accessed in strongly **dependent order** at each step, so the memory access speed is the algorithm's bottleneck. The **memory required** to compute Scrypt key derivation is calculated as follows:
23 |
24 | ```
25 | Memory required = 128 * N * r * p bytes
26 | ```
27 |
28 | Example: e.g. 128 \* N \* r \* p = 128 \* 16384 \* 8 \* 1 = 16 MB\
29 | (or 128 \* N \* r \* p = 128 \* 2048 \* 8 \* 1 = 2 MB)
30 |
31 | **Choosing parameters** depends on how much you want to wait and what level of security (password cracking resistance) do you want to achieve:
32 |
33 | * Sample parameters for **interactive login**: N=16384, r=8, p=1 (RAM = 2 MB). For interactive login you most probably do not want to wait more than a 0.5 seconds, so the computations should be very slow. Also at the server side, it is usual that many users can login in the same time, so slow Scrypt computation will slow down the entire system.
34 | * Sample parameters for **file encryption**: N=1048576, r=8, p=1 (RAM = 1 GB). When you encrypt your hard drive, you will unlock the encrypted data in rare cases, usually not more than 2-3 times per day, so you may want to wait for 2-3 seconds to increase the security.
35 |
36 | You can perform tests and choose the Scrypt parameters yourself during the design and development of your app or system. Always try to use the **fastest possible implementation of Scrypt** for your language and platform, because crackers will definitely use it. Some implementations (e.g. in Python) may be 100 times slower than the fastest ones!
37 |
38 | In the **MyEtherWallet** crypto wallet, the default Scrypt parameters are N=8192, r=8, p=1. These settings are not strong enough for crypto wallets, but this is how it works. The solution is to use long and complex password to avoid password cracking attacks.
39 |
40 | ## Scrypt - Example
41 |
42 | You can play with **Scrypt** key derivation online here: [https://8gwifi.org/scrypt.jsp](https://8gwifi.org/scrypt.jsp).
43 |
44 | 
45 |
46 | ## Scrypt Calculation in Python - Example
47 |
48 | Now, we shall write some **code in Python** to derive a key from a password using the **Scrypt** algorithm.
49 |
50 | First, install the Python package `scrypt` using the command:
51 |
52 | ```
53 | pip install scrypt
54 | ```
55 |
56 | Note that the `scrypt` package depends on OpenSSL, so first install it in its default location (e.g. in `C:\OpenSSL-Win64` in Windows), then install the **scrypt** Python package.
57 |
58 | Now, after the `scrypt` package is successfully installed, write the Python code to calculate a Scrypt hash:\
59 | (_Note, we have chosen smaller number for iterations count. We did that just to increase the following example execution speed. In common usage, a higher iterations count is recommended, e.g. 16384 - see above._)
60 |
61 | ```python
62 | import pyscrypt
63 |
64 | salt = b'aa1f2d3f4d23ac44e9c5a6c3d8f9ee8c'
65 | passwd = b'p@$Sw0rD~7'
66 | key = pyscrypt.hash(passwd, salt, 2048, 8, 1, 32)
67 | print("Derived key:", key.hex())
68 | ```
69 |
70 | Run the above code example: [https://repl.it/@nakov/Scrypt-in-Python](https://repl.it/@nakov/Scrypt-in-Python).
71 |
72 | The **Scrypt** calculation function takes several **input parameters**: the **password** (bytes sequence), the **salt** (bytes sequence), **iterations** count, **block size** for each iteration, **parallelism** factor and the output **key length** (number of bytes for the derived key).
73 |
74 | The **output** from the above code execution is the following:
75 |
76 | ```
77 | Derived key: b'e813a6f6ccc4e9110193bf9efb7c0a489d76655f9e36629dccbeaf2a73bc0c6f'
78 | ```
79 |
80 | Try to change the number of **iterations** or the **block size** and see how they affect the **execution time**. Have in mind that the above Python implementation is not very fast. You may find fast Scrypt implementation in Internet.
81 |
82 | ## Storing Algorithm Settings + Salt + Hash Together
83 |
84 | In many applications, frameworks and tools, **Scrypt encrypted passwords are stored together with the algorithm settings and salt**, into a single string (in certain format), consisting of several parts, separated by `$` character. For example, the password `p@ss~123` can be stored in the Scrypt standard format like this (several examples are given, to make the pattern apparent):
85 |
86 | ```
87 | 16384$8$1$kytG1MHY1KU=$afc338d494dc89be40e317788e3cd9166d066709db0e6481f0801bd918710f46
88 | 16384$8$1$5gFGlElztY0=$560f6229356c281a525fad4e2fc4c209bb55c21dec789381335a32bb84888a5a
89 | 32768$8$4$VGhlIHF1aWo=$54d657cec8b3aaca675b407e790bccf1dddb0a23665cd5f994820a736d4b58ba
90 | ```
91 |
92 | ## When to Use Scrypt?
93 |
94 | When configured properly **Scrypt** is considered a highly secure KDF function, so you can use it as general purpose password to key derivation algorithm, e.g. when encrypting wallets, files or app passwords.
95 |
--------------------------------------------------------------------------------
/more-cryptographic-concepts/README.md:
--------------------------------------------------------------------------------
1 | # More Cryptographic Concepts
2 |
3 | ...
4 |
5 | ## Digital Certificates, the X.509 Standard and PKI
6 |
7 | ...
8 |
9 | [https://cryptography.io/en/latest/x509/](https://cryptography.io/en/latest/x509/)
10 |
11 | ## Transport Layer Security (TLS) and SSL
12 |
13 | ...
14 |
15 | [https://en.wikipedia.org/wiki/Transport\_Layer\_Security](https://en.wikipedia.org/wiki/Transport\_Layer\_Security)
16 |
17 | A cipher suite is a set of algorithms that help secure a network connection that uses Transport Layer Security (TLS) or its now-deprecated predecessor Secure Socket Layer (SSL). The set of algorithms that cipher suites usually contain include: a **key exchange** algorithm, a **symmetric encryption** algorithm, and a message **authentication code** (MAC) algorithm.
18 |
19 | ## External Authentication and OAuth
20 |
21 | ...
22 |
23 | ## Two-Factor Authentication and One-Time Passwords
24 |
25 | Multi-Factor authentication adds additional layers of identity authentication. Usually, those factors should be added to some of the following categories:
26 |
27 | * What I know
28 | * What I have
29 | * What I am
30 |
31 | Two-Factor Authentication requires two of those three categories to be implemented. The most common case of **Two-Factor Authentication** is a **user password** and a device on which will be sent/generate **one-time-password**. To generate a one-time-password (OTP) the HMAC-based One-time Password algorithm is used.
32 |
33 | ### HMAC-based One-time Password (HOTP)
34 |
35 | The **HOTP** algorithm is based on [HMAC](https://en.wikipedia.org/wiki/HMAC) and provides a symmetric generation of human-readable passwords, each used for only one authentication attempt. The key parameter of HTOP is a secret which has to be exchanged between the parties in advance:
36 |
37 | ```
38 | HTOP(has_function, secret, value_length) -> htop
39 | htop.generate() -> auth_code
40 | htop.validate(auth_code) -> true/false
41 | ```
42 |
43 | The **hash\_func** can be any cryptographic hash function. The **secret** is the arbitrary byte string which must be shared between the parties and kept private. **value\_length** defines the **auth\_code** length.
44 |
45 | ### Counter-based One-Time Password algorithm (COTP)
46 |
47 | In the **COTP** scenario the HTOP function contains an internal counter. In order for parties to successfully authenticate each other they have to keep their counters in sync. Each time HOTP is requested to generate an **auth\_code** the counter increments.
48 |
49 | ### Time-based One-Time Password Algorithm (TOTP)
50 |
51 | Time-based One-Time Password Algorithm (**TOTP**) is an extension of COTP, where the **counter** is the current time, defined as **Unix time**. The **time-interval** is another parameter used for the generation of TOTP, which defines a period of time of which a given authentication code will be valid.
52 |
53 | ```
54 | htop_counter = (current_time - initial_time) / time_interval
55 | ```
56 |
57 | For TOTP to work correctly both parties need to have synchronized clocks with minimal verification time-step window (delay based on user's input, network latency, and clock time deviation).
58 |
59 | ```
60 | otp = TOTP(hash_function(secret), htop_counter)
61 | ```
62 |
63 | ### Time-based One-Time Password in Practice
64 |
65 | A popular use case of Two-Factor Authentication is the **Google Authenticator**. A server generates a secret and shares it as a QR code with the client. The client scan and store the secret in the [Google Authenticator](https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2) application on a phone. After that, the server and the phone start to generate the same one-time passwords.
66 |
67 | An example of a web-based JavaScript [example](http://blog.tinisles.com/2011/10/google-authenticator-one-time-password-algorithm-in-javascript/) for using and testing TOTP:
68 |
69 | 
70 |
71 | ## Infected Cryptosystems and Crypto Backdoors
72 |
73 | [https://en.wikipedia.org/wiki/Kleptography](https://en.wikipedia.org/wiki/Kleptography)
74 |
75 | ## Other Cryptographic Concepts and Standards
76 |
77 | Just to mention, the practical cryptography is endless. This is a list of crypto concepts, algorithm, protocols and standards that we will not going to explain in this book, but you can read about them from the provided links:
78 |
79 | * Kerberos - ...
80 | * IPsec - ...
81 | * WiFi cryptography standards - ...
82 | * PGP - ...
83 | * S/MIME - ...
84 | * JSON Web Tokens (JWT)
85 | * Object Identifiers (OID) - [https://en.wikipedia.org/wiki/Object\_identifier](https://en.wikipedia.org/wiki/Object\_identifier), e.g. the algorithm "SHA-256" has OID "2.16.840.1.101.3.4.2.1".
86 | * Cryptography Best Practices: [https://gist.github.com/atoponce/07d8d4c833873be2f68c34f9afc5a78a](https://gist.github.com/atoponce/07d8d4c833873be2f68c34f9afc5a78a)
87 |
--------------------------------------------------------------------------------
/more-cryptographic-concepts/digital-certificates-example.md:
--------------------------------------------------------------------------------
1 | # Digital Certificates - Example
2 |
3 | ...
4 |
5 | Generate X.509 self-signed certificate
6 |
7 | Dump certificate data from the Python code
8 |
9 | ...
10 |
--------------------------------------------------------------------------------
/more-cryptographic-concepts/one-time-passwords-otp-example.md:
--------------------------------------------------------------------------------
1 | # One-Time Passwords (OTP) - Example
2 |
3 | In this section, we shall provide an **example** of how to generate and validate One-Time Passwords (**OTP**) in Python. The Python library of our choice is [**PyOTP**](https://github.com/pyauth/pyotp), which implement the [RFC 4226](https://tools.ietf.org/html/rfc4226) and [RFC 6238](https://tools.ietf.org/html/rfc6238) standards. If you want to use this library you should **follow the requirements** in those standards. Installation:
4 |
5 | ```python
6 | pip install pyotp
7 | ```
8 |
9 | ## Server-Side Setup
10 |
11 | We need to **create a base32 secret** which has to be shared between the authentication server and the client. We will use [Google Authenticator OpenSource](https://github.com/google/google-authenticator) OTP model which produce a **URI for an exchange**, the secret and additional client-server details. It includes the shared secret, the client's username, and the issuer's name.
12 |
13 | ```python
14 | import pyotp
15 |
16 | base32secret = pyotp.random_base32()
17 | print('Secret:', base32secret)
18 |
19 | totp_uri = pyotp.totp.TOTP(base32secret).provisioning_uri(
20 | "alice@google.com",
21 | issuer_name="Secure App")
22 | print(totp_uri)
23 | ```
24 |
25 | Run the above code example: [https://repl.it/@nakov/OTP-Server-Side-in-Python](https://repl.it/@nakov/OTP-Server-Side-in-Python).
26 |
27 | Sample output:
28 |
29 | ```python
30 | Secret: S3K3TPI5MYA2M67V
31 | otpauth://totp/Secure%20App:alice%40google.com?secret=S3K3TPI5MYA2M67V&issuer=Secure%20App
32 | ```
33 |
34 | ## Client-Side Setup
35 |
36 | Once the client stores the secret in a secure way, in a **time-interval** of a 30 seconds (by default) a new code will be generated.
37 |
38 | ```python
39 | import pyotp
40 | import time
41 |
42 | base32secret = 'S3K3TPI5MYA2M67V'
43 | print('Secret:', base32secret)
44 |
45 | totp = pyotp.TOTP(base32secret)
46 | print('OTP code:', totp.now())
47 | time.sleep(30)
48 | print('OTP code:', totp.now())
49 | ```
50 |
51 | Run the above code example: [https://repl.it/@nakov/OTP-Client-Side-in-Python](https://repl.it/@nakov/OTP-Client-Side-in-Python).
52 |
53 | Sample output:
54 |
55 | ```
56 | Secret: S3K3TPI5MYA2M67V
57 | OTP code: 339838
58 | OTP code: 284911
59 | ```
60 |
61 | ## Working Example
62 |
63 | You can install Google Authenticator from [Google Play](https://play.google.com) or [App Store](http://appstore.com) and scan the QR code below:
64 |
65 | 
66 |
67 | Example validation check:
68 |
69 | ```python
70 | import pyotp
71 |
72 | base32secret = 'S3K3TPI5MYA2M67V'
73 | print('Secret:', base32secret)
74 |
75 | totp = pyotp.TOTP(base32secret)
76 | your_code = '123456'
77 | print(totp.verify('Code Valid:', your_code))
78 | ```
79 |
80 | Run the above code example: [https://repl.it/@nakov/QR-code-scanner-in-Python](https://repl.it/@nakov/QR-code-scanner-in-Python).
81 |
82 | Output:
83 |
84 | ```
85 | Secret: S3K3TPI5MYA2M67V
86 | Code Valid: True
87 | ```
88 |
--------------------------------------------------------------------------------
/more-cryptographic-concepts/tls-example.md:
--------------------------------------------------------------------------------
1 | # TLS - Example
2 |
3 | ...
4 |
5 | Connect to HTTPS server and download resource.
6 |
7 | Display the server certificate + the public key.
8 |
9 | Display info about the TLS cipher suite.
10 |
11 | ...
12 |
--------------------------------------------------------------------------------
/quantum-safe-cryptography/quantum-safe-asymmetric-encryption-example.md:
--------------------------------------------------------------------------------
1 | # Quantum-Safe Asymmetric Encryption - Example
2 |
3 | **TODO**: Explain about the **McEliece cryptosystem**:
4 |
5 | * [https://en.wikipedia.org/wiki/McEliece\_cryptosystem](https://en.wikipedia.org/wiki/McEliece\_cryptosystem)
6 |
7 | **TODO**: Demonstrate McEliece asymmetric quantum-safe encryption it in **Python**:
8 |
9 | * [https://github.com/jkrauze/mceliece](https://github.com/jkrauze/mceliece)
10 |
--------------------------------------------------------------------------------
/quantum-safe-cryptography/quantum-safe-key-exchange-example.md:
--------------------------------------------------------------------------------
1 | # Quantum-Safe Key Exchange - Example
2 |
3 | In this example we shall demonstrate the how to use the [**NewHope key exchange** protocol](https://newhopecrypto.org), which is a quantum-safe **lattice-based** key-exchange algorithm, designed to provide at least **128-bit post-quantum security level**. The underlying math is based on the Ring-Learning-with-Errors (**Ring-LWE**) problem and operates in a ring of **integer polynomials** by certain modulo. The key-exchange operates like this:
4 |
5 | 1. Alice generates a random **private key** and corresponding **public message** (public key) and sends the message to Bob. The **public message** consists of 1024 polynomial coefficients (integers in the range \[0...61443]) + random seed (32 bytes).
6 | 2. Bob takes the **message from Alice** (polynomial + seed) and calculates from it the **shared secret key** between Alice and Bob. Bob also generates internally a **private key** and uses it to calculate and sends a **public message** to Alice. This public message consists of **2 polynomials**, each represented by 1024 integer coefficients.
7 | 3. Alice takes the **message from Bob** (the 2 polynomials) and calculates from it the **shared secret key** between Alice and Bob (using her private key). The calculated **shared key** consists of 32 bytes (256 bits), perfect for symmetric key encryption.
8 |
9 | To illustrate the **NewHope key exchange** algorithm, we shall use the [`PyNewHope`](https://github.com/nakov/PyNewHope) package from the Python's official PyPI repository (which is designed for educational purposes and is not certified for production use):
10 |
11 | ```python
12 | pip install pynewhope
13 | ```
14 |
15 | The code to demonstrate the quantum-safe key-exchange "NewHope" is simple:
16 |
17 | ```python
18 | from pynewhope import newhope
19 |
20 | # Step 1: Alice generates random keys and her public msg to Bob
21 | alicePrivKey, aliceMsg = newhope.keygen()
22 | print("Alice sends to Bob her public message:", aliceMsg)
23 |
24 | # Step 2: Bob receives the msg from Alice and responds to Alice with a msg
25 | bobSharedKey, bobMsg = newhope.sharedB(aliceMsg)
26 | print("\nBob's sends to Alice his public message:", bobMsg)
27 | print("\nBob's shared key:", bobSharedKey)
28 |
29 | # Step 3: Alice receives the msg from Bob and generates her shared secret
30 | aliceSharedKey = newhope.sharedA(bobMsg, alicePrivKey)
31 | print("\nAlice's shared key:", aliceSharedKey)
32 |
33 | if aliceSharedKey == bobSharedKey:
34 | print("\nSuccessful key exchange! Keys match.")
35 | else:
36 | print("\nError! Keys do not match.")
37 | ```
38 |
39 | Run the above code example: [https://repl.it/@nakov/NewHope-key-exchange-in-Python](https://repl.it/@nakov/NewHope-key-exchange-in-Python).
40 |
41 | Alice generates a **private key** + **public message** and sends her public message to Bob, then Bob calculates his copy of the **shared secret key** from Alice's message and generates a **public message** for Alice, and finally Alice calculates her copy of the **shared secret key** from her private key together with Bob's message.
42 |
43 | The **output** from the above code looks like this (the 1024 polynomial coefficients are given in abbreviated form):
44 |
45 | ```
46 | Alice sends to Bob her public message: ([12663, 7323, 8979, 7763, 11139, 5460, 7337, 12182, ..., 8214, 10808, 8987], b'*[\x98t\xae\xe9\xc5H\xfc\xc2\x9b$\xd6\xaa[8k\xc1\x8d\xad\x1d\x01\x87i\xed\x03\x06\xe1k2\xa7N')
47 |
48 | Bob's sends to Alice his public message: ([2, 1, 1, 2, 0, 1, 1, 1, 1, 3, 3, 2, 1, 1, 3, 0, ..., 0, 0, 3], [7045, 4326, 6186, 8298, 12738, ..., 7730, 10577, 8046])
49 |
50 | Bob's shared key: [228, 159, 146, 8, 56, 146, 50, 7, 59, 87, 113, 57, 151, 137, 240, 139, 215, 33, 71, 188, 108, 239, 231, 252, 230, 77, 181, 178, 176, 7, 219, 217]
51 |
52 | Alice's shared key: [228, 159, 146, 8, 56, 146, 50, 7, 59, 87, 113, 57, 151, 137, 240, 139, 215, 33, 71, 188, 108, 239, 231, 252, 230, 77, 181, 178, 176, 7, 219, 217]
53 |
54 | Successful key exchange! Keys match.
55 | ```
56 |
57 | It is visible that the calculated **secret shared key** is the same 32-byte sequence for Alice and Bob and thus the key exchange algorithm works correctly. The above demonstrated **HewHope** key exchange algorithm works quite **fast** and provides a **128 bits of post-quantum security**.
58 |
--------------------------------------------------------------------------------
/resources/Practical-cryptography-for-developers-book-cover.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nakov/Practical-Cryptography-for-Developers-Book/85a0bfbb0d66b2f87029b08ae5387da2c94cf3cd/resources/Practical-cryptography-for-developers-book-cover.png
--------------------------------------------------------------------------------
/secure-random-generators/exercises-pseudo-random-generator.md:
--------------------------------------------------------------------------------
1 | # Exercises: Pseudo-Random Generator
2 |
3 | Write a code to generate **30 pseudo-random integers** in the range **\[1...10]**, starting from certain **entropy**, taken as input, using **HMAC key derivation**.
4 |
5 | From the **entropy** generate a **seed** (256-bit binary sequence) using **SHA-256**:
6 |
7 | ```python
8 | seed = SHA256(entropy)
9 | ```
10 |
11 | Generate the **n**-th random number by the formula:
12 |
13 | ```python
14 | 1 + HMAC-SHA256(n, seed) % 10
15 | ```
16 |
17 | Print the numbers at the output, separated by space.
18 |
19 | Sample **input** and corresponding **output**:
20 |
21 | | | |
22 | | ----------- | ----------------------------------------------------------------- |
23 | | **Input** | **Output** |
24 | | hello | 8 4 10 5 5 3 5 7 10 6 4 9 2 3 2 8 3 3 10 6 8 10 9 10 1 3 6 4 4 10 |
25 | | random text | 10 5 5 9 7 4 2 9 2 1 10 4 8 9 8 1 8 6 5 7 5 4 3 4 6 6 9 8 1 1 |
26 | | fun | 6 5 9 2 2 5 1 6 10 10 10 1 8 10 6 9 2 1 5 10 1 4 8 5 6 3 8 4 2 1 |
27 |
--------------------------------------------------------------------------------
/secure-random-generators/pseudo-random-numbers-examples.md:
--------------------------------------------------------------------------------
1 | # Pseudo-Random Numbers - Examples
2 |
3 | To get a better idea **how pseudo-random numbers are generated** in computer programming, let's play with at the following Python code, which generates 5 pseudo-random numbers in the range \[10...20]:
4 |
5 | ```python
6 | import hashlib, time
7 |
8 | startSeed = str(time.time()) + '|'
9 | min = 10
10 | max = 20
11 | for i in range(5):
12 | nextSeed = startSeed + str(i)
13 | hash = hashlib.sha256(nextSeed.encode('ascii')).digest()
14 | bigRand = int.from_bytes(hash, 'big')
15 | rand = min + bigRand % (max - min + 1)
16 | print(nextSeed, bigRand, '-->', rand)
17 | ```
18 |
19 | Run the above code example: [https://repl.it/@nakov/Pseudo-random-numbers-in-Python](https://repl.it/@nakov/Pseudo-random-numbers-in-Python).
20 |
21 | The above code produces time-depended (predictable) **pseudo-random sequence**:
22 |
23 | ```
24 | 1539884529.7564313|0 80821949188459167822103620715837790870744533466506114260335306835341654043374 --> 20
25 | 1539884529.7564313|1 74025479792630401388590516952955656999942018130178317853592496371994668720404 --> 12
26 | 1539884529.7564313|2 82017697577161203981429946799250236982499988253633196542465974577893633076425 --> 18
27 | 1539884529.7564313|3 107386997066995629290834465394867359239275712194747910247567090891223949362198 --> 13
28 | 1539884529.7564313|4 83874630241630198317549470506043001102325518306912594861433838548293113930135 --> 10
29 | ```
30 |
31 | The **initial pseudo-random seed** is taken from the current time. The first pseudo-random number in the sequence comes from the **SHA-256 hash** of the initial **seed** + the number `0`, the second pseudo-random number comes from the hash of the initial **seed** + the number `1` and so on. To get an output of certain **range \[min...max]** the 256-bit **hash** is divided to **(max - min + 1)** and **min** is added to it. The number `i`, together with the value `startSeed` hold the internal **state** of the random generator, which changes for each next random number.
32 |
33 | The above pseudo-random generator is based on the **random statistical distribution** of the **SHA-256** function. It is expected that the chance for each possible number to be generated is equal.
34 |
35 | ## Creating a Secure Random Generator
36 |
37 | The above random generator is **not secure**, because it is not initialized by an unpredictable source of entropy. **Let's fix this**.
38 |
39 | We shall **initialize the initial randomness based on the keyboard events**. The user will be asked to enter something 5 times and the exact precise times of the moments of the user input, together with the data entered from the user will be joined as **initial randomness (seed)**. The collected text entropy can be shortened through SHA-256 hashing (this will reduce it to 256 bits). After the entropy is collected and the start seed is calculated, the same logic like at the previous example will be used to generate 5 random numbers in the range \[10...20]. This is a sample Python implementation:
40 |
41 | ```python
42 | import hashlib, time, binascii
43 |
44 | entropy = ''
45 | for i in range(5):
46 | s = input("Enter something [" + str(i+1) + " of 5]: ")
47 | entropy = entropy + s + '|' + str(time.time()) + '|'
48 | print("Entropy:", entropy)
49 | startSeed = str(binascii.hexlify(hashlib.sha256(entropy.encode('ascii')).digest()))[2:-1]
50 | print("Start seed = SHA-256(entropy) =", startSeed)
51 |
52 | min = 10
53 | max = 20
54 | for i in range(5):
55 | nextSeed = startSeed + '|' + str(i)
56 | hash = hashlib.sha256(nextSeed.encode('ascii')).digest()
57 | bigRand = int.from_bytes(hash, 'big')
58 | rand = min + bigRand % (max - min + 1)
59 | print(nextSeed, bigRand, '-->', rand)
60 | ```
61 |
62 | Run the above code example: [https://repl.it/@nakov/secure-random-generator-in-Python](https://repl.it/@nakov/secure-random-generator-in-Python).
63 |
64 | A **sample outpu**t from the above code may look like this:
65 |
66 | ```
67 | Enter something [1 of 5]: first
68 | Enter something [2 of 5]: second
69 | Enter something [3 of 5]: random text
70 | Enter something [4 of 5]: dfasfdasfs
71 | Enter something [5 of 5]: last
72 | Entropy: first|1539885709.4494743|second|1539885713.687703|random text|1539885721.5754962|dfasfdasfs|1539885724.40904|last|1539885726.1286101|
73 | Start seed = SHA-256(entropy) = f8a4eaceb16156b1a23f4b6d08e54665ffa4822949b22e01d6de4c5daae965e3
74 | f8a4eaceb16156b1a23f4b6d08e54665ffa4822949b22e01d6de4c5daae965e3|0 84482770259566839097936866229004786554948913905882724148636325987196754263481 --> 19
75 | f8a4eaceb16156b1a23f4b6d08e54665ffa4822949b22e01d6de4c5daae965e3|1 67001454659030164457342421011672033052466168976555224352709830050538321411120 --> 14
76 | f8a4eaceb16156b1a23f4b6d08e54665ffa4822949b22e01d6de4c5daae965e3|2 103739181507291072572315034266940107849472122762876847172454548630886082729227 --> 12
77 | f8a4eaceb16156b1a23f4b6d08e54665ffa4822949b22e01d6de4c5daae965e3|3 3011033199204097839903859902789759740091959530467456042709372597822032778153 --> 16
78 | f8a4eaceb16156b1a23f4b6d08e54665ffa4822949b22e01d6de4c5daae965e3|4 100466094724924763659843669256673300207383922129676800217664465341535622195997 --> 16
79 | ```
80 |
81 | Note that the **collected entropy is very hard to be predicted**. The cracker should guess all the text entered by the user and also guess the exact time for each of the 5 inputs. If the above is repeated 20 instead of 5 times, it will be even harder to predict (the collected entropy will be bigger).
82 |
83 | Some cryptographical software use similar techniques like in the above code example when generating keys, password and randomness as general and now you know why: to collect entropy in an unpredictable way.
84 |
--------------------------------------------------------------------------------
/secure-random-generators/secure-random-generators-csprng.md:
--------------------------------------------------------------------------------
1 | # Secure Random Generators (CSPRNG)
2 |
3 | Cryptography secure pseudo-random number generators (**CSPRNG**) are random generators, which guarantee that the random numbers coming from them are **absolutely unpredictable**. **CSPRNG** satisfy the [**next-bit test**](https://en.wikipedia.org/wiki/Next-bit\_test) and withstand the [**state compromise extensions**](https://www.owasp.org/index.php/PRNG\_state\_compromise\_extension\_attack) and are typically part of the operating system or come from secure external source. Depending on the level of security required, CSPRNG can be implemented as **software** components or as **hardware** devices or as combination of both.
4 |
5 | For example, in the credit card printing centers the formal security regulations require certified **hardware random generators** to be used to generate credit card PIN codes, private keys and other data, designed to remain private.
6 |
7 | Modern operating systems (OS) **collect entropy** (initial seed) from the **environmental noise**: keyboard clicks, mouse moves, network activity, system I/O interruptions, hard disk activity, etc. Sources of randomness from the environment in Linux, for example, include inter-keyboard timings, inter-interrupt timings from some interrupts, and other events which are both non-deterministic and hard to measure for an outside observer.
8 |
9 | The collected in the OS randomness is usually accessible from `/dev/random` and `/dev/urandom`.
10 |
11 | * Reading from the `/dev/random` file (the limited blocking random generator) **returns entropy** from the kernel's entropy pool (collected noise) and **blocks** when the entropy pool is empty until additional environmental noise is gathered.
12 | * Reading the `/dev/urandom` file (the unlimited non-blocking random generator) returns entropy from the kernel's entropy pool or a pseudo-random data, generated from previously collected environmental noise, which is also unpredictable, but is based on secure entropy "stretching" algorithm.
13 |
14 | Usually a **CSPRNG** should start from an **unpredictable random seed** from the operating system, from a specialized hardware or from external source. Random numbers after the seed initialization are typically produces by a **pseudo-random computation**, but this does not compromise the security. Most algorithms often "**reseed**" the CSPRNG random generator when a new entropy comes, to make their work even more unpredictable.
15 |
16 | Typically modern OS CSPRNG APIs combine the constantly collected **entropy** from the environment with the **internal state** of their built-in pseudo-random algorithm with continuous **reseeding** to guarantee maximal **unpredictability** of the generated randomness with high **speed** and **non-blocking** behavior in the same time.
17 |
18 | ## Hardware Random Generators (TRNG)
19 |
20 | Hardware random generators, known as **true random number generators (TRNG)**, typically capture physical processes or phenomenа, such as the visible spectrum of the light, the thermal noise from the environment, the atmosphere noise, etc. The randomness from the physical environment is collected through specialized sensors, then amplified and processed by the device and finally transmitted to the computer through USB, PCI Express or other standard interface.
21 |
22 | Modern **microprocessors** (CPU) \*\*\*\*provide a built-in hardware random generator, accessible through a special **CPU instruction** [`RdRand`](https://en.wikipedia.org/wiki/RdRand), which return a random integer into one of the CPU registers.
23 |
24 | Most cryptographic applications today do not require a hardware random generator, because the entropy in the operating system is secure enough for general cryptographic purposes. Using a **TRNG** is needed for systems with higher security requirements, such as banking and finance applications, certification authorities and high volume payment processors.
25 |
26 | ## How as a Developer to Access the CSPRNG?
27 |
28 | Typically developers access the cryptographically strong random number generators (**CSPRNG**) for their OS from a **cryptography library** for their language and platform.
29 |
30 | * In **Linux** and **macOS**, it is considered that both `/dev/random` and `/dev/urandom` sources of randomness are **secure enough for most cryptographic purposes** and most cryptographic libraries access them internally.
31 | * In **Windows**, random numbers for cryptographic purposes can be securely generated using the `BCryptGenRandom` function from the [Cryptography API: Next Generation (CNG)](https://docs.microsoft.com/windows/desktop/SecCNG/cng-portal) or higher level crypto libraries.
32 | * In **C#** use `System.Security.Cryptography.RandomNumberGenerator.Create()` from .NET Framework or .NET Core.
33 | * In **Python** use `os.urandom()` or the `secrets` library.
34 | * In **Java** use the `java.security.SecureRandom` system class.
35 | * In **JavaScript** use `window.crypto.getRandomValues(Uint8Array)` for client side (in the Web browser) or `crypto.randomBytes()` or external module like `node-sodium` for server-side (in Node.js).
36 |
37 | **Never use** `Math.random()` or similar insecure RNG functions for cryptographic purposes!
38 |
--------------------------------------------------------------------------------
/styles/pdf.css:
--------------------------------------------------------------------------------
1 | /* This CSS code is applied for PDF rendering */
2 |
3 | .readme-book-cover-image {
4 | display: none;
5 | }
6 |
7 | .page .section code,
8 | .page .section pre {
9 | font-family: "Consolas", "Lucida Console", "Liberation Mono", "Menlo", "Courier New", monospace;
10 | }
11 |
12 | .page .section code {
13 | padding: 0.2em 0em;
14 | border-radius: 0.25em;
15 | font-size: 1em;
16 | }
17 |
18 | .page .section pre {
19 | padding: 0.4em 0.6em;
20 | border-radius: 0.25em;
21 | line-height: 1.5em;
22 | }
23 |
24 | .page .section pre>code {
25 | font-size: 1em;
26 | }
27 |
28 | .page .section h1, .page .section h2, .page .section h3, .page .section h4, .page .section h5, .page .section h6 {
29 | margin-top: 0.7em;
30 | margin-bottom: .3em;
31 | }
32 |
33 | .page .section table {
34 | max-width: 100%;
35 | }
36 |
37 | .page .section table th {
38 | background: #eee;
39 | }
40 |
41 | .page .section table td {
42 | word-break: break-all;
43 | }
44 |
--------------------------------------------------------------------------------
/styles/website.css:
--------------------------------------------------------------------------------
1 | /* This CSS code is applied for browser-only rendering in HTML format */
2 |
3 | .readme-book-cover-image {
4 | float: right;
5 | margin-left: 10px;
6 | width: 50%;
7 | }
8 |
9 | @media screen and (min-width 480px) {
10 | .readme-book-cover-image {
11 | float: none;
12 | }
13 | }
14 |
15 | .markdown-section code {
16 | padding: 0.2em 0em;
17 | border-radius: 0.25em;
18 | font-size: 1em;
19 | }
20 |
21 | .markdown-section pre {
22 | padding: 0.4em 0.6em;
23 | border-radius: 0.25em;
24 | line-height: 1.5em;
25 | margin-bottom: 1em;
26 | }
27 |
28 | .markdown-section pre>code {
29 | font-size: 1em;
30 | }
31 |
32 | .markdown-section h1, .markdown-section h2, .markdown-section h3, .markdown-section h4, .markdown-section h5, .markdown-section h6 {
33 | margin-top: 0.7em;
34 | margin-bottom: .3em;
35 | }
36 |
37 | .markdown-section table {
38 | max-width: 100%;
39 | }
40 |
41 | .markdown-section table th {
42 | background: #eee;
43 | }
44 |
45 | .markdown-section table td {
46 | word-break: break-all;
47 | }
48 |
49 | .markdown-section pre>code {
50 | word-wrap: break-word;
51 | white-space: pre-wrap;
52 | }
53 |
54 | .page-wrapper .page-inner {
55 | max-width: 960px;
56 | padding-left: 20px;
57 | }
58 |
59 | a.run-code-button:hover, a.run-code-button:focus {
60 | background: #98d598;
61 | text-decoration: none;
62 | }
63 |
64 | a.run-code-button {
65 | float: right;
66 | background: #cae7ca;
67 | border-radius: 4px;
68 | padding: 3px 10px;
69 | text-shadow: 0px 0px 2px white;
70 | border: 1px solid #add2ad;
71 | margin-top: 3px;
72 | }
73 |
74 | span.run-code-loading {
75 | float: right;
76 | background: #ffd02b;
77 | border-radius: 4px;
78 | padding: 3px 10px;
79 | text-shadow: 0px 0px 2px white;
80 | border: 1px solid #eec036;
81 | margin-top: 3px;
82 | margin-left: 10px;
83 | cursor: wait;
84 | }
85 |
--------------------------------------------------------------------------------
/symmetric-key-ciphers/README.md:
--------------------------------------------------------------------------------
1 | # Symmetric Key Ciphers
2 |
3 | **Symmetric key ciphers** (like **AES**, **ChaCha20**, **RC6**, **Twofish**, **CAST** and many others) use the same key (or password) to **encrypt** and **decrypt** data. They are often used in combination with other algorithms into a **symmetric encryption schemes** (like **ChaCha20-Poly1305** and **AES-128-GCM** and **AES-256-CTR-HMAC-SHA256**), often with password to **key derivation** algorithms (like **Scrypt** and **Argon2**). Symmetric key ciphers are **quantum-resistant**, which means that powerful quantum computers will not be able to break their security (when big enough key lengths are used). Symmetric ciphers can encrypt data coming as blocks of fixed size (**block ciphers**) or data coming as a sequence of bytes (**stream ciphers**). Block ciphers can be transformed to stream ciphers by certain constructions, known as "**block cipher modes** of operation".
4 |
5 | ## Symmetric Encryption / Decryption
6 |
7 | **Symmetric encryption** and decryption uses a **secret key** or passphrase (to derive the key from it). The **secret key** used to encrypt and decrypt the data is usually 128 bits or 256 bits and is called "**encryption key**". Sometimes it is given as hex or base64-encoded integer number or is derived through a **password-to-key derivation scheme**.
8 |
9 | When the input data is encrypted, it is transformed to **encrypted ciphertext** and when the ciphertext is decrypted, it is transformed back to the original input data.
10 |
11 | 
12 |
13 | ## Symmetric Encryption Uses a Set of Algorithms
14 |
15 | It is important to know as a concept that symmetric-key encryption algorithms usually do not work standalone. They work together with other related crypto algorithms, into a **symmetric encryption scheme** / **symmetric encryption construction**.
16 |
17 | In most encryption schemes an **encryption** is combined with password to **key derivation** algorithm and **message authentication** scheme (see [authenticated encryption](https://en.wikipedia.org/wiki/Authenticated\_encryption)). Typically a symmetric encryption procedure uses a sequence of steps, involving different crypto algorithms:
18 |
19 | * **Password-to-key derivation** algorithm (like Scrypt or Argon2): to allow using a password instead of a key and to make password cracking hard and slow to be performed.
20 | * **Block to stream cipher transformation** algorithm (block cipher mode like **CBC** or **CTR**) + **message padding** algorithm like **PKCS7** (in some modes): to allow encrypting data of arbitrary size using a block cipher algorithm (like **AES**).
21 | * **Block cipher algorithm** (like **AES**): to securely encrypt data blocks of fixed length using a secret key.
22 | * **Message authentication** algorithm (like **HMAC**): to check whether after decryption the obtained result matches the original message before the encryption.
23 |
24 | Later in this section we shall give **more details and examples** about how to configure and use symmetric block ciphers (like AES) along with the all above described algorithms to securely encrypt and decrypt messages of arbitrary size.
25 |
--------------------------------------------------------------------------------
/symmetric-key-ciphers/chacha20-poly1305.md:
--------------------------------------------------------------------------------
1 | # ChaCha20-Poly1305
2 |
3 | ## ChaCha20-Poly1305
4 |
5 | **\[TODO]**
6 |
7 | The AEAD construction **ChaCha20-Poly1305** combines the **ChaCha20** stream cipher paired with the **Poly1305** authenticator...
8 |
9 | ## Chacha20-Poly1305 - Example in Python
10 |
11 | [https://github.com/ph4r05/py-chacha20poly1305](https://github.com/ph4r05/py-chacha20poly1305)
12 |
13 | **\[TODO]**
14 |
--------------------------------------------------------------------------------
/symmetric-key-ciphers/ethereum-wallet-encryption.md:
--------------------------------------------------------------------------------
1 | # Ethereum Wallet Encryption
2 |
3 | To illustrate the application of **the AES cipher in action**, we shall look into one **real-world example**: the standard **encrypted wallet file format** for the **Ethereum** blockchain. We shall see how **AES-128-CTR** cipher is combined with **Scrypt** and **MAC** to securely implement authenticated symmetric key encryption by text-based password.
4 |
5 | ## Ethereum UTC / JSON Wallets
6 |
7 | In public blockchain networks (like Bitcoin and Ethereum) the private keys of the blockchain asset holders are stored in special keystores, called **crypto wallets**. Typically these crypto-wallets are files on the local hard disk, encrypted by a password.
8 |
9 | In the **Ethereum blockchain** crypto wallets are internally stored in a special **encrypted** format known as "[**UTC / JSON Wallet (Keystore File)**](https://theethereum.wiki/w/index.php/Accounts,\_Addresses,\_Public\_And\_Private\_Keys,\_And\_Tokens#UTC\_JSON\_Keystore\_File)" or "[**Web3 Secret Storage Definition**](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition)". This is the **wallet file format**, used in [**geth**](https://geth.ethereum.org) and [**Parity**](https://www.parity.io/ethereum) (the leading protocol implementations for Ethereum), in [**MyEtherWallet**](https://www.myetherwallet.com) (popular online client-side Ethereum wallet), in [**MetaMask**](https://metamask.io) (widely used in-browser Ethereum wallet), in the [**ethers.js**](https://github.com/ethers-io/ethers.js/) and [**Nethereum**](https://github.com/Nethereum/Nethereum) libraries and in many other Ethereum-related technologies and tools.
10 |
11 | The Ethereum **UTC / JSON keystores** keep the **encrypted private key** (or wallet seed words) as **JSON text document**, specifying the encrypted data, encryption algorithms and their parameters.
12 |
13 | ## UTC / JSON Keystore - Example
14 |
15 | Let's look into a **sample UTC / JSON keystore file**, which holds a password-protected 256-bit private key.
16 |
17 | ```javascript
18 | {
19 | "version": 3,
20 | "id": "07a9f767-93c5-4842-9afd-b3b083659f04",
21 | "address": "aef8cad64d29fcc4ed07629b9e896ebc3160a8d0",
22 | "Crypto": {
23 | "ciphertext": "99d0e66c67941a08690e48222a58843ef2481e110969325db7ff5284cd3d3093",
24 | "cipherparams": { "iv": "7d7fabf8dee2e77f0d7e3ff3b965fc23" },
25 | "cipher": "aes-128-ctr",
26 | "kdf": "scrypt",
27 | "kdfparams": {
28 | "dklen": 32,
29 | "salt": "85ad073989d461c72358ccaea3551f7ecb8e672503cb05c2ee80cfb6b922f4d4",
30 | "n": 8192,
31 | "r": 8,
32 | "p": 1
33 | },
34 | "mac": "06dcf1cc4bffe1616fafe94a2a7087fd79df444756bb17c93af588c3ab02a913"
35 | }
36 | }
37 | ```
38 |
39 | The above JSON document is a classical example of **authenticated symmetric encryption**.
40 |
41 | ## What Is Inside the UTC / JSON File?
42 |
43 | Typically a UTC / JSON keystore holds the following data:
44 |
45 | * **Key-derivation function** (KDF) used to transform the text-based wallet encryption **password** into an AES symmetric **key**, used to encrypt the wallet contents. Usually the KDF function is "**scrypt**".
46 | * The **KDF parameters** - the parameters used in the KDF function to derive the password (e.g. iterations count, salt, etc.)
47 | * The **ciphertext** - the encrypted wallet content (typically holds an encrypted 256-bit private key).
48 | * Symmetric **cipher algorithm** + its **parameters**, e.g. **AES-128-CTR** + initial vector (**IV**).
49 | * **MAC** - message authentication code used (MAC) to check the message integrity after it is decrypted (to know whether the wallet decryption password was correct or not).
50 | * Ethereum calculates the MAC by calculating **keccak-256** hash of the concatenations of the second-leftmost 16 bytes of the derived key together with the full **ciphertext**.
51 | * Additional **metadata**: wallet format **version**, wallet unique **id** (uuid) and the blockchain **address**, controlled by this wallet.
52 |
53 | By default the key-derivation function is scrypt and uses **weak scrypt parameters** (n=8192 cost factor, r=8 block size, p=1 parallelization), so it is recommended to use long and complex passwords to avoid brute-force wallet decryption attacks.
54 |
55 | ## MyEtherWallet: Play with UTC / JSON Keystore Files
56 |
57 | To learn better the file format behind the Ethereum UTC / JSON keystore files, play with **MyEtherWallet**.
58 |
59 | 
60 |
61 | Follow the steps below to create a new **random Ethereum crypto wallet** and view its encrypted JSON content:
62 |
63 | * Open the **MyEtherWallet** web site: [**https://myetherwallet.com**](https://www.myetherwallet.com).
64 | * Choose a **password** and create a **new wallet**.
65 | * Download the **Keystore File** (UTC / JSON).
66 | * See **what's inside** the downloaded file.
67 | * Try to **make some changes**, try to decrypt it with wrong password and other changes.
68 | * Enjoy **learning by playing**.
69 |
--------------------------------------------------------------------------------
/symmetric-key-ciphers/exercises-aes-encrypt-decrypt.md:
--------------------------------------------------------------------------------
1 | # Exercises: AES Encrypt / Decrypt
2 |
3 | In this exercise we shall **encrypt** and **decrypt** a text message using a symmetric cipher **AES-CBC-256**, combined with **Scrypt** password-to-key derivation and **HMAC** message authentication code. In fact we shall implement a **password-based symmetric authenticated encryption scheme**.
4 |
5 | ## Symmetric Encryption (AES + Scrypt + HMAC)
6 |
7 | Write a program to **encrypt** a text **message** using given **password**. Use the following steps:
8 |
9 | * Derive a **512-bit key** from the **password** using **Scrypt** (n=16384, r=16, p=1) with random **salt** (128 bits).
10 | * Split the derived key into two **256-bit** sub-keys: **encryption key** and **HMAC key**.
11 | * **Pad** the input message using the **PKCS7** algorithm to length, which is multiple of **16 bytes** (128 bits).
12 | * **Encrypt** the padded message using **AES-256-CBC** using the **encryption key**. The obtained result is the **ciphertext**. Its length should be a multiple of 16 bytes (128 bits), which is the block size in the AES cipher.
13 | * Use a randomly generated 128-bit initial vector (**IV**).
14 | * Calculate message authentication code (**MAC**) using **HMAC-SHA256**(**hmac\_key**, **ciphertext**).
15 |
16 | **Input**: **message** + **password** (space separated).
17 |
18 | **Output**: **JSON** document (see the example below), holding the following assets:
19 |
20 | * The Scrypt randomly-generated **salt** (in hex format).
21 | * The randomly-generated **iv** (in hex format), used for the AES cipher.
22 | * The encrypted message **ciphertext** (in hex format) from the **AES** cipher.
23 | * The message authentication code - **mac** (in hex format).
24 |
25 | Write your code in programming language of choice.
26 |
27 | | | |
28 | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
29 | | **Input** | **Output** |
30 | | **p@sSw0rd\~123** SecretMsg | {"**salt**": "9757a3a22a9937ca0e0f2b5f2a4a11b4", "**iv**": "2ce8c035d50f7a6ee6509c14fe11725a", "**ciphertext**": "bb435d8ad048c240b50f0e4a191605d9", "**mac**": "02cf870ad1f7453c339dac06edbd648c455f5e8abbf6f2716cbc2d164b644200"} |
31 | | **stupid!pass** longer-message-for-encryption | {"**salt**": "b243f0ac10ef358ff0d37f1e30ef19c2", "**iv**": "fdeff97e89705289d99751f079e2a308", "**ciphertext**": "ea76bc60799c5824627a8c1276b48ab70e24011b6654f8ffb019a4f6876485af", "**mac**": "34085e1a47ae53e154b7466336efee386c2f1ed61a0105183ef016af794da58f"} |
32 |
33 | Note that the above input will be different in your case, bеcause of the randomly generated **salt** and **iv**.
34 |
35 | ## Symmetric Decryption (AES + Scrypt + HMAC)
36 |
37 | Write a program to **decrypt** an **encrypted message** (coming as input) using given **password**.
38 |
39 | * Derive a **512-bit key** from the **password** using **Scrypt** (n=16384, r=16, p=1) with the **salt** (from the JSON).
40 | * Split the derived key into two 256-bit sub-keys: **encryption key** and **HMAC key**.
41 | * Calculate message authentication code (**MAC**) using **HMAC-SHA256**(**hmac\_key**, **ciphertext**).
42 | * **Compare** the MAC with the MAC in the JSON document.
43 | * Same MAC means "correct password / successful decryption".
44 | * Different MAC means "wrong password / incorrect input data".
45 | * **Decrypt** the **ciphertext** from the input using **AES-256-CBC** using the **encryption key** and the **IV** from the JSON.
46 | * **Unpad** the decrypted message using the **PKCS7** algorithm from length, which is multiple of **16 bytes** (128 bits) to its original length (usually smaller).
47 |
48 | **Input**: password + JSON (space separated). The JSON is in exactly the same format, like in the output from the previous exercise (it holds **salt**, **iv**, **ciphertext** and **mac**, all as **hex** numbers)
49 |
50 | **Output**: `Decrypted:` + the original **decrypted message** or the text `Decryption failed!` in case or wrong password or other problem.
51 |
52 | Write your code in programming language of choice.
53 |
54 | | | |
55 | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
56 | | **Input** | **Output** |
57 | | **p@sSw0rd\~123** {"**salt**": "9757a3a22a9937ca0e0f2b5f2a4a11b4", "**iv**": "2ce8c035d50f7a6ee6509c14fe11725a", "**ciphertext**": "bb435d8ad048c240b50f0e4a191605d9", "**mac**": "02cf870ad1f7453c339dac06edbd648c455f5e8abbf6f2716cbc2d164b644200"} | Decrypted: SecretMsg |
58 | | **wrong!pass** {"**salt**": "9757a3a22a9937ca0e0f2b5f2a4a11b4", "**iv**": "2ce8c035d50f7a6ee6509c14fe11725a", "**ciphertext**": "bb435d8ad048c240b50f0e4a191605d9", "**mac**": "02cf870ad1f7453c339dac06edbd648c455f5e8abbf6f2716cbc2d164b644200"} | Decryption failed! |
59 |
--------------------------------------------------------------------------------
/symmetric-key-ciphers/exercises-chacha20-poly1305.md:
--------------------------------------------------------------------------------
1 | # Exercises: ChaCha20-Poly1305
2 |
3 | \[TODO]
4 |
--------------------------------------------------------------------------------