4 ms·
Ask HN: Best way to derive an AES256 key from a password/passphrase?
Hi all, I'm working on a crypto app that will use AES256 to encrypt data and am looking for a good way to come up with the AES key.
My current approach to generate the aes key is to ask for a password/passphrase, bcrypt it, then do a SHA256 on the bcrypt hash to generate the key, and store the bcrypt salt. The purpose of the SHA256 is because the bcrypt hash wouldn't be 256 bits.
Are there any weaknesses in this scenario? If so, can anyone suggest a better approach?
Please be polite.
- marshray 15y ago> The purpose of the SHA256 is because the bcrypt hash wouldn't be 256 bits. That's nearly equivalent to padding it out with zeroes, which is a lot like just using AES-128 in the first place. > Are there any weaknesses in this scenario? Make sure your bcrypt code isn't vulnerable to the common implementation bug disclosed a year or so ago. > If so, can anyone suggest a better approach? PBKDF2[ HMAC[SHA-2-256] ] or PBKDF2[ HMAC[SHA-2-512/256] ] can be used to derive your AES-256 keys, and are more officially standard than bcrypt.
- chubs 15y agoThankyou for the helpful reply. I'll look into the PBKDF2 approach. Which would be better, the first or second one you described? And what is the 'common implementation bug' in bcrypt you described, so i can look out for it?
- chubs 15y agoSounds like OpenSSL's 'PKCS5_PBKDF2_HMAC_SHA1' is the 'officially standard' way to make a key from a password, am i on the right track?
- marshray 15y agoYes, that sounds great. SHA-1 is officially deprecated, but there aren't known weaknesses with using it in PBKDF2 and HMAC. Still, prefer SHA-2 ("SHA-256" or "SHA-512") if it's available. Be sure you specify an iteration count high enough to consume noticeable time (it should hurt a little bit) and store that count with the salt.
- chubs 15y agoThanks a lot! Very helpful. I'll use that then, since it's part of openssl - then i can claim rightly that i use industry standard crypto, rather than my bcrypt/sha256 mashup that i dreamt up myself.
- chubs 15y agoOK here's my code, any issues with it anyone can see? #import <CommonCrypto/CommonKeyDerivation.h> ... // Makes a random 256-bit salt - (NSData*)generateSalt256 { unsigned char salt[32]; for (int i=0; i<32; i++) { salt[i] = (unsigned char)arc4random(); } return [NSData dataWithBytes:salt length:32]; } ... // Make keys! NSString* myPass = @"MyPassword1234"; NSData* myPassData = [myPass dataUsingEncoding:NSUTF8StringEncoding]; NSData* salt = [self generateSalt256]; // How many rounds to use so that it takes 0.1s ? int rounds = CCCalibratePBKDF(kCCPBKDF2, myPassData.length, salt.length, kCCPRFHmacAlgSHA256, 32, 100); // Open CommonKeyDerivation.h for help unsigned char key[32]; CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes, myPassData.length, salt.bytes, salt.length, kCCPRFHmacAlgSHA256, rounds, key, 32);