

Ask HN: Best way to derive an AES256 key from a password/passphrase? - chubs

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.<p>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.<p>Are there any weaknesses in this scenario? If so, can anyone suggest a better approach?<p>Please be polite.
======
marshray
> 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
Thankyou 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
Sounds 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
Yes, 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
Thanks 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
OK 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);

