I have this function that in the first call, is giving me back the Correct Encrypted Value
120692dbcdca656394fc10147e2418f2
But all that comes after are incorrect :
764e1a39b43c42f30da2e9e327d4ed22
b93b46dbc936ae3b06f571ffe1a59cac
b93b46dbc936ae3b06f571ffe1a59cac
a71787b35326e282f8c1bf3a0a034620
I'm new with C++ and I think it is a matter of initialization of one of the variables.
I did many Tests but I'm not able to point out where is the Error.
Could someone help me please ?
Thank You -
#include <openssl/aes.h>
#include <iostream>
#include <iomanip>
using namespace std;
char* pxEnAndDeCrypt(char* pStr )
{
static const unsigned char key[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
char *ptr = NULL;
unsigned char enc_out[80]= {};
unsigned char dec_out[80]= {};
int i,j,lenHexa ;
char enc_out_HEXA[200]= {};
unsigned char enc_out_TRANSF[200]= {};
unsigned char enc_out_BACK[200]= {};
AES_KEY enc_key, dec_key;
// ENCRYPT : Input =*pStr Output = enc_out
AES_set_encrypt_key(key, 128, &enc_key);
AES_encrypt((const unsigned char *)pStr, enc_out, &enc_key);
// TRANSFORM OUTPUT OF ENCRYPT TO HEXA : Input =enc_out Output = enc_out_HEXA
int len = strlen((char*)enc_out);
for (i = 0, j = 0; i < len; ++i, j += 2)
{
sprintf(enc_out_HEXA + j, "%02x", enc_out[i] & 0xff);
}
ptr = (char *) enc_out_HEXA;
// OUTPUT
return ptr;
}
The problem with your code is that your function returns a pointer to enc_out_HEXA.
ptr = (char *) enc_out_HEXA;
return ptr;
The issue here is that enc_out_HEXA is declared inside pxEnAndDeCrypt so it no longer exists once you have exitted pxEnAndDeCrypt, so your function is returning a pointer to an object which no longer exists. This results in the strange behaviour you see.
Since you are programming C++, the simple solution is to use C++ (your current code is pure C). Instead of returning a pointer, return a std::string.
#include <string>
std::string pxEnAndDeCrypt(char* pStr )
{
...
return ptr;
}
There are many other places in the above code where you could replace the C code with C++. But this simple change should be enough to get over the current problem.
Of course you will also have to change the code that calls pxEnAndDeCrypt, but since you didn't post that I can't really help with that.
EDIT
Here's an alternative solution that doesn't require std::string.
The basic problem is that enc_out_HEXA has been declared inside the pxEnAndDeCrypt function and so you can't use it (or a pointer to it) outside the function. So one solution is to move the enc_out_HEXA to the calling function and pass a pointer to that array to the function. Like this
void pxEnAndDeCrypt(char* pStr, char* result)
{
...
for (i = 0, j = 0; i < len; ++i, j += 2)
{
sprintf(result + j, "%02x", enc_out[i] & 0xff);
}
}
Then somewhere else in your code you will have
char enc_out_HEXA[200];
pxEnAndDeCrypt(some_string, enc_out_HEXA);
That's the solution that would be used in a C program.
Related
int computeHMACSHA1Hash(const char * unhashedcstr, char * hashedcstr, const char * key, int returncode)
{
string hashed;
size_t unhashlength = strlen(unhashedcstr);
char * nonconstunhashcstr = new char[unhashlength];
strcpy_s(nonconstunhashcstr, unhashlength + 1, unhashedcstr);
unsigned char* pixels = reinterpret_cast<unsigned char*>(nonconstunhashcstr);
returncode = 0;
HMAC_CTX* context = HMAC_CTX_new();
size_t unhashedstrlength = sizeof(unhashedcstr);
if (context != NULL)
{
if (HMAC_Init_ex(context, key, strlen(key), EVP_sha1(), NULL))
{
if (HMAC_Update(context, pixels, unhashedstrlength))
{
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int lengthOfHash = 0;
if (HMAC_Final(context, hash, &lengthOfHash))
{
std::stringstream ss;
for (unsigned int i = 0; i < lengthOfHash; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
}
hashed = ss.str();
size_t outputSize = hashed.length() + 1; // +1 for null terminator
strcpy_s(hashedcstr, outputSize, hashed.c_str());
returncode = 0;
}
else
{
returncode = 7;
}
}
else
{
returncode = 6;
}
}
else
{
returncode = 5;
}
HMAC_CTX_free(context);
}
else
{
returncode = 4;
}
return returncode;
}
int main()
{
const char * unhashedcstr = "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={\"invoiceCode\": \"11111\",\"invoiceNo\": \"2222\",\"inTaxAmount\": \"\",\"exTaxAmount\": \"\"}";
char * hashedcstr = new char[100];
int returncode = 0;
const char * key = "SD886A11B0EE428F";
int result = computeHMACSHA1Hash(unhashedcstr, hashedcstr, key, returncode);
return 0;
}
I tried the code above to calculating the HMAC SHA1 hash value for a content, but compared the results on https://www.freeformatter.com/hmac-generator.html#before-output
it looks like I didn't do it right. I'm not sure what I have done wrong though. Any help would be appreciated.
It turned out the result was "d916b4c2d277319bbf18076c158f0cbcf6c3bc57", while on the website https://www.freeformatter.com/hmac-generator.html#before-output, the result was "71482b292f2b2a47b3eca6dad5e7350566d60963". Even when I tried using the string "a=services&l=v1&p=open&k=SD58292829&i=20200918125249803&n=2124&t=1600404769&f={"invoiceCode": "11111","invoiceNo": "2222","inTaxAmount": "","exTaxAmount": ""}" which removed the escape characters, the result was "09be98b6129c149e685ed57a1d19651a602cda0d". It didn't match the correct one.
Is there anything wrong with my code?
Your hash is calculated over the bytes a=se, which are the first four bytes of the whole input string. Thus, you get d916b4c2d277319bbf18076c158f0cbcf6c3bc57 instead of the 09be98b6129c149e685ed57a1d19651a602cda0d that would correspond to the whole string.
The reason is this:
size_t unhashedstrlength = sizeof(unhashedcstr);
Here, sizeof(unhashedcstr) is the size of the unhashedcstr pointer itself (which is of type const char*), not the size of the null-terminated C-style string this unhashedcstr pointer is pointing to. You are compiling a 32-bit program, so the size of a pointer is 4 bytes. Thus, unhashedstrlength is 4.
To get the length of the C-style string, you can do this instead:
size_t unhashedstrlength = strlen(unhashedcstr);
But just as a comment, in modern C++, you should avoid using raw pointers (such as const char*, char*, unsigned char*), C functions (like strlen(), strcpy_s()) and manual memory management (new / delete and new[] / delete[]). You should prefer to use std::string and/or std::vector<unsigned char> instead, wherever possible. When you need to pass a buffer's address to an API function, you can use std::string::data(), std::vector::data(), or more generally, std::data().
By the way, you currently leak memory: you dynamically allocate buffers using new[], but you never deallocate those (using delete[]). So that memory is released by the OS only after the program exits. This is called a memory leak.
I am trying to convert some C++ code to C for my compiler that can't run with C++ code. I'd like to create the template below to C. This template converts the decimal integer to hexadecimal, and adds 0 in front of value if the size of the hexadecimal string is smaller than (sizeof(T)*2). Data type T can be unsigned char, char, short, unsigned short, int, unsigned int, long long, and unsigned long long.
template< typename T > std::string hexify(T i)
{
std::stringbuf buf;
std::ostream os(&buf);
os << std::setfill('0') << std::setw(sizeof(T) * 2)
<< std::hex << i;
std::cout<<"sizeof(T) * 2 = "<<sizeof(T) * 2<<" buf.str() = "<<buf.str()<<" buf.str.c_str() = "<<buf.str().c_str()<<std::endl;
return buf.str().c_str();
}
Thank you for tour help.
Edit 1: I have tried to use the declaration
char * hexify (void data, size_t data_size)
but when I call with the int value int_value:
char * result = hexify(int_value, sizeof(int))
it doesn't work because of:
noncompetitive type (void and int).
So in this case, do I have to use a macro? I haven't tried with macro because it's complicated.
C does not have templates. One solution is to pass the maximum width integer supported (uintmax_t, in Value below) and the size of the original integer (in Size). One routine can use the size to determine the number of digits to print. Another complication is C does not provide C++’s std::string with is automatic memory management. A typical way to handle this in C is for the called function to allocate a buffer and return it to the caller, who is responsible for freeing it when done.
The code below shows a hexify function that does this, and it also shows a Hexify macro that takes a single parameter and passes both its size and its value to the hexify function.
Note that, in C, character constants such as 'A' have type int, not char, so some care is needed in providing the desired size. The code below includes an example for that.
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
char *hexify(size_t Size, uintmax_t Value)
{
// Allocate space for "0x", 2*Size digits, and a null character.
size_t BufferSize = 2 + 2*Size + 1;
char *Buffer = malloc(BufferSize);
// Ensure a buffer was allocated.
if (!Buffer)
{
fprintf(stderr,
"Error, unable to allocate buffer of %zu bytes in %s.\n",
BufferSize, __func__);
exit(EXIT_FAILURE);
}
// Format the value as "0x" followed by 2*Size hexadecimal digits.
snprintf(Buffer, BufferSize, "0x%0*" PRIxMAX, (int) (2*Size), Value);
return Buffer;
}
/* Provide a macro that passes both the size and the value of its parameter
to the hexify function.
*/
#define Hexify(x) (hexify(sizeof (x), (x)))
int main(void)
{
char *Buffer;
/* Show two examples of using the hexify function with different integer
types. (The examples assume ASCII.)
*/
char x = 'A';
Buffer = hexify(sizeof x, x);
printf("Character '%c' = %s.\n", x, Buffer); // Prints "0x41".
free(Buffer);
int i = 123;
Buffer = hexify(sizeof i, i);
printf("Integer %d = %s.\n", i, Buffer); // Prints "0x00007b".
free(Buffer);
/* Show examples of using the Hexify macro, demonstrating that 'A' is an
int value, not a char value, so it would need to be cast if a char is
desired.
*/
Buffer = Hexify('A');
printf("Character '%c' = %s.\n", 'A', Buffer); // Prints "0x00000041".
free(Buffer);
Buffer = Hexify((char) 'A');
printf("Character '%c' = %s.\n", 'A', Buffer); // Prints "0x41".
free(Buffer);
}
You don't need templates if you step down to raw bits and bytes.
If performance is important, it is also best to roll out the conversion routine by hand, since the string handling functions in C and C++ come with lots of slow overhead. The somewhat well-optimized version would look something like this:
char* hexify_data (char*restrict dst, const char*restrict src, size_t size)
{
const char NIBBLE_LOOKUP[0xF+1] = "0123456789ABCDEF";
char* d = dst;
for(size_t i=0; i<size; i++)
{
size_t byte = size - i - 1; // assuming little endian
*d = NIBBLE_LOOKUP[ (src[byte]&0xF0u)>>4 ];
d++;
*d = NIBBLE_LOOKUP[ (src[byte]&0x0Fu)>>0 ];
d++;
}
*d = '\0';
return dst;
}
This breaks down any passed type byte-by-byte, using a character type. Which is fine, when using character types specifically. It also uses caller allocation for maximum performance. (It can also be made endianess-independent with an extra check per loop.)
We can make the call a bit more convenient with a wrapper macro:
#define hexify(buf, var) hexify_data(buf, (char*)&var, sizeof(var))
Full example:
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#define hexify(buf, var) hexify_data(buf, (char*)&var, sizeof(var))
char* hexify_data (char*restrict dst, const char*restrict src, size_t size)
{
const char NIBBLE_LOOKUP[0xF+1] = "0123456789ABCDEF";
char* d = dst;
for(size_t i=0; i<size; i++)
{
size_t byte = size - i - 1; // assuming little endian
*d = NIBBLE_LOOKUP[ (src[byte]&0xF0u)>>4 ];
d++;
*d = NIBBLE_LOOKUP[ (src[byte]&0x0Fu)>>0 ];
d++;
}
*d = '\0';
return dst;
}
int main (void)
{
char buf[50];
int32_t i32a = 0xABCD;
puts(hexify(buf, i32a));
int32_t i32b = 0xAAAABBBB;
puts(hexify(buf, i32b));
char c = 5;
puts(hexify(buf, c));
uint8_t u8 = 100;
puts(hexify(buf, u8));
}
Output:
0000ABCD
AAAABBBB
05
64
an optional solution is to use format string like printf
note that you can't return pointer to local variable, but you can get the buffer as argument, (here it is without boundaries check).
char* hexify(char* result, const char* format, void* arg)
{
int size = 0;
if(0 == strcmp(format,"%d") || 0 == strcmp(format,"%u"))
{
size=4;
sprintf(result,"%08x",arg);
}
else if(0 == strcmp(format,"%hd") || 0 == strcmp(format,"%hu"))
{
size=2;
sprintf(result,"%04x",arg);
}
else if(0 == strcmp(format,"%hhd")|| 0 == strcmp(format,"%hhu"))
{
size=1;
sprintf(result,"%02x",arg);
}
else if(0 == strcmp(format,"%lld") || 0 == strcmp(format,"%llu") )
{
size=8;
sprintf(result,"%016x",arg);
}
//printf("size=%d", size);
return result;
}
int main()
{
char result[256];
printf("%s", hexify(result,"%hhu", 1));
return 0;
}
I have this code, but is impossible to compile with g++ or msvc. I am trying to make a custom type CharNw that I can use it as string, in existing all string routines or pass as argument all existing functions:
#include <string.h>
#include <stdio.h>
void fx(unsigned int x)
{
/*this is the reason of all this
but is ok, not is problem here */
.....
}
class CharNw
{
int wt;
char cr;
public:
CharNw() { wt = -1; cr = '\0'; }
CharNw( char c) { if wt > 0 fx( (unsigned int) wt); cr = c; }
operator char () { if wt > 0 fx( (unsigned int) wt); return cr ;}
assgn( int f) { wt = f;}
};
int main(void)
{
CharNw hs[40]; //it is ok
CharNw tf[] = "This is not working, Why?\n";
char dst[40];
strcpy(dst, tf); //impossible to compile
printf("dst = %s, tf = %s", dst, tf); //too
return 0;
}
Can help me?
Line by line.
CharNw hs[40]; //it is ok
The above is an array of CharNw objects with a capacity of 40 elements. This is good.
CharNw tf[] = "This is not working, Why?\n";
On the right hand side (RHS) of the assignment, you have a type char const * const* and on the left you have an array ofCharNw. TheCharNw` is not a character, so you have a problem here. Prefer to have both sides of an assignment to have the same type.
char dst[40];
An array of characters. Nothing more, nothing less. It has a capacity of 40 characters. The dst array is not a string. You should prefer to use #define for your array capacities.
strcpy(dst, tf); //impossible to compile
The strcpy requires both parameters to be pointers to char. The left parameter can be decomposed to a pointer to the first char of the array. The tf is an array of CharNw which is not compatible with an array of char nor a pointer to char.
printf("dst = %s, tf = %s", dst, tf); //too
The printf format specifier %s requires a pointer to a character, preferably a C-Style, nul terminated array (or sequence) of characters. The tf parameter is an array of CharNw which is not an array of characters nor a pointer to a single character or a C-Style string.
Edit 1: Conversion Operators
The method operator char () in your class converts a character variable to a CharNw variable. It does not apply to pointers nor arrays.
You would need some messy pointer conversion functions.
Here is an examples:
const unsigned int ARRAY_CAPACITY = 40U;
const char text[] = "I am Sam. Sam I am."
CharNw tf[ARRAY_CAPACITY];
for (unsigned int i = 0U; i < sizeof(text); ++i)
{
tf[i] = text[i]; // OK, Converts via constructor.
}
for (unsigned int i = 0U; i < sizeof(text); ++i)
{
printf("%c", tf[i]); // The tf[i] should use the operator char () method.
}
A better approach is to declare a class using std::basic_string, rather than trying to squeeze your class into the C-Style string functions.
For example:
class StringNw : public std::basic_string<CharNw>
{
};
tl;dr
Why do I get different output every time I run this code (Ideone):
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
const char* _user = "FOO";
const char* _password = "BAR";
char login[21];
sprintf(login,
"\x15\x00\x01%-8s%-10s",
_user,
_password);
for (int i = 0; i < 21; i++) {
printf(" %02x", login[i] & 0xff);
}
return 0;
}
But not this code (Ideone):
#include <iostream>
#include <stdio.h>
using namespace std;
int main() {
const char* _user = "FOO";
const char* _password = "BAR";
const char* _session = "ABCDEFGHIJ";
int _expectedSeq = 123;
char login[38];
sprintf(login,
"L%-6s%-10s%10s%10d\xA",
_user,
_password,
_session,
_expectedSeq);
for (int i = 0; i < 38; i++) {
printf(" %02x", login[i] & 0xff);
}
return 0;
}
Question
Deep in our application code, I came across this:
char login[38];
sprintf(login,
"L%-6s%-10s%10s%10d\xA",
_user,
_password,
_session,
_expectedSeq);
Now, I need to write a (simpler) variant of this code:
char login[21];
sprintf(login,
"\x15\x00\x01%-8s%-10s",
_user,
_password);
Somehow, this doesn't work! What's weird is that the latter produces different results every time.
Thoughts
The former example only has a hex literal at the end. Is this masking the issue in the former's case?
Or, am I actually messing up my debug output, printf? (By the way, I got the & 0xff thing from Printing hexadecimal characters in C.)
Could it have something to do with using char instead of unsigned char? But then, why does the former case work?
The problem is that your string literal has an embedded NUL byte, and that marks the end of the string as far as sprintf is concerned. So your call is identical to:
sprintf(login,
"\x15",
_user,
_password);
And that writes into the login array only two bytes: 0x15 0x00.
There are several approaches to solve this mixing of bytes and characters. My choice would be something along the lines of:
memcpy(login, "\x15\x00\x01", 3);
sprintf(login + 3,
"%-8s%-10s",
_user,
_password);
The call to memcpy takes as parameter the number of bytes, so it is immune to the embedded NUL problem.
But note that sprintf automaticall adds a NUL byte at the end of the output string, so you actually need 22 bytes: 3 + 8 + 10 + 1 = 22:
char login[22];
Your issue is that second format string contains a null character (\x00) which terminates it prematurely. Change the string to use %c instead and have a null character printed there.
So I am working on a tool that dereferences the values of some addresses, it is in both C and C++, and although I am not familiar with C++ I figured out I can maybe take advantage of the string type offered by C++.
What I have is this:
unsigned char contents_address = 0;
unsigned char * address = (unsigned char *) add.addr;
int i;
for(i = 0; i < bytesize; i++){ //bytesize can be anything from 1 to whatever
if(add.num == 3){
contents_address = *(address + i);
//printf("%02x ", contents_address);
}
}
As you can see what I am trying to do is dereference the unsigned char pointer. What I want to do is have a string variable and concatenate all of the dereferenced values into it and by the end instead of having to go through a for case for getting each one of the elements (by having an array of characters or by just going through the pointers) to have a string variable with everything inside.
NOTE: I need to do this because the string variable is going to a MySQL database and it would be a pain to insert an array into a table...
Try this that I borrowed from this link:
http://www.corsix.org/content/algorithmic-stdstring-creation
#include <sstream>
#include <iomanip>
std::string hexifyChar(int c)
{
std::stringstream ss;
ss << std::hex << std::setw(2) << std::setfill('0') << c;
return ss.str();
}
std::string hexify(const char* base, size_t len)
{
std::stringstream ss;
for(size_t i = 0; i < len; ++i)
ss << hexifyChar(base[i]);
return ss.str();
}
I didn't quite understand what you want to do here (why do you assign a dereferenced value to a variable called ..._address)?.
But maybe what you're looking for is a stringstream.
Here's a relatively efficient version that performs only one allocation and no additional function calls:
#include <string>
std::string hexify(unsigned char buf, unsigned int len)
{
std::string result;
result.reserve(2 * len);
static char const alphabet[] = "0123456789ABCDEF";
for (unsigned int i = 0; i != len)
{
result.push_back(alphabet[buf[i] / 16]);
result.push_back(alphabet[buf[i] % 16]);
{
return result;
}
This should be rather more efficient than using iostreams. You can also modify this trivially to write into a given output buffer, if you prefer a C version which leaves allocation to the consumer.