Advertisement
Guest User

Untitled

a guest
May 6th, 2015
257
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.37 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/time.h>
  5. #include <openssl/pem.h>
  6. #include <openssl/rand.h>
  7.  
  8. int my_better_rand_bytes(unsigned char *buf, int num_bytes);
  9. void seed_randomness();
  10.  
  11. int main (int argc, char *argv[])
  12. {
  13.  
  14. // Normal house keeping
  15. char *priv_key_file = "q1_privkey.priv";
  16. char *pub_key_file = "q1_pubkey.pub";
  17. FILE *fp;
  18. int num_bits = 2048;
  19.  
  20. // This is a recommend public exponent everyone uses. 65537.
  21. unsigned long exponent = RSA_F4;
  22.  
  23. // Those openssl guys are CHUMPS. Did you see that debian bug? What the
  24. // heck. I don't trust them, I'm going to write my own random
  25. // implementation. That way I know it will be secure.
  26.  
  27. // Hmm, in openssl lingo the way you generate random numbers is with a
  28. // RAND_METHOD Looks like I need to create my own RAND_METHOD structure. It
  29. // has a bunch of stuff in it, but the only really important parts are the
  30. // pseudrand and rand members.
  31. RAND_METHOD my_better_random_method;
  32.  
  33. // Part of the house keeping is I need to clear the struct
  34. memset(&my_better_random_method, 0x00, sizeof(RAND_METHOD));
  35.  
  36.  
  37. // From the openssl man pages it looks liked I need to set two key functions:
  38. // pseudorand which behaves like RAND_pseudo_bytes, and
  39. // bytes which behaves like RAND_bytes.
  40. // man page: http://linux.die.net/man/3/rand_bytes
  41. // In my implementation, all bytes are pseudorandom, so these are the same
  42. my_better_random_method.pseudorand = my_better_rand_bytes;
  43. my_better_random_method.bytes = my_better_rand_bytes;
  44.  
  45. // Okies I built my random method, now I just need tell openssl to use it
  46. RAND_set_rand_method(&my_better_random_method);
  47.  
  48. // Seed my random function...
  49. seed_randomness();
  50.  
  51. // Finally I can sleep at night.
  52.  
  53. // Create our key
  54. RSA *rsa = RSA_generate_key(num_bits,exponent,NULL,NULL);
  55.  
  56. // The RSA structure has all our important fields. n, e, d, p, q, etc.
  57. // struct
  58. // {
  59. // BIGNUM *n; // public modulus
  60. // BIGNUM *e; // public exponent
  61. // BIGNUM *d; // private exponent
  62. // BIGNUM *p; // secret prime factor
  63. // BIGNUM *q; // secret prime factor
  64. // BIGNUM *dmp1; // d mod (p-1)
  65. // BIGNUM *dmq1; // d mod (q-1)
  66. // BIGNUM *iqmp; // q^-1 mod p
  67. // // ...
  68. // };
  69. // RSA
  70. // http://www.openssl.org/docs/crypto/rsa.html
  71. // But even with all those fields, n is enough to uniquely match a public and
  72. // private keypair.
  73. //
  74. // BIGNUM's are hard to work with directly, though. You have to use things like
  75. // BN_cmp().
  76. // http://www.openssl.org/docs/crypto/BN_cmp.html
  77.  
  78. // Write out the private key
  79. if (!(fp = fopen(priv_key_file, "w"))){
  80. fprintf(stderr, "Could not open private key file %s\n", priv_key_file);
  81. exit(1);
  82. }
  83.  
  84. // openssl has this handy function to write out our private key in the correct format. Awesome.
  85. if (!PEM_write_RSAPrivateKey( fp, // Output file
  86. rsa, // Our private key
  87. NULL,NULL,0,NULL,NULL // Houekeeping
  88. )
  89. ){
  90. fprintf(stderr, "Could not write private key file %s\n", priv_key_file);
  91. exit(1);
  92. }
  93. fclose(fp);
  94.  
  95. // Write out the public key
  96. if (!(fp = fopen(pub_key_file, "w"))){
  97. fprintf(stderr, "Could not open public key file %s\n", pub_key_file);
  98. exit(1);
  99. }
  100.  
  101. // Just like the private key, the public key can be written by openssl
  102. if (!PEM_write_RSAPublicKey(fp, rsa))
  103. {
  104. fprintf(stderr, "Could not write public key file %s\n", pub_key_file);
  105. exit(1);
  106. }
  107. fclose(fp);
  108.  
  109. // OpenSSL has a corresponding read function, it looks like: PEM_read_RSAPublicKey
  110. exit(0); // Security Success!
  111.  
  112. }
  113.  
  114. // K&R are awesome guys. I once got a chance to meet them. I'm sure their
  115. // random number generation is cryptographically secure, given an unguessable
  116. // seed. Let's just use their rand() call.
  117. int my_better_rand_bytes(unsigned char *buf, int num_bytes)
  118. {
  119.  
  120. for (int i = 0; i < num_bytes; i+=4)
  121. {
  122. int rand_int = rand();
  123. #define min(a,b) (((a)<(b))?(a):(b))
  124. memcpy(buf + i, &rand_int, min(num_bytes - i,4));
  125. }
  126.  
  127. return 1; // 1 means good!
  128. }
  129.  
  130. // For the standard C rand I need to seed it with srand()...
  131. void seed_randomness()
  132. {
  133. // my_better_rand_bytes needs a seed for my random function. I need
  134. // something random and unguessable... how about the system time when I
  135. // turn on the program?
  136.  
  137. struct timeval t;
  138. gettimeofday(&t, NULL);
  139.  
  140. unsigned int time_in_sec = t.tv_sec; // Current seconds since epoc (midnight, jan 1, 1970)
  141. unsigned int time_micro_sec = t.tv_usec; // Number of microseconds this second
  142. unsigned int seed;
  143.  
  144. // Set the seed to the number of seconds since epoc
  145. seed = time_in_sec;
  146.  
  147. // Add to that the number of milli-seconds
  148. seed = time_micro_sec >> 7;
  149.  
  150. srand(seed); // Unguessable!
  151. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement