#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
int my_better_rand_ bytes(unsigned char *buf, int num_bytes);
void seed_randomness ();
int main (int argc, char *argv[])
{
// Normal house keeping
char *priv_key_file = "q1_privkey.pri v";
char *pub_key_file = "q1_pubkey.pub" ;
FILE *fp;
int num_bits = 2048;
// This is a recommend public exponent everyone uses. 65537.
unsigned long exponent = RSA_F4;
// Those openssl guys are CHUMPS. Did you see that debian bug? What the
// heck. I don't trust them, I'm going to write my own random
// implementation. That way I know it will be secure.
// Hmm, in openssl lingo the way you generate random numbers is with a
// RAND_METHOD Looks like I need to create my own RAND_METHOD structure. It
// has a bunch of stuff in it, but the only really important parts are the
// pseudrand and rand members.
RAND_METHOD my_better_rando m_method;
// Part of the house keeping is I need to clear the struct
memset(&my_bett er_random_metho d, 0x00, sizeof(RAND_MET HOD));
// From the openssl man pages it looks liked I need to set two key functions:
// pseudorand which behaves like RAND_pseudo_byt es, and
// bytes which behaves like RAND_bytes.
// man page: http://linux.die.net/man/3/rand_bytes
// In my implementation, all bytes are pseudorandom, so these are the same
my_better_rando m_method.pseudo rand = my_better_rand_ bytes;
my_better_rando m_method.bytes = my_better_rand_ bytes;
// Okies I built my random method, now I just need tell openssl to use it
RAND_set_rand_m ethod(&my_bette r_random_method );
// Seed my random function...
seed_randomness ();
// Finally I can sleep at night.
// Create our key
RSA *rsa = RSA_generate_ke y(num_bits,expo nent,NULL,NULL) ;
// The RSA structure has all our important fields. n, e, d, p, q, etc.
// struct
// {
// BIGNUM *n; // public modulus
// BIGNUM *e; // public exponent
// BIGNUM *d; // private exponent
// BIGNUM *p; // secret prime factor
// BIGNUM *q; // secret prime factor
// BIGNUM *dmp1; // d mod (p-1)
// BIGNUM *dmq1; // d mod (q-1)
// BIGNUM *iqmp; // q^-1 mod p
// // ...
// };
// RSA
// http://www.openssl.org/docs/crypto/rsa.html
// But even with all those fields, n is enough to uniquely match a public and
// private keypair.
//
// BIGNUM's are hard to work with directly, though. You have to use things like
// BN_cmp().
// http://www.openssl.org/docs/crypto/BN_cmp.html
// Write out the private key
if (!(fp = fopen(priv_key_ file, "w"))){
fprintf(stderr, "Could not open private key file %s\n", priv_key_file);
exit(1);
}
// openssl has this handy function to write out our private key in the correct format. Awesome.
if (!PEM_write_RSA PrivateKey( fp, // Output file
rsa, // Our private key
NULL,NULL,0,NUL L,NULL // Houekeeping
)
){
fprintf(stderr, "Could not write private key file %s\n", priv_key_file);
exit(1);
}
// Write out the public key
if (!(fp = fopen(pub_key_f ile, "w"))){
fprintf(stderr, "Could not open public key file %s\n", pub_key_file);
exit(1);
}
// Just like the private key, the public key can be written by openssl
if (!PEM_write_RSA PublicKey(fp, rsa))
{
fprintf(stderr, "Could not write public key file %s\n", pub_key_file);
exit(1);
}
// OpenSSL has a corresponding read function, it looks like: PEM_read_RSAPub licKey
exit(0); // Security Success!
}
// K&R are awesome guys. I once got a chance to meet them. I'm sure their
// random number generation is cryptographical ly secure, given an unguessable
// seed. Let's just use their rand() call.
int my_better_rand_ bytes(unsigned char *buf, int num_bytes)
{
for (int i = 0; i < num_bytes; i+=4)
{
int rand_int = rand();
memcpy(buf + i, &rand_int, num_bytes - i);
}
return 1; // 1 means good!
}
// For the standard C rand I need to seed it with srand()...
void seed_randomness ()
{
// my_better_rand_ bytes needs a seed for my random function. I need
// something random and unguessable... how about the system time when I
// turn on the program?
struct timeval t;
gettimeofday(&t , NULL);
unsigned int time_in_sec = t.tv_sec; // Current seconds since epoc (midnight, jan 1, 1970)
unsigned int time_micro_sec = t.tv_usec; // Number of microseconds this second
unsigned int seed;
// Set the seed to the number of seconds since epoc
seed = time_in_sec;
// Add to that the number of milli-seconds
seed = time_micro_sec >> 7;
srand(seed); // Unguessable!
}
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
int my_better_rand_ bytes(unsigned char *buf, int num_bytes);
void seed_randomness ();
int main (int argc, char *argv[])
{
// Normal house keeping
char *priv_key_file = "q1_privkey.pri v";
char *pub_key_file = "q1_pubkey.pub" ;
FILE *fp;
int num_bits = 2048;
// This is a recommend public exponent everyone uses. 65537.
unsigned long exponent = RSA_F4;
// Those openssl guys are CHUMPS. Did you see that debian bug? What the
// heck. I don't trust them, I'm going to write my own random
// implementation. That way I know it will be secure.
// Hmm, in openssl lingo the way you generate random numbers is with a
// RAND_METHOD Looks like I need to create my own RAND_METHOD structure. It
// has a bunch of stuff in it, but the only really important parts are the
// pseudrand and rand members.
RAND_METHOD my_better_rando m_method;
// Part of the house keeping is I need to clear the struct
memset(&my_bett er_random_metho d, 0x00, sizeof(RAND_MET HOD));
// From the openssl man pages it looks liked I need to set two key functions:
// pseudorand which behaves like RAND_pseudo_byt es, and
// bytes which behaves like RAND_bytes.
// man page: http://linux.die.net/man/3/rand_bytes
// In my implementation, all bytes are pseudorandom, so these are the same
my_better_rando m_method.pseudo rand = my_better_rand_ bytes;
my_better_rando m_method.bytes = my_better_rand_ bytes;
// Okies I built my random method, now I just need tell openssl to use it
RAND_set_rand_m ethod(&my_bette r_random_method );
// Seed my random function...
seed_randomness ();
// Finally I can sleep at night.
// Create our key
RSA *rsa = RSA_generate_ke y(num_bits,expo nent,NULL,NULL) ;
// The RSA structure has all our important fields. n, e, d, p, q, etc.
// struct
// {
// BIGNUM *n; // public modulus
// BIGNUM *e; // public exponent
// BIGNUM *d; // private exponent
// BIGNUM *p; // secret prime factor
// BIGNUM *q; // secret prime factor
// BIGNUM *dmp1; // d mod (p-1)
// BIGNUM *dmq1; // d mod (q-1)
// BIGNUM *iqmp; // q^-1 mod p
// // ...
// };
// RSA
// http://www.openssl.org/docs/crypto/rsa.html
// But even with all those fields, n is enough to uniquely match a public and
// private keypair.
//
// BIGNUM's are hard to work with directly, though. You have to use things like
// BN_cmp().
// http://www.openssl.org/docs/crypto/BN_cmp.html
// Write out the private key
if (!(fp = fopen(priv_key_ file, "w"))){
fprintf(stderr, "Could not open private key file %s\n", priv_key_file);
exit(1);
}
// openssl has this handy function to write out our private key in the correct format. Awesome.
if (!PEM_write_RSA PrivateKey( fp, // Output file
rsa, // Our private key
NULL,NULL,0,NUL L,NULL // Houekeeping
)
){
fprintf(stderr, "Could not write private key file %s\n", priv_key_file);
exit(1);
}
// Write out the public key
if (!(fp = fopen(pub_key_f ile, "w"))){
fprintf(stderr, "Could not open public key file %s\n", pub_key_file);
exit(1);
}
// Just like the private key, the public key can be written by openssl
if (!PEM_write_RSA PublicKey(fp, rsa))
{
fprintf(stderr, "Could not write public key file %s\n", pub_key_file);
exit(1);
}
// OpenSSL has a corresponding read function, it looks like: PEM_read_RSAPub licKey
exit(0); // Security Success!
}
// K&R are awesome guys. I once got a chance to meet them. I'm sure their
// random number generation is cryptographical ly secure, given an unguessable
// seed. Let's just use their rand() call.
int my_better_rand_ bytes(unsigned char *buf, int num_bytes)
{
for (int i = 0; i < num_bytes; i+=4)
{
int rand_int = rand();
memcpy(buf + i, &rand_int, num_bytes - i);
}
return 1; // 1 means good!
}
// For the standard C rand I need to seed it with srand()...
void seed_randomness ()
{
// my_better_rand_ bytes needs a seed for my random function. I need
// something random and unguessable... how about the system time when I
// turn on the program?
struct timeval t;
gettimeofday(&t , NULL);
unsigned int time_in_sec = t.tv_sec; // Current seconds since epoc (midnight, jan 1, 1970)
unsigned int time_micro_sec = t.tv_usec; // Number of microseconds this second
unsigned int seed;
// Set the seed to the number of seconds since epoc
seed = time_in_sec;
// Add to that the number of milli-seconds
seed = time_micro_sec >> 7;
srand(seed); // Unguessable!
}
Comment