update openssl, do not work hmac - c++

there is code
#include <stdio.h>
#include <string.h>
#include <openssl/hmac.h>
int main() {
const char key[] = "012345678";
char data[] = "hello world";
unsigned char* result;
unsigned int len = 20;
result = (unsigned char*)malloc(sizeof(char) * len);
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, strlen(key), EVP_sha1(), NULL);
HMAC_Update(&ctx, (unsigned char*)&data, strlen(data));
HMAC_Final(&ctx, result, &len);
HMAC_CTX_cleanup(&ctx);
printf("HMAC digest: ");
for (int i = 0; i != len; i++)
printf("%02x", (unsigned int)result[i]);
printf("\n");
free(result);
}
output HMAC digest: e19e220122b37b708bfb95aca2577905acabf0c0
I can not update this code for openssl 1.1.0.
The new version changed the syntax hmac.
#include <iostream>
#include <string.h>
#include <openssl/hmac.h>
using namespace std;
int main() {
const char key[] = "012345678";
char data[] = "hello world";
int datalen = strlen(data);
int keylen = strlen(key);
unsigned char* result;
unsigned int len = 20;
result = (unsigned char*)malloc(sizeof(char) * len);
cout << datalen << endl;
cout << keylen << endl;
cout << len << endl;
HMAC_CTX *HMAC_CTX_new();
int HMAC_CTX_reset(HMAC_CTX *ctx);
int HMAC_Init_ex(HMAC_CTX *ctx, const char key, int keylen, const EVP_MD EVP_sha1());
int HMAC_Update(HMAC_CTX * ctx, char &data, int datalen);
int HMAC_Final(HMAC_CTX * ctx, char result, int &len);
int HMAC_CTX_cleanup(HMAC_CTX * ctx);
printf("HMAC digest: ");
for (int i = 0; i != len; i++)
printf("%02x", (unsigned int)result[i]);
printf("\n");
free(result);
return 0;
}
output HMAC digest: 0000000000000000000000000000000000000000
I will be glad of any help

Related

C++ OPENSSL - How to convert OPENSSL output to a readable text and store it to a variable (if possible)

I have the working code below using OPENSSL AES 256 CBC to encrypt/decrypt.
It is working but I am missing something really important that is to CONVERT the Encryption result to readable text and STORE it to a STRING variable if possible (for later use).
For example, I need to see something like this: UkV8ecEWh+b1Dz0ZdwMzFVFieCI5Ps3fxYrfqAoPmOY=
Trying hard to find how to do that and what format OPENSSL is throwing out from Encryption process. (binary format ??) See image attached.
ps. Don't worry about the hashes below. They are not in production.
Thanks in Advance!!
Here is my code so far:
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
using namespace std;
// HEX PRINT
static void hex_print(const void* pv, size_t len)
{
const unsigned char* p = (const unsigned char*)pv;
if (NULL == pv)
printf("NULL");
else
{
size_t i = 0;
for (; i < len; ++i)
printf("%02X ", *p++);
}
printf("\n");
}
// Starting MAIN function
int main()
{
int keylength = 256;
unsigned char aes_key[] = "1Tb2lYkqstqbh9lPAbeWpQOs3seHk6cX";
// Message we want to encrypt
unsigned char aes_input[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890 abcdefghijklmnopqrstuvwxyz";
size_t inputslength = sizeof(aes_input)-1; // -1 because we don't want to encrypt the \0 character
// initialization vector IV - same for Encryption and Decryption
unsigned char iv_enc[] = "JxebB512Gl3brfx4" ;
unsigned char iv_dec[] = "JxebB512Gl3brfx4" ;
// buffers for encryption and decryption
const size_t encslength = inputslength ;
unsigned char enc_out[257];
unsigned char dec_out[257];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
//Encryption START
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, keylength, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv_enc, AES_ENCRYPT);
//Decryption START
AES_set_decrypt_key(aes_key, keylength, &dec_key);
AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv_dec, AES_DECRYPT);
// Printing Results
printf("original: \t");
hex_print(aes_input, sizeof(aes_input));
cout << aes_input << endl;
printf("encrypted: \t");
hex_print(enc_out, sizeof(enc_out));
cout << enc_out << endl;
printf("decrypt: \t");
hex_print(dec_out, sizeof(dec_out));
cout << dec_out << endl;
return 0;
}
Image of the Process
All Right. Thanks for the tips #RemyLebeau and #PaulSanders !!
I could resolve the issue using another tip from here -->
Base64 C++
Working REALLY fine now!!
Thanks Much!!
Here is the code for "encode" and "decode" Base64, just in case someone wants to do the same. Very usefull!!
typedef unsigned char uchar;
static const string b = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static string base64_encode(const string &in) {
string out;
int val=0, valb=-6;
for (uchar c : in) {
val = (val<<8) + c;
valb += 8;
while (valb>=0) {
out.push_back(b[(val>>valb)&0x3F]);
valb-=6;
}
}
if (valb>-6) out.push_back(b[((val<<8)>>(valb+8))&0x3F]);
while (out.size()%4) out.push_back('=');
return out;
}
static string base64_decode(const string &in) {
string out;
vector<int> T(256,-1);
for (int i=0; i<64; i++) T[b[i]] = i;
int val=0, valb=-8;
for (uchar c : in) {
if (T[c] == -1) break;
val = (val<<6) + T[c];
valb += 6;
if (valb>=0) {
out.push_back(char((val>>valb)&0xFF));
valb-=8;
}
}
return out;
}

