/*******************************
编译:
gcc -g -o ssha_check ssha_check.c -lssl
测试:
./ssha_check shanghai 8Mhh1STpS0WOcp15/hd26yZMbE9uRMN0NQcBEQ==
ret: 0
*********************************/
//ssha_check.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>
#define PASSWD_OK (0)
#define PASSWD_ERR (-1)
#define SHA1_BYTES 20
char *base64_decode(unsigned char *in, int32_t len)
{
BIO *b64, *bmem;
char *buffer = (char *)calloc(1, len);
if (buffer == NULL) {
printf("alloc memory fail\n");
return -1;
}
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new_mem_buf(in, len);
bmem = BIO_push(b64, bmem);
BIO_read(bmem, buffer, len);
BIO_free_all(bmem);
return buffer;
}
/*
* @passwd: source passwd from user intpu
* @cred: ssha passwd
* return:
* 0: succ
* -1: fail
*/
static int chk_ssha1(const char *passwd, const char *cred)
{
SHA_CTX SHA1context;
unsigned char SHA1digest[SHA1_BYTES];
int32_t rc;
unsigned char *orig_pass = NULL;
char *cred_pass = NULL;
/* safety check -- must have some salt */
if (BASE64_DECODE_LEN(strlen(cred)) <= sizeof(SHA1digest)) {
return PASSWD_ERR;
}
/* decode base64 password */
cred_pass = (unsigned char *)calloc(1, strlen(cred) + 1);
if(cred_pass == NULL ) return PASSWD_ERR;
memcpy(cred_pass, cred, strlen(cred));
cred_pass[strlen(cred)] = '\n';
cred_pass[strlen(cred)+1] = '\0';
orig_pass = base64_decode(cred_pass, strlen(cred_pass));
rc = strlen(orig_pass);
/* safety check -- must have some salt */
if (rc <= (int)(sizeof(SHA1digest))) {
free(cred_pass);
free(orig_pass);
return PASSWD_ERR;
}
/* hash credentials with salt */
SHA1_Init(&SHA1context);
SHA1_Update(&SHA1context,
(const unsigned char *) passwd, strlen(passwd));
SHA1_Update(&SHA1context,
(const unsigned char *) &orig_pass[sizeof(SHA1digest)],
rc - sizeof(SHA1digest));
SHA1_Final(SHA1digest, &SHA1context);
/* compare */
rc = memcmp((char *)orig_pass, (char *)SHA1digest, sizeof(SHA1digest));
free(cred_pass);
free(orig_pass);
return rc ? PASSWD_ERR : PASSWD_OK;
}
// ./ssha_check shanghai 8Mhh1STpS0WOcp15/hd26yZMbE9uRMN0NQcBEQ==
int main(int argc, char **argv)
{
char *passwd = argv[1];
char *cred = argv[2];
int32_t ret = chk_ssha1(passwd, cred);
printf("ret: %d\n", ret);
return 0;
}
网友评论