I am trying to use the lib-sodium cryptography library in Visual Studio 2015.
Following is my piece of code
unsigned char pk[crypto_box_PUBLICKEYBYTES];
unsigned char sk[crypto_box_SECRETKEYBYTES];
crypto_box_keypair(pk, sk);
cout << "\nPrivate Key: " << pk;
cout << "\nSecret Key: " << sk;
cout << "\n";
int m_len = 6, c_len = crypto_box_SEALBYTES + m_len;
unsigned char *m=NULL, *c=NULL;
m = (unsigned char *)sodium_malloc(m_len);
c = (unsigned char *)new unsigned char(c_len);
unsigned char *m2=NULL;
m2 = (unsigned char *) new unsigned char(m_len);
//Message to be encrpted
m[0] = 'M';
m[1] = 'C';
m[2] = '2';
m[3] = '2';
m[4] = '5';
m[5] = '\0';
cout << "\nMessage is: " << m;
if (crypto_box_seal(c, m, m_len, pk) != 0) {
cout << "\nFail in cypto";
return 1;
}
cout << "\nCrypted is: " << c;
if (crypto_box_seal_open(m2, c, c_len, pk, sk) != 0) {
printf("crypto_box_seal_open() failure\n");
return 1;
}
cout << "\nDecrypt is: " << m2;
Questions are as follows:
Every time I run the code I get different sizes of public and private key, but the size of variable I use is constant. How can this be possible?
I am trying to use sodium_malloc function to allocate memory for crypted message and decrypted message. But it throws a violation of accessing wrong memory space. Is this a problem because i am coding in C++ or is there any other reason?
Please let me know if you need any other information regarding the problem.
Related
I have 20byte binary char array. I want to divide into 3 parts: 4byte, 8byte, 8byte. I implemented it like the following. It works but seems I might be able to use buffer stream. I want to know how to use it.
Now
void main()
{
// _data is 20byte binary char array. 0000000000000000000000000000000000000000000001111001110001111111001110000010110000001011101101000000000000000000000000000000000000000000000000000000000000000001
// strA (4 byte)
string strA;
for (std::size_t i = 0; i < 4; ++i) {
strA += bitset<8>(_data.c_str()[i]).to_string();
}
cout << strA << endl; // 00000000000000000000000000000000
// strB (8 byte)
string strB;
for (std::size_t i = 4; i < 12; ++i) {
strB += bitset<8>(_data.c_str()[i]).to_string();
}
cout << strB << endl; // 0000000000000111100111000111111100111000001011000000101110110100
// strC (8 byte)
string strC;
for (std::size_t i = 12; i < 20; ++i) {
strC += bitset<8>(_data.c_str()[i]).to_string();
}
cout << strC << endl; // 0000000000000000000000000000000000000000000000000000000000000001
}
Expectation
I want to implement like this.
void main()
{
stringstream ss = _data;
strA = ss.pop(4);
strB = ss.pop(8);
strC = ss.pop(8);
}
Update 1
Thank you guys. I'm trying all of answers you gave me one by one. I'm newbie in c++ so it takes time to understand it. The following is Anders K's one.
struct S { char four[4]; char eight1[8]; char eight2[8]; };
struct S *p = reinterpret_cast<S*>(&_data);
cout << p->four << endl; // => Output "(" I think I can find way to output
Update 2
It works using string::substr. Thanks Zakir.
int main()
{
// I don't know how to change to string value in smart way..
string str;
for (std::size_t i = 0; i < _data.size(); ++i) {
str += bitset<8>(_data.c_str()[i]).to_string();
}
cout << str << endl; // 0000000000000000000000000000000000000000000001111001110001111111001110000010110000001011101101000000000000000000000000000000000000000000000000000000000000000001
std::string d = str; // Your binary stream goes here
int lenA = (4*8); // First 4 Bytes
int lenB = (8*8); // Second 8 Bytes
int lenC = (8*8); // Last 8 Bytes
std::string strA = d.substr(0, lenA);
std::string strB = d.substr(lenA + 1, lenB - 1);
std::string strC = d.substr(lenA + lenB + 1, lenC - 1);
cout << strA << endl; // 00000000000000000000000000000000
cout << strB << endl; // 000000000000111100111000111111100111000001011000000101110110100
cout << strC << endl; // 000000000000000000000000000000000000000000000000000000000000001
}
Update 3
I got an error when I try Scheff's way. This is my fault and I think I can solve it. And I think I should reconsider about _data's type.
int main
{
const char data = _data;
const char *iter = data;
string strA = pop(iter, 4);
string strB = pop(iter, 8);
string strC = pop(iter, 8);
cout << "strA: '" << strA << "'" << endl;
cout << "strB: '" << strB << "'" << endl;
cout << "strC: '" << strC << "'" << endl;
}
Make Error Message
error: no viable conversion from 'string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') to
'const char'
const char data = _data;
It is not possible to make a new method for std::stringstream. (At least, I would not recommend this.)
Instead, I would suggest to make it a function. The usage would be similar.
#include <bitset>
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
string pop(istream &in, size_t n)
{
string ret;
while (n--) {
unsigned char byte = (unsigned char)in.get();
ret += bitset<8>(byte).to_string();
}
return ret;
}
int main()
{
string data(
"\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa"
"\xbb\xcc\xdd\xee\xff\xde\xad\xbe\xef\x00", 20);
istringstream in; in.str(data);
string strA = pop(in, 4);
string strB = pop(in, 8);
string strC = pop(in, 8);
cout << "strA: '" << strA << "'" << endl;
cout << "strB: '" << strB << "'" << endl;
cout << "strC: '" << strC << "'" << endl;
return 0;
}
Output:
strA: '00010001001000100011001101000100'
strB: '0101010101100110011101111000100010011001101010101011101111001100'
strC: '1101110111101110111111111101111010101101101111101110111100000000'
Note:
Using a std::istream makes it applicable to any stream derived from std::istream.
There is no error handling in pop(). Thus, the returned result of pop() might be wrong if the passed stream isn't good() afterwards.
Btw. I agree with the comments that a std::stream might be "over-engineered". Thus, here the "light-weight" version:
#include <bitset>
#include <iostream>
#include <string>
using namespace std;
string pop(const char *&iter, size_t n)
{
string ret;
while (n--) {
ret += bitset<8>((unsigned char)*iter++).to_string();
}
return ret;
}
int main()
{
const char data[] =
"\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa"
"\xbb\xcc\xdd\xee\xff\xde\xad\xbe\xef\x00";
const char *iter = data;
string strA = pop(iter, 4);
string strB = pop(iter, 8);
string strC = pop(iter, 8);
cout << "strA: '" << strA << "'" << endl;
cout << "strB: '" << strB << "'" << endl;
cout << "strC: '" << strC << "'" << endl;
return 0;
}
The output is identical like above.
Note:
The usage of char[] and char* is much more sensitive for out-of-bound access. Thus, it has to be used carefully.
I'm not quite sure whether the (unsigned char) cast is necessary. As I have often seen "funny" effects concerning char, int and sign extension, I guess it cannot hurt. (I feel better with it.)
I can propose you a very simple alternative using string::substr
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string _data="00010001001000100011001101000100\
0101010101100110011101111000100010011001101010101011101111001100\
1101110111101110111111111101111010101101101111101110111100000000";
int lenA = (4*8); //First 4 Bytes
int lenB = (8*8); //Second 8 Bytes
int lenC = (16*8); //Last 16 Bytes
string strA = _data.substr(0, lenA - 1);
string strB = _data.substr(lenA, lenB - 1);
string strC = _data.substr(lenB, lenC - 1);
std::cout << "strA: " << strA << endl;
std::cout << "strB: " << strB << endl;
std::cout << "strC: " << strC << endl;
return 0;
}
This is neat and simple but gets your job done!
Demo here
Output:-
strA: 0001000100100010001100110100010
strB: 010101010110011001110111100010001001100110101010101110111100110
strC: 100110011010101010111011110011001101110111101110111111111101111010101101101111101110111100000000
i'am writing some encryption program in c++, and when i start it then console print only one char, and decryption don't work, when i do encryption / decryption then program not doing that with numeric numbers of nn, he do that with hes adress. sorry for my english.
// Var
std::string text = "string";
const char *nn = text.c_str();
// Encryption
int x = (int(nn));
x = x * 3 - 100 * 2;
cout << "Numerical numbers: " << x << endl;
cout << "String: " << (char(x)) << endl;
// Decryption
x = (x - 100 * 2) / 3;
cout << "Numerical numbers: " << x << endl;
cout << "String: " << (char(x));
I suppose you would like to encrypt every characters of this:
std::string text = "string";
In this case you will need a vector of integers instead of a single int, to store every encoded character:
std::vector<int> encrypted;
Since you know what will be the final size of the vector, you can prepare the vector beforehand to allocate the necessary space, but this is optional:
encrypted.reserve(text.size());
Than you have to go through the characters one by one, encode them and put them to the vector:
for(auto &ch : text) {
int x = ch * 3 - 100 * 2;
encrypted.push_back(x);
}
The resulting vector can be printed this way:
cout << "Numerical numbers: ";
for(auto x : encrypted) { cout << x << ", "; }
cout << endl;
The decryption is analogous:
std::string decrypted;
decrypted.reserve(encrypted.size());
for(auto &x : encrypted) {
char ch = (x + 100 * 2) / 3;
decrypted += ch;
}
Unless you have restrictions that you have to use the formula x * 3 - 100 * 2 for encryption/decryption, I suggest you to use XOR.
#include <iostream>
#include <string>
int main()
{
// Var
std::string text = "string", encrypt, decrypt;
// Encryption
for (int i = 0; i < text.length(); i++)
{
encrypt += text[i] ^ '1';
}
// Decryption
for (int i = 0; i < encrypt.length(); i++)
{
decrypt += encrypt[i] ^ '1';
}
std::cout << "original text: " << text << std::endl << "encrypted text: " << encrypt << std::endl << "decrypted text: " << decrypt;
}
The output of the above code would be:
original text: string
encrypted text: BECX_V
decrypted text: string
Here is an working example of the above code.
I cannot print the values of a character array, even when I pass the array with the address of its first element:
vbv_packet = Packet::create(&username[0],
&password[0], Packet::VBV, Packet::DATA,
bytea_from_memptr(& new_mr, car_multirecord::HEADER_SIZE +
(new_mr.get_count() * sizeof(car_compact_record))));
And in the definition function I try to print the array values like this:
static Packet::ptr create(const char* username, const char* password,RTCINET_COMMANDS cmd, RTCINET_COMMANDS subcmd, Packet::ptr_bytea ba)
// TODO: unsigned short command_seq, data_seq, length
{
//Add user authentication fields, username n password here
std::cout << "********** CREATING PACKET";
std::cout << "sizeof username: " << strlen(username);
std::cout << "sizeof password: " << strlen(password);
for(int i = 0; i < strlen(username); i++)
{
std::cout << *(username + sizeof(char) * i);
}
std::cout << "\n";
for(int j = 0; j < strlen(password); j++)
{
std::cout << password[j];
}
needless to say, the two string are defined as:
const char username[] = "ARG-CO";
const char password[] = "xxxxx!";
where am I doing wrong?
vbv_packet = Packet::create(username,
password, Packet::VBV, Packet::DATA,
bytea_from_memptr(& new_mr, car_multirecord::HEADER_SIZE +
(new_mr.get_count() * sizeof(car_compact_record))));
Should be correct, what are you trying to achieve here:
for(int i = 0; i < strlen(username); i++)
{
std::cout << *(username + sizeof(char) * i);
}
Why are you doing this *(username + sizeof(char) * i), If you wanna print every character in this char array use it like this : username[i]
Is it printing the password correctly?
I'm currently trying to convert an integer into a char* in order to send it over a socket. In the receiving method I logically try to treat the char* as an integer again, but I seem to be missing something because I can't get it right.
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int num1 = 42; // Works
int num2 = 100; // Works
int num3 = 126; // Works
int num4 = 517; // Doesn't seem to work for int > 127
char p1[sizeof(int)];
*p1 = num1;
char p2[sizeof(int)];
*p2 = num2;
char p3[sizeof(int)];
*p3 = num3;
char p4[sizeof(int)];
*p4 = num4;
void* pA = p4;
void* pB = &num4;
int result1 = static_cast<int>(*p1);
int result2 = static_cast<int>(*p2);
int result3 = static_cast<int>(*p3);
int result4 = static_cast<int>(*p4);
int resultV1 = *static_cast<int*>(pA);
int resultV2 = *reinterpret_cast<int*>(p3);
unsigned int resultV3 = static_cast<int>(*p4);
int resultV4 = *static_cast<int*>(pB); // Works, but I need to convert a char* into an int, not a void* into an int
cout << "R1: " << result1 << endl;
cout << "Expected: " << num1 << endl << endl;
cout << "R2: " << result2 << endl;
cout << "Expected: " << num2 << endl << endl;
cout << "R3: " << result3 << endl;
cout << "Expected: " << num3 << endl << endl;
cout << "R4: " << result4 << endl;
cout << "Expected: " << num4 << endl << endl;
cout << "RV1: " << resultV1 << endl;
cout << "Expected: " << num4 << endl << endl;
cout << "RV2: " << resultV2 << endl;
cout << "Expected: " << num4 << endl << endl;
cout << "RV3: " << resultV3 << endl;
cout << "Expected: " << num4 << endl << endl;
cout << "RV4: " << resultV4 << endl;
cout << "Expected: " << num4 << endl << endl;
getchar();
return 0;
}
I have absolutely no idea how to solve this problem at this point. I tried several other ways, but none of them seemed to work correctly yet. It is essential that the integer is converted into a char* first as the recv() method in the WinSock-API stores its read bytes in a buffer char-array.
Any explanations or solutions? Thanks in advance.
If you don't want to use C-style pointers, perhaps you can try this.
void int2CharArr(int num, char* p1){
p1[0] = num & 0xFF;
p1[1] = (num >> 8) & 0xFF;
p1[2] = (num >> 16) & 0xFF;
p1[3] = (num >> 24) & 0xFF;
}
int charArr2Int(char* p1){
return (p1[3] << 24) + (p1[2] << 16) + (p1[1] << 8) + p1[0];
}
void test(){
int a = 0x12345678;
char q[sizeof(int)];
int2CharArr(a, q);
int b = charArr2Int(q);
printf("%x , %x , %x , %x\n", *q, *(q+1), *(q+2), *(q+3));
printf("%x\n", b);
}
Sorry for my primitive syntax. Have no really good and full explanation, wait for some, but this works.
char p1[sizeof(int)];
*((int *) p1) = num1;
char p2[sizeof(int)];
*((int *) p2) = num2;
char p3[sizeof(int)];
*((int *) p3) = num3;
char p4[sizeof(int)];
*((int *) p4) = num4;
void* pA = p4;
void* pB = &num4;
int result1 = *((int *)p1);
int result2 = *((int *)p2);
int result3 = *((int *)p3);
int result4 = *((int *)p4);
You could do it like this:
//to a char*
char *P2 = static_cast<char *>((void*)Tst);
//from a char *
int *S1 = static_cast<int *>((void *)P2);
However, if you are sending the same number of ints each time you send, you may want to consider sending blocks of data instead, like so:
int Data[4] ={42,100,126,517};
char *C1 = static_cast<char*>((void*)Data);
send(socket,C1, sizeof(int[4]),NULL);
and to receive:
char * Buff = new char[16];
recv(socket, buff, sizeof(int[4]), 0);
int Data = static_cast((void)buff);
int R1 = Data[0];
int R2 = Data[1];
int R3 = Data[2];
int R4 = Data[3];
or if you are sending mixed data, but the format is the same for each transmission, use structs, like so:
struct dataBlock
{
char ID[20];
int R1;
int R2;
int R3;
int R4;
};
...
dataBlock Data = {"test\0", 57,100,127,156};
char *Buff = static_cast<char*>((void*)&Data);
send(socket, Buff, sizeof(dataBlock), 0);
and then to receive:
char *Buff = new char[sizeof(dataBlock)];
recv(socket, Buff, sizeof(dataBlock),0);
dataBlock * Data = static_cast<dataBlock*>((void*)Buff);
any suggestion on how to strip characters from char array pass as pointer in C++. i must use memcpy function to copy.
void foo(char *test)
{
char a[1] = {0};
char b[1] = {0};
char c[1]= {0};
memcpy(&a,&test[0],1);
memcpy(&b,&test[1],1);
memcpy(&c,&test[2],1);
cout << a <<endl;
cout << b <<endl;
cout << c <<endl;
}
int main()
{
char uibuffer[4] = "ABC";
foo(uibuffer);
return 0;
}
the current output is:
ABC��
BC��
C��
desired output is:
A
B
C
void foo(char *test)
{
/* Please note, you need to add one extra byte here for a terminator */
char a[2] = {0};
char b[2] = {0};
char c[2]= {0};
memcpy(&a,&test[0],1);
memcpy(&b,&test[1],1);
memcpy(&c,&test[2],1);
cout << a <<endl;
cout << b <<endl;
cout << c <<endl;
}
int main()
{
char uibuffer[4] = "ABC";
foo(uibuffer);
return 0;
}
OR
Think about improving your code by getting rid of arrays and memory copying. Simple char a = buffer[x] will do the trick.
since you haven't created \0 terminated strings do:
cout << a[0] <<endl;
cout << b[0] <<endl;
cout << c[0] <<endl;
Don't make a, b and c an array. Probably won't compile but to illustrate.
void foo(char *test)
{
char a = 0;
char b = 0;
char c = 0;
memcpy(&a,&test[0],1);
memcpy(&b,&test[1],1);
memcpy(&c,&test[2],1);
cout << a <<endl;
cout << b <<endl;
cout << c <<endl;
}
int main()
{
char uibuffer[4] = "ABC";
foo(uibuffer);
return 0;
}
Don't make them arrays:
char a = test[0];
char b = test[1];
char c = test[2];
You can still use memcpy, if you must, just as you are now.