1
$\begingroup$

Are there any suitable key derivation functions that allow the output to have certain constraints applied to them?`

I know you can choose a length in some functions (HKDF for example), but what about restricting the output to conform to a subset of the printable ASCII set, such as [a-Z][A-Z][0-9].

Thanks

$\endgroup$
  • 4
    $\begingroup$ Welcome to Cryptography. This is not about Cryptography, this is about encoding the output. Look for base64 or Binary to Text encoding. $\endgroup$ – kelalaka Feb 13 at 9:18
  • $\begingroup$ Having a base that is a power of two is highly recommended of course, otherwise you may have to use big integers for your base conversion (or use escaping for some values). The output of almost all modern crypto functions is binary after all. Your ASCII consists of 62 characters, which is not a good idea in that sense. $\endgroup$ – Maarten Bodewes Feb 13 at 14:53
1
$\begingroup$

Modern cryptography operates mostly on binary values or big numbers. And generally cryptography that operates on numbers encodes / decodes those numbers to binary as well (RSA PKCS#1 specifies binary representations for the public key, private key and of course the ciphertext and signatures). If an API specifies text input / output it is generally provided as a convenience to the programmer rather than that it is part of the implemented algorithm specification.

To have printable ASCII it is easiest to convert the binary value generated by your KDF to base64 or base64url. In that case each character encodes 6 bits. It should be easy to calculate the output size of the KDF to give the precise amount of base 64 characters. Otherwise you could still cut of the left over base 64 characters, but remember that base 64 implementations may require you to input 4 characters at a time (including padding characters) making it impossible to decode your pruned base 64 encoding directly. It would make sense to use a multiple of 3 for the output of the KDF / multiple of 4 characters after encoding using base 64.

To have base 62 (as specified in your question) is much harder, as 62 is not a power of two. That means that you either need to perform base conversion using big integer calculations (divide-and-remainder) or you'll have to convert to base64 and escape out three characters (the +, the / and the escape character itself). Escaping will result in a variable length encoding though, maxing out on doubling the base64 string in size.


Notes:

  • Hexadecimals is even easier to work with: it takes 2 characters per byte, and that's it. It will expand the output some more, but that may be worth it for the convenience it offers;
  • Encoding keying material in a textual string is generally frowned upon. Strings are easy to find in application code and are generally hard to destroy (e.g. Java has immutable strings that may not be garbage collected either).
$\endgroup$
  • $\begingroup$ The last note is the golden point. $\endgroup$ – kelalaka Feb 13 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.