Advertisement
nitestryker

password gen.

Apr 26th, 2023 (edited)
3,494
0
Never
3
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.68 KB | Software | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <string.h>
  5. #include <limits.h>
  6. #include <unistd.h>
  7. #include <bsd/stdlib.h>
  8. #include <openssl/evp.h>
  9. #include <stdbool.h>
  10. #include <time.h>
  11. #include <ctype.h>
  12.  
  13. #define ALPHABET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+~`|}{[]\\:;?><,./-="
  14. #define ALPHABET_LEN (sizeof(ALPHABET) - 1)
  15. #define SALT_LEN 16
  16. #define ITERATIONS 100000
  17. #define KEY_LEN 32
  18.  
  19. int get_password_length() {
  20.     int len;
  21.     printf("Enter length of password (min 8, max 64): ");
  22.     if (scanf("%d", &len) != 1) {
  23.         printf("Invalid input.\n");
  24.         exit(EXIT_FAILURE);
  25.     }
  26.     if (len < 8 || len > 64) {
  27.         printf("Password length must be between 8 and 64 characters.\n");
  28.         exit(EXIT_FAILURE);
  29.     }
  30.     return len;
  31. }
  32.  
  33. void generate_salt(unsigned char *salt, size_t len) {
  34.     arc4random_buf(salt, len);
  35. }
  36.  
  37. void derive_key(unsigned char *key, size_t key_len, const unsigned char *password,
  38.                 size_t password_len, const unsigned char *salt, size_t salt_len) {
  39.     PKCS5_PBKDF2_HMAC((const char *)password, password_len, salt, salt_len, ITERATIONS,
  40.                       EVP_sha256(), key_len, key);
  41. }
  42.  
  43. void generate_password(char *password, size_t len) {
  44.     unsigned char salt[SALT_LEN];
  45.     generate_salt(salt, sizeof(salt));
  46.  
  47.     unsigned char key[KEY_LEN];
  48.     char password_str[PATH_MAX];
  49.     bool valid_password = false;
  50.     while (!valid_password) {
  51.         printf("Enter master password: ");
  52.         if (fgets(password_str, PATH_MAX, stdin) == NULL) {
  53.             printf("Error reading password.\n");
  54.             exit(EXIT_FAILURE);
  55.         }
  56.         size_t password_len = strlen(password_str) - 1;
  57.         password_str[password_len] = '\0'; /* remove newline character */
  58.         if (password_len < 8) {
  59.             printf("Password must be at least 8 characters long.\n");
  60.         } else {
  61.             valid_password = true;
  62.         }
  63.     }
  64.  
  65.     derive_key(key, sizeof(key), (const unsigned char *)password_str, strlen(password_str),
  66.                salt, sizeof(salt));
  67.  
  68.     size_t i = 0;
  69.     size_t j = 0;
  70.     size_t k = 0;
  71.     unsigned char rand_byte;
  72.     srand(time(NULL));
  73.     while (i < len) {
  74.         if (j == KEY_LEN) {
  75.             /* regenerate key if exhausted */
  76.             derive_key(key, sizeof(key), (const unsigned char *)password_str, strlen(password_str),
  77.                        salt, sizeof(salt));
  78.             j = 0;
  79.         }
  80.         rand_byte = key[j];
  81.         j++;
  82.  
  83.         if (rand_byte < UCHAR_MAX - (UCHAR_MAX % ALPHABET_LEN)) {
  84.             password[i] = ALPHABET[rand_byte % ALPHABET_LEN];
  85.             i++;
  86.         } else {
  87.             k = rand() % len;
  88.             password[k] = ALPHABET[rand_byte % ALPHABET_LEN];
  89.         }
  90.     }
  91. }
  92.  
  93. int count_lowercase(char *str) {
  94.     int count = 0;
  95.     for (int i = 0; str[i]; i++) {
  96.         if (str[i] >= 'a' && str[i] <= 'z') {
  97.             count++;
  98.         }
  99.     }
  100.     return count;
  101. }
  102.  
  103. int count_uppercase(char *str) {
  104.     int count = 0;
  105.     for (int i = 0; str[i]; i++) {
  106.         if (str[i] >= 'A' && str[i] <= 'Z') {
  107.             count++;
  108.         }
  109.     }
  110.     return count;
  111. }
  112.  
  113. int count_digits(char *str) {
  114.     int count = 0;
  115.     for (int i = 0; str[i]; i++) {
  116.         if (str[i] >= '0' && str[i] <= '9') {
  117.             count++;
  118.         }
  119.     }
  120.     return count;
  121. }
  122.  
  123. int count_symbols(char *str) {
  124.     int count = 0;
  125.     for (int i = 0; str[i]; i++) {
  126.         if (!isalnum(str[i])) {
  127.             count++;
  128.         }
  129.     }
  130.     return count;
  131. }
  132.  
  133. void print_strength_meter(int strength) {
  134.     printf("Password strength: ");
  135.     if (strength < 25) {
  136.         printf("Very weak\n");
  137.     } else if (strength < 50) {
  138.         printf("Weak\n");
  139.     } else if (strength < 75) {
  140.         printf("Moderate\n");
  141.     } else if (strength < 100) {
  142.         printf("Strong\n");
  143.     } else {
  144.         printf("Very strong\n");
  145.     }
  146. }
  147.  
  148. int main() {
  149.     int len = get_password_length();
  150.     char *password = malloc((len + 1) * sizeof(char));
  151.     if (password == NULL) {
  152.         perror("malloc");
  153.         exit(EXIT_FAILURE);
  154.     }
  155.  
  156.     generate_password(password, len);
  157.  
  158.     int lowercase_count = count_lowercase(password);
  159.     int uppercase_count = count_uppercase(password);
  160.     int digit_count = count_digits(password);
  161.     int symbol_count = count_symbols(password);
  162.     int strength = ((lowercase_count > 0) + (uppercase_count > 0) + (digit_count > 0) + (symbol_count > 0)) * 25;
  163.  
  164.     printf("Generated password: %s\n", password);
  165.     print_strength_meter(strength);
  166.  
  167.     free(password);
  168.     return 0;
  169. }
  170.  
  171.  
  172. // compile
  173. // gcc -o passgen passgen.c -lcrypto -lbsd
Advertisement
Comments
  • nitestryker
    1 year
    Comment was deleted
  • nitestryker
    1 year
    # C 0.04 KB | 0 0
    1. updated version that checks password strength
  • nitestryker
    1 year
    # text 0.90 KB | 0 0
    1. Here's a brief summary of the functions used in the program:
    2.  
    3. get_password_length() prompts the user to enter a password length and validates the input.
    4. generate_salt() generates a random salt of a specified length.
    5. derive_key() uses the PBKDF2 function from OpenSSL to derive a key from a master password and a salt.
    6. generate_password() generates a password of a specified length using a pseudo-random sequence of characters from a defined alphabet and a key derived from a master password and a salt.
    7. count_lowercase(), count_uppercase(), count_digits(), and count_symbols() count the number of lowercase letters, uppercase letters, digits, and symbols in a given string.
    8. print_strength_meter() prints a description of the password strength based on the number of lowercase letters, uppercase letters, digits, and symbols in a given password.
    9. The program requires the OpenSSL and BSD libraries to compile and run.
Add Comment
Please, Sign In to add comment
Advertisement