0

I'm building a simple encryption tool in dart.

I need to encrypt my rsa private key with a pass phrase.

I'm using AES to do the encryption.

AES requires keys to be a specific no. of bits.

In my case 256 bits.

I'm requiring that the user enter a passphrase of at least 16 characters (128 bits).

As such I need to extend the passphrase to a full 256 bits.

Currently I just double the pass phrase and then clip the result to 256 bits.

Is this the correct thing to do or is the a more secure method of padding the key?

I'm using the dart pointycastle libraries which are based on the java bouncycastle libraries.


Update

Here is my latest attempt

class StrongKey extends Key {
  StrongKey.fromPassPhrase(String passPhrase) : super.fromUtf8(passPhrase);

  Key secureStretch(Uint8List salt) {
    return stretch(256, iterationCount: 100000, salt: salt);
  }

  @override
  Key stretch(int desiredKeyLength, {int iterationCount = 100, Uint8List salt}) {
    final params = Pbkdf2Parameters(salt, iterationCount, desiredKeyLength);
    final pbkdf2 = PBKDF2KeyDerivator(Mac('SHA-512/HMAC'))..init(params);

    return Key(pbkdf2.process(bytes));
  }

  static Uint8List get generateSalt => SecureRandom(256).bytes;
}
Brett Sutton
  • 3,900
  • 2
  • 28
  • 53
  • 2
    You'd use a password based key derivation function (PBKDF) such as a secure version of Argon2 or, indeed, PBKDF2. You'd need a high iteration count and store a salt with the encrypted RSA key. Of course, 16 characters doesn't contain even close to 128 bits of randomness, so using AES-256 is fooling yourself. – Maarten Bodewes Aug 17 '20 at 22:44
  • 16 * 8 = 128 or have I misunderstood the bitness. This is intended as the minimum pass phrase and the app recommends users use a higher no. of chars. If its not enough randomness then how do you utilise a reasonable passphrase to encrypt a private key? – Brett Sutton Aug 18 '20 at 00:30
  • when you say store the salt I assume that the salt needs to be stored in clear text as it needs to be used to decrypt the key? I assume I need to add the salt to the pass phrase in a similar manner used for password hashing. – Brett Sutton Aug 18 '20 at 00:32
  • The passphrase is not using 128 bits because a normal user would not utilize all 256 possible characters for each byte. Passphrases are inherently weak, that's one reason why you'd use a PBKDF. AES-128 seems sufficient, as it is not the weak spot. Yes, the salt just needs to be unique, but usually it's, say, a 16 **bytes** random value stored with the encrypted key. – Maarten Bodewes Aug 18 '20 at 07:12
  • @MaartenBodewes I've updated the question with a class I found that looks like implements your suggestion. Can you confirm this looks OK? – Brett Sutton Aug 18 '20 at 09:17
  • The `from...` methods should be removed. The default iteration count is at least a factor of a thousand off, and the use of SHA-1 is not a good idea if you want to output 256 bits. For PBKDF2 you want to use a hash that can at least output as many bits as required (using SHA-512 instead is probably the best method to make sure that this is the case). – Maarten Bodewes Aug 18 '20 at 11:41
  • So to be clear the iteration should be 100,000. – Brett Sutton Aug 19 '20 at 13:10
  • @MaartenBodewes I've posted an updated version of the Key generator which I believe follows your instructions. – Brett Sutton Aug 19 '20 at 13:30
  • @MaartenBodewes I'm probably pushing the love now, but this is what I'm trying to create. https://github.com/bsutton/dvault/wiki any feedback would be greatly appreciated. – Brett Sutton Aug 19 '20 at 13:33

0 Answers0