(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.
- 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.