3

I need to implement account management for my application, and I would rather not use chpasswd subprocess, or otherwise let the plaintext password out my my application's memory space.

I want to use putspent with a password hash I generate with crypt, but I can't find any standard function to randomize a salt for crypt. An online search only found weird hashing function implementations I'd rather not copy into my code. Is there a standard function that would generate a salt for me?

Otherwise, would it be wise to just re-use the current salt stored in my shadow file? I couldn't think of why it WOULD be a security hazard (it will not weaken my shadow file against a rainbow table attack), it just feels wrong because in systems security a rule of thumb is to always randomize everything... (Users are added with system utilities)

immortal
  • 3,118
  • 20
  • 38
  • What do you mean by "standard"? If you mean POSIX, the salt is just two random characters, but this would mean DES encryption -- not a good idea. Do you intend to use `glibc` extensions of `crypt()`, allowing e.g. for SHA-256 encryption? –  Aug 03 '17 at 08:41
  • 1
    Not wise to reuse the salt for sure. Also, `crypt` is not a [syscall](https://en.wikipedia.org/wiki/System_call), and so neither would be the hypothetical `new_salt`. You can use `getrandom` on recent Linuxen to get random bytes for the salt - then mask those unsigned chars with `& 63`, map to `[a-zA-Z0-9./]` for salt. – Antti Haapala -- Слава Україні Aug 03 '17 at 08:57
  • Thank you both. Yes, I mean POSIX/standard libs including glib. Yes, of course I'd use SHA 512. Is there any such function in any standard lib? Are we really expected to write such function manually each time? – immortal Aug 03 '17 at 09:21

3 Answers3

0

It depends on your libc version. In newer Versions there is crypt_gensalt which should be what you need. Use the *_rn versions to be thread-safe.

Example:

#include <crypt.h>
#include <stddef.h>
#include <stdio.h>

int main() {
    char result[CRYPT_GENSALT_OUTPUT_SIZE];
    const char* salt = crypt_gensalt_rn("$6$", 0, NULL, 0, result, sizeof(result));

    if(salt == NULL)
        return -1;

    printf("salt: %s\n", salt);

    struct crypt_data state_data = {0};
    const char* hash = crypt_rn("password", salt, &state_data, sizeof(state_data));

    printf("hash: %s\n", hash);
}
heine
  • 599
  • 5
  • 18
-1

OpenSSL provides functions for sha512:

https://www.openssl.org/docs/man1.0.2/crypto/SHA512.html

int SHA256_Init(SHA256_CTX *c);
int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
int SHA256_Final(unsigned char *md, SHA256_CTX *c);
unsigned char *SHA256(const unsigned char *d, size_t n,
      unsigned char *md);
user803422
  • 2,636
  • 2
  • 18
  • 36
-2

For generating a salt for crypt(), you need 2 random bytes. For this, you can use openssl:

#include <openssl/rand.h>
int RAND_bytes(unsigned char *buf, int num);
int RAND_pseudo_bytes(unsigned char *buf, int num);

Ref: https://www.openssl.org/docs/man1.0.2/crypto/RAND_bytes.html

Example:

unsigned char salt[2];
RAND_pseudo_bytes(salt, 2);
char *ptr = crypt(password, salt);
user803422
  • 2,636
  • 2
  • 18
  • 36
  • 1
    I'm afraid this code will not yield the desired result... A salt is a string in the form of `$6$salt$`where 6 means SHA 512 and salt is an 8 to 16 chars string of [a-zA-Z0-9./] – immortal Aug 05 '17 at 06:41