How to make a hashed password like the crypt function does? - c++

I want to generate a hashed password manually using openssl API according to the wiki of crypt, but the program result is not same with the result from crypt function, is there something wrong?
int main() {
const char *salt = "123456";
const char *password = "123456";
unsigned char hashedPasswd[SHA512_DIGEST_LENGTH];
SHA512_CTX context;
if (!SHA512_Init(&context)) return -1;
if (!SHA512_Update(&context, (unsigned char *) salt, strlen(salt))) return -1;
if (!SHA512_Update(&context, (unsigned char *) password, strlen(password))) return -1;
if (!SHA512_Final(hashedPasswd, &context)) return -1;
std::string base64Data = base64_encode(hashedPasswd, sizeof(hashedPasswd));
printf("my result: %s\n", base64Data.c_str());
char *hashedPassword = crypt("123456", "$6$123456");
printf("crypt result: %s\n", hashedPassword);
return 0;
}
My Result:
PXeFkSq39sRSVXsSaxLWUUWDt45I8tw9mgcY8GE3B/r3VylOko0q727qPChy+uibqcFuCy6w67ruaQ3AyHHeDg==
Crypt Result:
$6$123456$37mxvJGRzjWxgD3HYl.bKq4aUXrcYV8mk0pxmqg8ARv3t9ke5ZM/NBbwTkx1FDcnLhrOX3jQc6L/NKAohhQJn/
The part of hashed is quite different.

Related

exception error in vio_ssl_write(Vio*, const uchar*, size_t) in openssl