how to encrypt and decrypt string with openssl?

Trying to encrypt and decrypt strings with evp functions of openssl.
I tried the following source code but I got unexpected results (garbege output).
What I am missing?
#include <stdio.h>
#include <unistd.h>
#if 1
#include <openssl/evp.h>
char *se_evp_encrypt(char *ssid, char *data, int inl, char *ret, int *rb)
{
int i, tmp, ol;
EVP_CIPHER_CTX evpctx;
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
*ret = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_EncryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_EncryptUpdate(&evpctx, ret, &ol, data, inl);
*rb = ol;
EVP_EncryptFinal(&evpctx, ret, &ol);
return ret;
}
char *se_evp_decrypt(char *ssid, char *ct, int inl, char *pt)
{
int ol;
EVP_CIPHER_CTX evpctx;
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
char final[EVP_MAX_BLOCK_LENGTH];
*pt = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_DecryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_DecryptUpdate(&evpctx, pt, &ol, ct, inl);
if (!ol) /* there's no block to decrypt */
{
return "";
}
pt[ol] = 0;
EVP_DecryptFinal(&evpctx, final, &inl);
return pt;
}
int main(int argc, char *argv[])
{
char str[] = "abcdef123456789";
char buf[256] = "", buf2[256] = "";
int i;
se_evp_encrypt("anyssid", str, strlen(str), buf, &i);
printf("Ciphertext is %d bytes. %d\n", i, strlen(str));
se_evp_decrypt("anyssid", buf, i, buf2);
printf("Decrypted: >>%s<<\n", buf2);
}
#endif
fixed the source code in this way
#include <stdio.h>
#include <unistd.h>
#if 1
#include <openssl/evp.h>
char *se_evp_encrypt(char *ssid, char *data, int inl, char *ret, int *rb)
{
int i, tmp, ol;
EVP_CIPHER_CTX evpctx = {0};
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
*ret = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_EncryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_EncryptUpdate(&evpctx, ret, &ol, data, inl);
EVP_EncryptFinal(&evpctx, ret + ol, &tmp);
*rb = ol + tmp;
return ret;
}
char *se_evp_decrypt(char *ssid, char *ct, int inl, char *pt)
{
int ol, tmp;
EVP_CIPHER_CTX evpctx;
char key[EVP_MAX_KEY_LENGTH] = {0};
char iv[EVP_MAX_IV_LENGTH] = {0};
char final[EVP_MAX_BLOCK_LENGTH];
*pt = '\0';
strncpy(key, ssid, EVP_MAX_KEY_LENGTH);
strncpy(iv, ssid, EVP_MAX_IV_LENGTH);
EVP_DecryptInit(&evpctx, EVP_bf_cbc(), key, iv);
EVP_DecryptUpdate(&evpctx, pt, &ol, ct, inl);
EVP_DecryptFinal(&evpctx, pt+ol , &tmp);
pt[ol+tmp] = 0;
return pt;
}
int main(int argc, char *argv[])
{
char str[] = "abcdef123456789";
char buf[256] = "", buf2[256] = "";
int i;
se_evp_encrypt("anyssid", str, strlen(str), buf, &i);
printf("Ciphertext is %d bytes. %d\n", i, strlen(str));
se_evp_decrypt("anyssid", buf, i, buf2);
printf("Decrypted: >>%s<<\n", buf2);
}
#endif

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;
}

