Last active
August 18, 2021 19:43
-
-
Save bdd/1115291 to your computer and use it in GitHub Desktop.
Generate a key from a passpharse w/ PBKDF2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2011 Berk D. Demir <bdd@mindcast.org> | |
* | |
* Permission to use, copy, modify, and distribute this software for any | |
* purpose with or without fee is hereby granted, provided that the above | |
* copyright notice and this permission notice appear in all copies. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
*/ | |
/* | |
* OpenSSL doesn't provide a userland tool for PBKDF2. | |
* | |
* I recently needed this for supplying Crashplan my own encryption key | |
* for its Blowfish cipher. | |
* | |
* Sadly I realized their passphrase implementation was simply padding the | |
* password to 448-bits and storing it in base64. Sigh... | |
* | |
* This small piece of code gets password, salt, number of iterations and | |
* desired key length in bytes and outputs HMAC SHA1 backed PBKDF2 function | |
* output to stdout as binary. | |
* | |
* Use pipes or shell i/o redirection to make the output useful. | |
* | |
* e.g. | |
* % pbkdf2 password salt 1024 56 > bf448.key | |
* | |
* % pbkdf2 password salt 1024 56 | openssl base64 | |
* | |
*/ | |
#include <err.h> | |
#include <errno.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <openssl/evp.h> | |
int | |
main(int argc, char *argv[]) | |
{ | |
const char *usage = "usage: %s <password> <salt> <iterations> <keylen>"; | |
const char *errstr_notint = "\"%s\" is not a decimal integer."; | |
unsigned char *out; | |
const char *pass, *salt; | |
int iter, keylen; | |
if (argc != 5) | |
errx(1, usage, argv[0]); | |
pass = argv[1]; | |
salt = argv[2]; | |
iter = (int)strtol(argv[3], (char **)NULL, 10); | |
keylen = (int)strtol(argv[4], (char **)NULL, 10); | |
if (errno != 0) { /* strtol failed */ | |
if (iter == 0) | |
warnx(errstr_notint, argv[3]); | |
if (keylen == 0) | |
warnx(errstr_notint, argv[4]); | |
errx(1, usage, argv[0]); | |
} | |
out = malloc(keylen); | |
if (out == NULL) | |
err(1, "Couldn't allocate memory."); | |
/* always returns 1 */ | |
PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), | |
salt, strlen(salt), | |
iter, keylen, | |
out); | |
if (write(1, out, keylen) == -1) | |
return 1; | |
else | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
passing 'const char *' to parameter of type 'const unsigned char *' converts between pointers to integer types with different sign [-Wpointer-sign]