I have a decryption method which decrypts data using private key:
auto decrypt_private(const unsigned char* data,size_t data_len,
unsigned char* decrypted_data)-> int
{
std::string pr_key_name="mykey.pem";
std::string keypass = "pass";
char * keypass_byte= const_cast<char*>( keypass.c_str() );
//open the private key file
FILE *fp = fopen(pr_key_name.c_str(), "r");
RSA *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, keypass_byte);
if(rsa==NULL)
ERR_print_errors_fp(stderr);
fclose(fp);
int rsa_outlen = RSA_private_decrypt(data_len, data, decrypted_data,rsa,
RSA_PKCS1_PADDING);
RSA_free(rsa);
return rsa_outlen;
}
In main I have:
int main(){
std::string encrypted_data;
// encrypted data is in hex encoding
cin>>encrypted_data;
// I know the exact length of decrypted data
unsigned char* decrypted_data = new unsigned char[DATA_SIZE];
unsigned char* encrypted_data_byte= new unsigned char[encrypted_data.length()/2];
int decrypted_data_size= decrypt_private(encrypted_data_byte,
encrypted_data.length()/2, decrypted_data);
// catch error if decryption faild
if(decrypted_data_size==-1){
delete[] decrypted_data;
delete[] encrypted_data_byte;
std::cout<<"decryption faild";
return 1;
}
delete[] decrypted_data;
delete[] encrypted_data_byte;
return 0;
}
but as I add the if condition and the result of the decryption method is -1 I get error from viossl.cc :
../vio/viossl.cc:315: size_t vio_ssl_write(Vio*, const uchar*, size_t): Assertion `ERR_peek_error() == 0' failed.
and throw an exception and the program crashes. Does any body knows the reason? By the way I also removed the if condition and again I get the same error.
Adding ERR_clear_error() solved the problem:
if(decrypted_data_size==-1){
ERR_clear_error();
delete[] decrypted_data;
delete[] encrypted_data_byte;
std::cout<<"decryption faild";
return 1;
}

Decrypt AES in C++ Example

I need some help with decrypt a char array in C++ using AES decrypt with Open SSL library. I already done encryption mode and works fine, but decryption is not working.
This is the Encrypt Function:
string Encrypt(char *Key, char *Msg, int size)
{
static char* Res;
static const char* const lut = "0123456789ABCDEF";
string output;
AES_KEY enc_key;
Res = (char *)malloc(size);
AES_set_encrypt_key((unsigned char *)Key, 128, &enc_key);
for(int vuelta = 0; vuelta <= size; vuelta += 16)
{
AES_ecb_encrypt((unsigned char *)Msg + vuelta, (unsigned char *)Res + vuelta, &enc_key, AES_ENCRYPT);
}
output.reserve(2 * size);
for (size_t i = 0; i < size; ++i)
{
const unsigned char c = Res[i];
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
}
free(Res);
return output;
}
This is the Decrypt Function (not working):
char * Decrypt( char *Key, char *Msg, int size)
{
static char* Res;
AES_KEY dec_key;
Res = ( char * ) malloc( size );
AES_set_decrypt_key(( unsigned char * ) Key, 128, &dec_key);
for(int vuelta= 0; vuelta<=size; vuelta+=16)
{
AES_ecb_encrypt(( unsigned char * ) Msg+vuelta, ( unsigned char * ) Res+vuelta, &dec_key, AES_DECRYPT);
}
return (Res);
}
This is an Example of the Main function that call the methods, the problem is thar no mather how i print the "Res" variable in the Decrypt function, it always show random ASCII values, and i like to show the result in a string like the Encrypt function:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "openSSL/aes.h"
using namespace std;
int main(int argc, char const *argv[])
{
char key[16];
char message[128];
char enc_message[128];
string s_key = "THIS_IS_THE_KEY_";
string s_message = "Hello World !!!";
memset(key, 0, sizeof(key));
strcpy(key, s_key.c_str());
memset(message, 0, sizeof(message));
strcpy(message, s_message.c_str());
string response = Encrypt(key, message, sizeof(message));
cout<<"This is the Encrypted Message: "<<response<<endl;
memset(enc_message, 0, sizeof(enc_message));
strcpy(enc_message, response.c_str());
Decrypt(key, enc_message, sizeof(enc_message));
return 0;
}
Any improve in this methods?
I wanted to put the answer to how I solved it: The problem with my example was that I was trying to use the decrypt function with a HEXADECIMAL STRING and it should be done with an ASCII STRING with the values ​​as delivered by the encryption function.
That is, instead of trying to decrypt a string like this: 461D019896EFA3
It must be decrypted with a string like this: #(%_!#$
After that, the decryption will be delivered in ASCII values. They must be passed to Hexadecimal and finally to a String.
Here is the example that worked for me:
string Decrypt_string(char *Key, string HEX_Message, int size)
{
static const char* const lut = "0123456789ABCDEF";
int i = 0;
char* Res;
AES_KEY dec_key;
string auxString, output, newString;
for(i = 0; i < size; i += 2)
{
string byte = HEX_Message.substr(i, 2);
char chr = (char) (int)strtol(byte.c_str(), NULL, 16);
auxString.push_back(chr);
}
const char *Msg = auxString.c_str();
Res = (char *)malloc(size);
AES_set_decrypt_key((unsigned char *)Key, 128, &dec_key);
for(i = 0; i <= size; i += 16)
{
AES_ecb_encrypt((unsigned char *)Msg + i, (unsigned char *)Res + i, &dec_key, AES_DECRYPT);
}
output.reserve(2 * size);
for (size_t i = 0; i < size; ++i)
{
const unsigned char c = Res[i];
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
}
int len = output.length();
for(int i = 0; i < len; i += 2)
{
string byte = output.substr(i, 2);
char chr = (char) (int)strtol(byte.c_str(), NULL, 16);
newString.push_back(chr);
}
free(Res);
return newString;
}

Base64 encode a XXTEA encrypted string error

I would like to secure my data so I try to encrypt it with XXTEA. I do this way:
inputString -> XXTEA encrypt -> outputString
outputString -> XXTEA decrypt -> inputString
Everything is encrypt and decrypt ok. But when I try to make a base64 encode the output after XXTEA encrypt it and base64 decode it before XXTEA decrypt, the result is wrong:
input -> XXTEA encrypt -> base64 encode -> output
output -> base64 decode -> XXTEA decrypt != input
When I test with http://www.tools4noobs.com/online_tools/xxtea_encrypt/ and http://www.tools4noobs.com/online_tools/xxtea_decrypt/
My example's input string is hello and its final result is bjz/S2f3Xkxr08hu
But when I test with my code (see below), the final result is bjz/Sw==
Here is my encryption code:
std::string ProjectUtils::encrypt_data_xxtea(std::string input, std::string secret) {
//Encrypt with XXTEA
xxtea_long retLength = 0;
unsigned char data[input.length()];
strncpy((char*)data, input.c_str(), sizeof(data));
xxtea_long dataLength = (xxtea_long) sizeof(data);
unsigned char key[secret.length()];
strncpy((char*)key, secret.c_str(), sizeof(key));
xxtea_long keyLength = (xxtea_long) sizeof(key);
unsigned char *encryptedData = xxtea_encrypt(data, dataLength, key, keyLength, &retLength);
//Encode base64
char* out = NULL;
base64Encode(encryptedData, sizeof(encryptedData), &out);
CCLOG("xxtea encrypted data: %s", out);
return out;
}
Here is my decryption code:
char* ProjectUtils::decrypt_data_xxtea(std::string input, std::string secret) {
//Decode base64
unsigned char* output = NULL;
base64Decode((unsigned char*)input.c_str(), (unsigned int)strlen(input.c_str()), &output);
xxtea_long dataLength = (xxtea_long) sizeof(output);
xxtea_long retLength = 0;
unsigned char key[secret.length()];
strncpy((char*)key, secret.c_str(), sizeof(key));
xxtea_long keyLength = (xxtea_long) sizeof(key);
//Decrypt with XXTEA
char *decryptedData = reinterpret_cast<char*>(xxtea_decrypt(output, dataLength, key, keyLength, &retLength));
CCLOG("xxtea decrypted data: %s", decryptedData);
return decryptedData;
}
Do you know what is wrong with my code? Any help would be appreciated!
Thanks very much.
here is full working code on cocos2d-x 3.4
std::string UserProfile::encryptString(std::string input, std::string secret) {
//Encrypt with XXTEA
xxtea_long retLength = 0;
unsigned char data[input.length()];
strncpy((char*)data, input.c_str(), sizeof(data));
xxtea_long dataLength = (xxtea_long) sizeof(data);
unsigned char key[secret.length()];
strncpy((char*)key, secret.c_str(), sizeof(key));
xxtea_long keyLength = (xxtea_long) sizeof(key);
unsigned const char *encryptedData = reinterpret_cast<unsigned const char*>(xxtea_encrypt(data, dataLength, key, keyLength, &retLength));
char* out = NULL;
cocos2d::base64Encode(encryptedData, retLength, &out); // use real length returned by xxtea_encrypt
CCLOG("xxtea encrypted data: [%s][%s]", encryptedData, out);
std::string outStr(out); // make string object
CCLOG("xxtea encrypted data: [%s][%s]", encryptedData, outStr.c_str());
setStr(KEY, outStr); // function that store value in user defaults
std::string revertStr = getStr(KEY); // get string value back
CCLOG("xxtea revertStr: [%s]", revertStr.c_str());
unsigned char* output = NULL;
int outLength = cocos2d::base64Decode((unsigned char*)revertStr.c_str(), (unsigned int)strlen(revertStr.c_str()), &output); // get real length of decoded string
char *decryptedData = reinterpret_cast<char*>(xxtea_decrypt(output, outLength, key, keyLength, &retLength)); // use it
CCLOG("xxtea decrypted data: %s", decryptedData); // string the same as original for me
return "";
}
thanks for your code, it works for me)
I have replaced length of base64 string by actual retLength
base64Encode(encryptedData, retLength, &out);
and back, get actual size as well
int outLength = cocos2d::base64Decode((unsigned char*)revertStr.c_str(), (unsigned int)strlen(revertStr.c_str()), &output);
char *decryptedData = reinterpret_cast<char*>(xxtea_decrypt(output, outLength, key, keyLength, &retLength));

HMAC_Init crashes while calculating HMAC-SHA1

Here is my code:
int function(const char * buffer,size_t len,unsigned char * value)
{
char* user = "username";
char*password = "password";
size_t text_len = strlen(user) + strlen(password) + 2;
unsigned char* key = (unsigned char*)calloc(1,16);
unsigned char* text= (unsigned char *)calloc(1,text_len);
snprintf((char*)text, text_len, "%s:%s",user,password );
MD5(text, text_len-1, key)
HMAC_CTX *ctx = NULL;
unsigned int md_len = 20;
ctx = (HMAC_CTX*) calloc(1,sizeof(HMAC_CTX));
if(ctx == NULL){return -1;}
HMAC_CTX_init(ctx);
`HMAC_Init(ctx, key, 16, EVP_sha1());` //crashing everytime, saying heap corruption
HMAC_Update(ctx, buffer, len);
HMAC_Final(ctx, value, &md_len);
HMAC_CTX_cleanup(ctx);
return 0;
}
I am using openssl 0.9.8.c. If anyone faced this problem please let me know.
According to the man page HMAC_Init is deprecated. Might be worth trying HMAC_Init_ex.

OpenSSL - How to determine the right length of an rsa encrypted string?

I use OpenSSL to encryt a string. After that I want to encode the encrypted string with base64 algorithm also using OpenSSL. So I found the following code snipped: ( bit.ly/adUSEw )
char *base64(const unsigned char *input, int length) {
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
char *buff = (char*)malloc(bptr->length);
memcpy(buff, bptr->data, bptr->length - 1);
buff[bptr->length - 1] = 0;
BIO_free_all(b64);
return buff;
}
int main(int argc, char **argv) {
char *message = "TEST";
char *encryptedString = Encrypt(message);
if (encryptedString == NULL) {
return 0;
}
else {
char *output = base64(encryptedString, strlen(encryptedString));
cout << output << endl;
} }
I noticed that strlen(encryptedString) isn't working properly in this case. Sometimes it returns the right lenght but mostly not. So whats is the proper way to determine the correct lenght?
The size of the encrypted message is exactly the size of the modulus in the private key. You have to get the information from there.
You cannot use strlen because
the buffer with the encrypted message is likely not null-terminated, and
the encrypted message may contain (and will likely contain) null bytes.