openssl hash producing partially different output - c++ ubuntu

Below is my code for creating a hash in openssl.
I was wondering why is my output always partially diffrent.
int main()
{
char alg[] = "MD5";
char buf[EVP_MAX_KEY_LENGTH] = "5";
unsigned char *testKey;
unsigned int olen;
testKey = simple_digest(alg, buf, EVP_MAX_KEY_LENGTH,&olen);
std::cout << "Printing key : >>";
print_hex(testKey,EVP_MAX_KEY_LENGTH);
std::cout << "<<" << std::endl;
}
unsigned char *simple_digest(char *alg, char *buf, unsigned int len,unsigned int *olen)
{
const EVP_MD *m;
EVP_MD_CTX ctx;
unsigned char *ret;
OpenSSL_add_all_digests();
if (!(m = EVP_get_digestbyname(alg)))
return NULL;
if (!(ret = (unsigned char *)malloc(EVP_MAX_MD_SIZE)))
return NULL;
EVP_DigestInit(&ctx, m);
EVP_DigestUpdate(&ctx, buf, len);
EVP_DigestFinal(&ctx, ret, olen);
// std::cout << "computed key" << ret << std::endl;
return ret;
}
void print_hex(unsigned char *bs, unsigned int n)
{
int i;
for (i = 0; i < n; i++)
printf("%02x", bs[i]);
printf("\n");
}
Output :
3afb8ebc9c93bf6d40285736f210b7856af8bab4d040ca090043ca09f840ca09
3afb8ebc9c93bf6d40285736f210b7856af8bab490a5f909c0a7f909b8a5f909
As you can see only the back few characters differ.
Thanks in advance! :D
Update (correct working version) :
int main()
{
char alg[] = "MD5";
char buf[EVP_MAX_KEY_LENGTH] = "5";
unsigned char *testKey;
unsigned int olen;
testKey = simple_digest(alg, buf,strlen(buf),&olen);
std::cout << "Printing key : >>";
print_hex(testKey,olen);
std::cout << "<<" << std::endl;
}
unsigned char *simple_digest(char *alg, char *buf, unsigned int len,unsigned int *olen)
{
const EVP_MD *m;
EVP_MD_CTX ctx;
unsigned char *ret;
OpenSSL_add_all_digests();
if (!(m = EVP_get_digestbyname(alg)))
return NULL;
if (!(ret = (unsigned char *)malloc(EVP_MAX_KEY_LENGTH)))
return NULL;
EVP_DigestInit(&ctx, m);
EVP_DigestUpdate(&ctx, buf, len);
EVP_DigestFinal(&ctx, ret, olen);
return ret;
}
void print_hex(unsigned char *bs, unsigned int n)
{
int i;
for (i = 0; i < n; i++)
printf("%02x", bs[i]);
}
output :
Printing key : >>e4da3b7fbbce2345d7772b0674a318d5<<
You are trying to hash a one-character string, "5", but you are telling EVP_Digest_Update that your buffer length is EVP_MAX_KEY_LENGTH. You need to pass the actual length of your buffer, not the maximum length it could be.
For completeness, here is what your main function should look like:
int main()
{
char alg[] = "MD5";
char buf[EVP_MAX_KEY_LENGTH] = "5";
unsigned char *testKey;
unsigned int olen;
# Pass the true length of but
testKey = simple_digest(alg, buf, strlen(buf), &olen);
std::cout << "Printing key : >>";
# Pass the true length of testKey
print_hex(testKey,olen);
std::cout << "<<" << std::endl;
}
One other caveat: you probably don't want to use EVP_MAX_KEY_LENGTH for your buffer, as that would limit the size of the message you could hash.

How to create a RSA public key from a unsigned char * modulus and exponent 65537(RSA_F4)

