------------------------------------------------------------------------------- Key Derivation Functions (KDF) Expanding user Passwords into Binary Encryption Keys... This is a form of 'hashing' is used to take a user password, and expand it into a binary 'cryptographic key' that is needed for the actual encryption work. In some ways this is simular to password hashing, (for password storage) as they have the same goals (slow down attackers). Only the result of the hash is saved rather than actually used for decrypting a file. The hashing needs to be slow, (unlike checksumming), and memory hungry, so that GPU, FPGA, and ACIS hardware arrays can't be used to try multiple 'dictionary' attacks. ASIDE: The cryptographic key while becomming a large binary form, would still be regarded as 'weak' as the original password, with the same entropy as that password, with regards to dictionary attacks. A good general summery is in https://security.stackexchange.com/questions/4781/ Specicially for algorithms... In summary... PBKDF2 NIST recommends as being (good enough) there are GPU implementations bcrypt Unbroken, and is now generally used as crypt method 6 Implemented on a GPU with extra RAM scrypt Very intensive, good for hard disk encryption, Not for general use: needs too many resources for an active system. argon2 which has 'i' and 'd' varients to combat different hardware methods. ------------------------------------------------------------------------------- Password Encrypted Master Passwords See "Encrypted Key on Device itself" in ~/info/crypto/linux_dmcrypt.hints and example in ~/store/crypto/key_store_dm.pl OR the original paper by Clemens Fruhwirth, TKS1, An anti-forensic, two level, and iterated key setup scheme. http://clemens.endorphin.org/TKS1-draft.pdf That is you have set of binary master passwords which you decrypt or hash using the user provided password in some way to produce the cryptographic password of the larger encrypted data. This typically relies on the original system being encrypted with a purely random binary 'master' password which is then separately encrypted using a users password in some form of 'key store'. This can also allow you to have multiple copies of that master password each separately encrypted with different user passwords. that is each user can have their own password that is different to each others, but all of which can decrypt the actual data. See "key_storage.txt" also my "ks" script https://antofthy.gitlab.io/software/#ks The above scheme was incorporated into the "LUKS" version of dm-crypt, and uses a table of 8 slots, against which the user provided password 'tried'. Success on one of the slots then decodes the binary key needed to unlock the disk partition data. ------------------------------------------------------------------------------- PBKDF1.5 (PKCS#5 and RFC 2898) Password-Based Key Derivation Function v1.5 This is an older standard and should not be used. One hashing pass (fast), no salt openssl enc -aes-256-cbc -a -k the_pass_phrase -nosalt -P key=A0253F9092BDEA97210100C94D3F405E748164248667DCF9E071F69B2DD61347 iv =5AA879244988E7A86B366F5FDF3F4E71 Ignore the last line which is the base64 (-a) encryption of an empty file The '-P' flag gets "openssl enc" to output the derived "key" and "iv" and exit The Ecliptic Encryption does not need to generate a 'iv'... openssl enc -aes-256-ecb -a -k the_pass_phrase -nosalt -P key=A0253F9092BDEA97210100C94D3F405E748164248667DCF9E071F69B2DD61347 Note this is fast as it is only one pass, but that makes it less secure. Salting is used to randomised the hashing. For more examples see "openssl.txt" in this directory. ------------------------------------------------------------------------------- PBKDF2 (PKCS #5 or RFC 2898) algorithm Password-Based Key Derivation Function v2 This is an iterated PBKDF1 (Password to Key Derivation), and is designed to be slow, (based on the number of iterations), so as to not be a burden for legitimate parties, but will generate a significant burden for opponents. Basically iterativally hashing the hash over and over again so that it takes anywhere from 1/2 a second to 5 seconds to compute the final hash on a modern computer. This generally used for large decryptions (such as files and password stores), but not for network communications, which needs to be faster. This requires: password, iterative_count, salt (typically 8 or 16 bytes), and the hashing function that is to be used. Only the first of these needs to be kept secret. This is then used to generate the Cryptographic key, and the IV (the later does not technically need to be secret). WARNING: PBKDF2 can be implemented using standard GPU arrays, depending on the hashing function used. --- OpenSSL v1.1.1 With OpenSSL version 1.1.0, the "openssl" command can generate the PBKDF2 key derivation (to use as the key and iv of an encryption)... The actual 'encryption method' here does not matter, It is the '-P' option that returns the information. Also note iterations here is VERY low, and only for demonstation purposes. echo -n "passphrase" | openssl enc -aes-256-cbc -pbkdf2 -md sha1 -pass stdin -P \ -S 05775a1c0bafcade -iter 1000 -P Resulting Output (96 hex characters, => 48 bytes: 32 byte key, 16 byte iv ) salt=05775A1C0BAFCADE key=7CD6F050EDDFD3083D7DA8D108B96919920F0DC095E33324F78EB7FF929E9AE7 iv =28F39B18DC77C6A90A854A79006BB0B2 See "openssl.txt" for more info. pbkdf2_openssl.c Before this however it was only accessable via the OpenSSL library function PKCS5_PBKDF2_HMAC_SHA1(), which made accessing it very difficult. A trivial C example program "pkcs5.c" was found on the OpenSSL forum, which I modifed to generate a program "pbkdf2.c" to break out this function from the openssl library to command line (for both shell and perl access). See https://antofthy.gitlab.io/software/#pbkdf2_openssl echo -n "passphrase" | pbkdf2_openssl salt_hex count > 48_byte_hex_key_and_iv # For example (16 byte salt) echo -n "passphrase" | pbkdf2_openssl 05775a1c0bafcade 1000 # ... 96 hex characters ... for a 32 byte key and 16 byte IV use Crypt::PBKDF2; Perl module to access openssl cryptograpy functions. However this has a HUGE dependancy storm of unneeded and unwanted functions. use Crypt::KeyDerivation 'pbkdf2'; http://search.cpan.org/~mik/CryptX-0.021/lib/Crypt/KeyDerivation.pm Very good, though it defaults to using 'SHA256' and only 5000 iterations But the defaults can be changed. pbkdf2.pl A PBKDF2 function written purely in perl (no dependancies at all), proved to be equivelent to the OpenSSL function. It was found in the obscure Palm::Keyring module on CPAN, from which I extracted and tested it against the above openssl library function. http://www.perlmonks.org/?node_id=631963 This has been converted to a standalone perl script (or include module) See https://antofthy.gitlab.io/software/#pbkdf2 echo "passphrase" | pbkdf2.pl salt_hex count > 48_byte_hex_key_and_iv # For example echo "passphrase" | pbkdf2.pl 05775a1c0bafcade 1000 # ... 96 hex characters ... for a 32 byte key and 16 byte IV # KEY=7CD6F050EDDFD3083D7DA8D108B96919920F0DC095E33324F78EB7FF929E9AE7 # IV =28F39B18DC77C6A90A854A79006BB0B2 # Which is the same as tteh openssl 1.1.1 -pbkdf2 output This function has also been incorperated directly into my "encrypt" and "ks" perl scripts. It is slower than using the command line "pbkdf2_openssl" program (see above), but removes the non-standard dependancies in my scripts. I used this for many years, until openssl command line provided access to the PBKDF2 function for file encryption. python library hashlib python3 import hashlib passwd = b'passphrase' salt = bytes.fromhex('05775a1c0bafcade') dk = hashlib.pbkdf2_hmac( hash_name='sha1', password=passwd, salt=salt, iterations=1000, dklen=48, ) print( "KEY="+dk[:32].hex() ) print( "IV ="+dk[32:].hex() ) # KEY=7cd6f050eddfd3083d7da8d108b96919920f0dc095e33324f78eb7ff929e9ae7 # IV= 28f39b18dc77c6a90a854a79006bb0b2 Which as you can see is also the same as openssl, and pbkdf2.pl ------------------------------------------------------------------------------- bcrypt KDF for passwords used extensivally for Linux and BSD systems. Includes salt and iteration (cost factor) like PDKDF2, but more memory usage to make it more secure. From... http://security.stackexchange.com/questions/4781/ Bcrypt has the best kind of repute that can be achieved for a cryptographic algorithm: it has been around for quite some time, used quite widely, "attracted attention", and yet remains unbroken to date. The only warning known is to NOT use sha1/sha2 (even if salted) Example Usage crypt('password', '$6$round=1234$mysaltysalt$'); ------------------------------------------------------------------------------- scrypt A KDF designed specifically to use very slow and memory hungry derivation algorithms, so that it cannot be implemented using dedicated hardware (like GPUs), and thus making it harder for brute force dictionary attacks. It has 'salting' built into the algorithm. Developed in 2009, gaining notority in 2013, and not available in OpenSSL Perl usage... use Crypt::ScryptKDF ------------------------------------------------------------------------------- argon2 Is one of the latest hashing funtions (PHC competition 2015) not based on AES, and has time, memory, and parallelism, parameters, with built in ability to determine when a password needs to be re-hashed and upgraded. See "passwd_hashing.txt" for more information. -------------------------------------------------------------------------------