4

(Not to be confused with the DES algorithm subkey generation)
(edit: more examples)

Explanation of problem:

I'm doing this as part of a school assignment where I'm required to recode parts of OpenSSL in C, specifically those pertaining to PKI cryptosystems. So far I've recoded from scratch the core DES algorithm with ecb, cbc, 3des-ecb, and 3des-cbc modes of operation. Other parts of the project include MD5 and SHA256. This portion of the project focuses on RSA key generation, manipulation and usage.

Part of RSA key manipulation includes encrypting a given key with a passphrase.
(not with the pure key + initial vector alone like I've done before with DES)

This requires converting the user-input passphrase to a DES key (and optional additional IV as needed), and then using that to encrypt a RSA key. I know the general term for the function I'm looking for is PBKDF, or Password-Based Key Derivation Function. However, I have not been able (through searching the man pages of OpenSSL or google) to find what exact function (or functions) are used in OpenSSL for key derivation.

Demonstration of DES key generation encrypting RSA keys:

Running the following command with no passphrase generate an unencrypted RSA key example_plain_key.

ssh-keygen -t rsa -f example_plain_key

Then running the following commands will encrypt example_plain_key with the des cipher in ecb mode. Each command outputs the encrypted version to a new file so it doesn't change the original. Use the same passphrase for both commands (password, for example).

openssl rsa -DES-ECB -in id_rsa -out id_rsa_1
openssl rsa -DES-ECB -in id_rsa -out id_rsa_2

You can use head id_rsa and head id_rsa_1 to see how encrypting a key changes the header. If you compare the two new keys with

diff id_rsa_1 id_rsa_2

they will be identical in the header and formatting, but the key itself will be encrypted differently, even though the same passphrase is used. The difference is because the key generation (I believe) generates a new random salt every time it is ran. I would assume the hashing algorithm and the number of iterations would be the same. Also, unlike /etc/shadow on unix machines, the salt doesn't appear to be stored alongside the key (or at least I don't know how to read it).

Demonstration of DES key generation from password:

A more DES-specific example is:

openssl des -P

Running the above command any number of times with the same password will always result in a different key and iv, probably because the salt is different.

My findings, and deducted assumptions:

  • Searching "how are rsa keys encrypted?" brings up a lot of results on using RSA keys to encrypt. (sometimes I expect too much from Google's nlp)
  • Searching "how are DES keys generated from passphrase?" brings up a lot of results on how to generate the 16 round des subkeys.
  • I've skimmed the source of OpenSSL with no luck. I'll do an exhaustive search if absolutely necessary, but the code isn't the most readable or searchable.

  • php prototype

  • perl man page
  • A link I thought would be more helpful than it was
    (Note: I don't have an account with OpenSSL but don't think it'd be required to view)

The most helpful findings led me to believe an example prototype of what I'm looking for would look something like this:

#include <unistd.h>
#include <stdio.h>
#include <pwd.h>
// #include <something_else_maybe.h>

int     main(void)
{
    int     num_iterations = 1000;
    char    *salt;
    char    *passphrase;
    char    *key;

    passphrase = getpass("Password: ");
    salt = get_some_random_bytes(8); // assumed arbitrary length

    // the function in question
    key = example_pbkdf(md5_function, num_iterations, salt, 8, passphrase, strlen(passphrase));

    printf("Key (in hexadecimal or otherwise) is: %s\n", key);

    free(key);
    free(passphrase);
    free(salt);
    return (0);
}

Things I am specifically looking for:

(Knowing where to look for these answers would be more valuable than the answers themselves, but all help is appreciated. I do need the header/source/prototype/etc in C though.)

  • The function (if it exists) that operates like the one demonstrated above. It doesn't have to be a perfect match, I'm more concerned about what it does rather than the exact prototyping or usage.
  • Alternatively, (if it doesn't exist) the "recipe" or series of operations that could be summarized as "the algorithm" I'm looking for.
  • DES key generation. (though including multiple ciphers, say, AES, is awesome too)
  • How the salt is stored in an ecrypted RSA key, if it is (and if it isn't, how to recover it). I know the IV is stored in the header of a key encrypted with a cipher in CBC.
izcet
  • 49
  • 1
  • 7
  • https://en.wikipedia.org/wiki/PBKDF2 – qrdl Mar 12 '18 at 08:44
  • You might find this helpful since you are interested in Openssl. [https://github.com/openssl/openssl/blob/master/crypto/evp/p5_crpt2.c](https://github.com/openssl/openssl/blob/master/crypto/evp/p5_crpt2.c). – Grant Sanders Mar 12 '18 at 09:12
  • PBKDF@ and also called by names such as Rfc2898 and Rfc2898DeriveBytes. – zaph Mar 19 '18 at 00:26
  • 1
    I found the answer to this question on the [security stack exchange](https://security.stackexchange.com/questions/29106/openssl-recover-key-and-iv-by-passphrase "Security Stack Exchange Answer"). Thank you [Grant Sanders](https://stackoverflow.com/users/5358265/grant-sanders "Grant Sanders Profile"), your link to the source of the function helped point me to the source of the function (which I planned to dismantle and identify) but it turns out the actual process is a lot simpler. Even though a `PBKDF` by definition has a number of iterations and variable hash functions, OpenSSL's implementati – izcet Mar 18 '18 at 21:47

0 Answers0