I'm trying generate a rsa public key from a modulus type char[], and I now the exponent is RSA_F4(65537);
But when I'm trying generate my public key using this values for "n" and "e", the RSA_public_encrypt, return -1;
Thanks!
My code:
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <crypt.h>
#include <iostream>
#include <stdlib.h>
#include <openssl/rsa.h>
#include <openssl/aes.h>
#include <openssl/opensslconf.h>
#include <openssl/engine.h>
#include <openssl/pem.h>
#include <openssl/rc4.h>
using namespace std;
int main(void)
{
//modulus in format char hex;
char key[] = "C0E7FC730EB5CF85B040EC25DAEF288912641889AD651B3707CFED9FC5A1D3F6C40062AD46E3B3C3E21D4E71CC4800C80226D453242AEB2F86D748B41DDF35FD";
char palavra[] = "teste";
char crip[512];
int ret;
RSA * pubkey = RSA_new();
BIGNUM * modul = BN_new();
BIGNUM * expon = BN_new();
BN_hex2bn(&modul, (const char *) key);
BN_hex2bn(&expon, "010001");
cout << "N KEY: " << BN_bn2hex(modul) << endl;
cout << "E KEY: " << BN_bn2hex(expon) << endl;
pubkey->n = modul;
pubkey->e = expon;
cout << "N PUB KEY: " << BN_bn2hex(pubkey->n) << endl;
cout << "E PUB KEY: " << BN_bn2hex(pubkey->e) << endl;
if (RSA_public_encrypt(strlen((const char *) palavra), (const unsigned char *) palavra, (unsigned char *) crip, pubkey, RSA_PKCS1_PADDING ))
{
printf("ERRO encrypt\n");
}
else
{
printf("SUC encrypt\n");
}
return 0;
}
You probably want something that looks more like:
RSA *pubkey = RSA_new();
int len = BN_hex2bn(&pubkey->n, (const char *)p);
if (len == 0 || p[len])
fprintf(stderr, "'%s' does not appear to be a valid modulus\n", p);
BN_hex2bn(&pubkey->e, "010001");
edit
Your code works fine, except for the error check. RSA_public_encrypt returns the size of the ciphertext on success, not 0, so to make the code above work, add a <= 0 test to if line:
if (RSA_public_encrypt(....) <= 0)
Here is some C code, that does the trick:
#include <string.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
// cheating, .. ignoring deprecation warnings
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
unsigned char *base64_decode(const char* base64data, int* len) {
BIO *b64, *bmem;
size_t length = strlen(base64data);
unsigned char *buffer = (unsigned char *)malloc(length);
b64 = BIO_new(BIO_f_base64());
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
bmem = BIO_new_mem_buf((void*)base64data, length);
bmem = BIO_push(b64, bmem);
*len = BIO_read(bmem, buffer, length);
BIO_free_all(bmem);
return buffer;
}
BIGNUM* bignum_base64_decode(const char* base64bignum) {
BIGNUM* bn = NULL;
int len;
unsigned char* data = base64_decode(base64bignum, &len);
if (len) {
bn = BN_bin2bn(data, len, NULL);
}
free(data);
return bn;
}
EVP_PKEY* RSA_fromBase64(const char* modulus_b64, const char* exp_b64) {
BIGNUM *n = bignum_base64_decode(modulus_b64);
BIGNUM *e = bignum_base64_decode(exp_b64);
if (!n) printf("Invalid encoding for modulus\n");
if (!e) printf("Invalid encoding for public exponent\n");
if (e && n) {
EVP_PKEY* pRsaKey = EVP_PKEY_new();
RSA* rsa = RSA_new();
rsa->e = e;
rsa->n = n;
EVP_PKEY_assign_RSA(pRsaKey, rsa);
return pRsaKey;
} else {
if (n) BN_free(n);
if (e) BN_free(e);
return NULL;
}
}
void assert_syntax(int argc, char** argv) {
if (argc != 4) {
fprintf(stderr, "Description: %s takes a RSA public key modulus and exponent in base64 encoding and produces a public key file in PEM format.\n", argv[0]);
fprintf(stderr, "syntax: %s <modulus_base64> <exp_base64> <output_file>\n", argv[0]);
exit(1);
}
}
int main(int argc, char** argv) {
assert_syntax(argc, argv);
const char* modulus = argv[1];
const char* exp = argv[2];
const char* filename = argv[3];
EVP_PKEY* pkey = RSA_fromBase64(modulus, exp);
if (pkey == NULL) {
fprintf(stderr, "an error occurred :(\n");
return 2;
} else {
printf("success decoded into RSA public key\n");
FILE* file = fopen(filename, "w");
PEM_write_PUBKEY(file, pkey);
fflush(file);
fclose(file);
printf("written to file: %s\n", filename);
}
return 0;
}
See this link for further info: http://www.techper.net/2012/06/01/converting-rsa-public-key-modulus-and-exponent-into-pem-file/