I have string of hexadecimals which I need to convert to const byte*. I am using Crypto++ to do hashing and it needs the key to be in const byte* Is there any way i can convert the string of hexadecimal into const byte* using any of the Crypto++ libs or must i need to come up with my own?
There is a HexDecoder class in Crypto++.
You need to feed this characters. It seems that Crypto++ does not directly distinguish between characters and bytes. So the following line of code supplied by varren will work:
string destination;
StringSource ss(source, true, new HexDecoder(new StringSink(destination)));
const byte* result = (const byte*) destination.data();
I have string of hexadecimals which I need to convert to const byte*
...
But it will be in string. I need it to be in byte*
You should use a HexDecoder and ArraySink then. Something like:
string encoded = "FFEEDDCCBBAA99887766554433221100";
ASSERT(encoded.length() % 2 == 0);
size_t length = encoded.length() / 2;
unique_ptr<byte[]> decoded(new byte[length]);
StringSource ss(encoded, true /*pumpAll*/, new ArraySink(decoded.get(), length));
You can then use the byte array decoded.get() as a byte*.
You can also use a vector<byte>. In this case, the byte* is &v[0]. Something like:
string encoded = "FFEEDDCCBBAA99887766554433221100";
ASSERT(encoded.length() % 2 == 0);
size_t length = encoded.length() / 2;
vector<byte> decoded;
decoded.resize(length);
StringSource ss(encoded, true /*pumpAll*/, new ArraySink(&decoded[0], length));
(comment) But it will be in string. I need it to be in byte*
This is even easier:
string encoded = "FFEEDDCCBBAA99887766554433221100";
string decoded;
StringSource ss(encoded, true /*pumpAll*/, new StringSink(decoded));
const byte* data = reinterpret_cast<const byte*>(decoded.data());
If you want the non-const version then use:
byte* ptr = reinterpret_cast<byte*>(&decoded[0]);
// HEX to BIN using CryptoPP
string encoded = "FFEEDDCCBBAA99887766554433221100";
size_t length = encoded.length() / 2;
vector<byte> decoded;
decoded.resize(length);
StringSource ss(encoded, true, new HexDecoder(new ArraySink(&decoded[0], length)));
Related
I'm writing a recovery app that pulls passwords from Chrome. It has a GUI, so I've used their SQLite wrapper, which uses both SQLConnection and SQLQuery. Here's a snip of my code:
//Create our blob stream
TStream *Stream2 = SQLQuery1->CreateBlobStream(SQLQuery1->FieldByName("password_value"), bmRead);
//Get our blob size
int size = Stream2->Size;
//Create our buffer
char* pbDataInput = new char[size+1];
//Adding null terminator to buffer
memset(pbDataInput, 0x00, sizeof(char)*(size+1));
//Write to our buffer
Stream2->ReadBuffer(pbDataInput, size);
DWORD cbDataInput = size;
DataOut.pbData = pbDataInput;
DataOut.cbData = cbDataInput;
LPWSTR pDescrOut = NULL;
//Decrypt password
CryptUnprotectData( &DataOut,
&pDescrOut,
NULL,
NULL,
NULL,
0,
&DataVerify);
//Output password
UnicodeString password = (UnicodeString)(char*)DataVerify.pbData;
passwordgrid->Cells[2][i] = password;
The output data looks fine, except it behaves as if something went wrong with my null terminator. Here's what output looks like on every line:
I've Read
Windows doc for CryptUnprotectData:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa382377.aspx
Embarcadero documentation for CreateBlobStream:
http://docwiki.embarcadero.com/Libraries/en/Data.DB.TDataSet.CreateBlobStream
memset:
http://www.cplusplus.com/reference/cstring/memset/
Your reading and decrypting calls operate on raw bytes only, they know nothing about strings, and don't care about them. The null-terminator you are adding to pbDataInput is never used, so get rid of it:
//Get our blob size
int size = Stream2->Size;
//Create our buffer
char* pbDataInput = new char[size];
//Write to our buffer
Stream2->ReadBuffer(pbDataInput, size);
DWORD cbDataInput = size;
...
delete[] pbDataInput;
delete Stream2;
Now, when assigning pbData to password, you are casting pbData to char*, so the UnicodeString constructor interprets the data as a null-terminated ANSI string and will convert it to UTF-16 using the system default ANSI codepage, which is potentially a lossy conversion for non-ASCII characters. Is that what you really want?
If so, and if the decrypted data is not actually null-terminated, you have to specify the number of characters to the UnicodeString constructor:
UnicodeString password( (char*)DataVerify.pbData, DataVerify.cbData );
On the other hand, if the decrypted output is already in UTF-16, you need to cast pbData to wchar_t* instead:
UnicodeString password = (wchar_t*)DataVerify.pbData;
Or, if not null-terminated:
UnicodeString password( (wchar_t*)DataVerify.pbData, DataVerify.cbData / sizeof(wchar_t) );
I use Crypto++ library. I have a base64 string saved as CString. I want to convert my string to Integer. actually this base64 built from an Integer and now i want to convert to Integer again.but two Integer not equal.in the other words second Integer not equal with original Integer.
Base64Decoder bd;
CT2CA s(c);
std::string strStd(s);
bd.Put((byte*)strStd.data(), strStd.size());
bd.MessageEnd();
word64 size = bd.MaxRetrievable();
vector<byte> cypherVector(size);
string decoded;
if (size && size <= SIZE_MAX)
{
decoded.resize(size);
bd.Get((byte*)decoded.data(), decoded.size());
}
Integer cipherMessage((byte*)decoded.data(), decoded.size());
string decoded;
if (size && size <= SIZE_MAX)
{
decoded.resize(size);
bd.Get((byte*)decoded.data(), decoded.size());
}
You have a string called decoded, but you never actually decode the data by running it through a Base64Decoder.
Use something like the following. I don't have a MFC project handy to test, so I'm going to assume you converted the CString to a std::string.
// Converted from Unicode CString
std::string str;
StringSource source(str, true, new Base64Decoder);
Integer value(val, source.MaxRetrievable());
std::cout << std::hex << value << std::endl;
The StringSource is a BufferedTransformation. The Integer constructor you are using is:
Integer (BufferedTransformation &bt, size_t byteCount, Signedness sign=UNSIGNED, ByteOrder order=BIG_ENDIAN_ORDER)
In between the StringSource and the Integer is the Base64Decoder. its a filter that decodes the string on the fly. So data flows from the source (StringSource) to the sink (Integer constructor).
Also see Pipelines on the Crypto++ wiki.
Here is my solution to achieve this. It uses some Qt classes but it should be simple to replace them:
#include <QByteArray>
#include <QScopedArrayPointer>
#include <crypto++/base64.h>
#include <crypto++/rsa.h>
using namespace CryptoPP;
Integer convertBase64ToCryptoPpInt(const QByteArray &base64)
{
Base64Decoder decoder;
decoder.Put(reinterpret_cast<const byte*>(base64.data()), base64.size());
decoder.MessageEnd();
const word64 size = decoder.MaxRetrievable();
QScopedArrayPointer<byte> decoded{new byte[size]};
decoder.Get(decoded.data(), size);
return {decoded.data(), size};
}
QByteArray convertCryptoPpIntToBase64(const Integer &i)
{
// Copy content of i into byte array
const unsigned iLen = i.ByteCount();
QScopedArrayPointer<byte> idata{new byte[iLen]};
i.Encode(idata.data(), iLen);
// Encode data
Base64Encoder encoder;
encoder.Put(idata.data(), iLen);
encoder.MessageEnd();
const int encodedSize = encoder.MaxRetrievable();
QScopedArrayPointer<byte> encoded{new byte[encodedSize]};
encoder.Get(encoded.data(), encodedSize);
return {reinterpret_cast<char*>(encoded.data()), encodedSize};
}
It may be much more compact using CryptoPP's pipelining but i didn't find out how to stream from and to a CryptoPP::Integer.
My goal is to get this:
BYTE Data1[] = {0x6b,0x65,0x79};
BYTE Data2[] = {0x6D,0x65,0x73,0x73,0x61,0x67,0x65};
But my starting point is:
std::string msg = "message";
std::string key = "key";
I am not able to get from std::string to BYTE[].
I tried the following:
std::vector<BYTE> msgbytebuffer(msg.begin(), msg.end());
BYTE* Data1 = &msgbytebuffer[0];
This didn't cause compile or run time error. However, the end result (I feed this to a winapi function - crypto api) was not the same as when I used the actual byte array like in top most ({0x6D,0x65,0x73,0x73,0x61,0x67,0x65}).
You can use string::c_str() function which returns a pointer to c style string that can be passed to winapi functions like:
foo(string.c_str());
What it actually does is that it returns a pointer to an array that contains a null-terminated sequence of characters.
I suppose BYTE[] is actually a char array. You can assign your std::string to char array by doing:
std::string str = "hello";
BYTE byte[6]; // null terminated string;
strcpy(byte, str.c_str()); // copy from str to byte[]
If you want to copy the str without the 0 at the end, use strncpy instead:
BYTE byte[5];
strncpy(byte, str.c_str(), str.length());
Seems me that winapi is waiting a null terminated c-string. You can achieve that by using:
msg.c_str();
or, using your BYTE type, something like that:
std::vector<BYTE> msgbytebuffer(msg.length() + 1, 0);
std::copy(msg.begin(), msg.end(), msgbytebuffer.begin());
I am working to encrypt and decrypt files using Crypto++. In encryption, key and random IV are generated and hexencoded where as text from file is encrypted. Both IV and cipher text are written to the same file.
In decryption, key is generated using same criteria as encryption and random IV is extracted from the file and hexdecoded. Text after iv length is stored in a string and decrypted.
What happens is I can see the original file so I know that it is working but it also displays cipher text after the original file text. Does any one how to solve it?
//some code to declare variables, read from file and so on
unsigned char * inputContent = (unsigned char *) malloc(fileSize * sizeof(char)); //create char array of same size as file content
//inputContent is for storing file data
string rawString(reinterpret_cast<char*>(inputContent), fileSize); //convert char array to string
//extract iv, key and cipher from rawString
string rawIV;
rawIV = rawString.substr(0, 32);
//code to hexdecode iv
string cipher;
cipher = rawString.substr(32, fileSize - 32);
string recovered;
CBC_Mode< AES >::Decryption d;
d.SetKeyWithIV(key, sizeof(key), iv);
StringSource s_recover(cipher, true,
new StreamTransformationFilter(d,
new StringSink(recovered)
)
);
const char * writeContent = recovered.c_str();
if(pwrite(fd, writeContent, recovered.length(), 0) <= 0)
{
return -1; //error
}
Thanks in advance. ☺
You might try something like this. But its hard to say if it will actually work since its not clear what you are actually doing or where the problem lies.
FileSource fs("<filename>", false /*pumpAll*/);
SecByteBlock key(AES::DEFAULT_KEYLENGTH), iv(AES::BLOCKSIZE);
// Fetch key from somewhere
key = ...;
// Fetch IV from file
fs.Detach(new HexDecoder(new ArraySink(iv, iv.size()));
fs.Pump(32);
CBC_Mode< AES >::Decryption dec;
dec.SetKeyWithIV(key, key.size(), iv, iv.size());
string recovered;
fs.Detach(new HexDecoder(new StreamTransformationFilter(dec, new StringSink(recovered))));
fs.PumpAll();
You can also use the following if you get the SecByteBlockSink patch:
SecByteBlock recovered;
fs.Detach(new HexDecoder(new StreamTransformationFilter(dec, new SecByteBlockSink(recovered))));
fs.PumpAll();
rawString isn't needed below:
//create char array of same size as file content
unsigned char * inputContent = (unsigned char *) malloc(fileSize * sizeof(char));
//inputContent is for storing file data
//convert char array to string
string rawString(reinterpret_cast<char*>(inputContent), fileSize);
Maybe you should try:
ArraySource as(inputContent, fileSize, false /*pumpAll*/);
Using the ArraySource means you don't make a copy of the data (the string copies the data), and its ready to go for Crypto++.
Also, since you're already into C++ code, use an unique_ptr and new rather than malloc. The unique_ptr will handle cleanup for you. (Or, use a std::vector).
unique_ptr<byte[]> buffer(new byte[fileSize]);
I don't know how you are going to make a file descriptor work in the grand scheme of things. Crypto++ is a C++ library, and C++ uses I/O streams. Maybe this will help: How to construct a c++ fstream from a POSIX file descriptor?
Also see Retrieving file descriptor from a std::fstream and Getting a FILE* from a std::fstream.
I have c++ code that encrypts a string as a plaintext using AES_CFB and generates a same size ciphertext, but the problem is the data type of input and output, So could anyone help me to let it encrypts an unsigned int number and generates unsigned int number ciphertext withe keeping the same length for the plaintext and chipertext (length of bits ).
string ENCRYPTOR(const std::string& PlainText)
{
byte key[16]= "1234ff";// byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ];
byte iv[16]= "123456";//byte iv[ CryptoPP::AES::BLOCKSIZE ];
std::string CipherText;
// Encryptor
CryptoPP::CFB_Mode< CryptoPP::AES >::Encryption encryptor( key, sizeof(key), iv);
// Encryption
CryptoPP::StringSource( PlainText, true,
new CryptoPP::StreamTransformationFilter( encryptor,
new CryptoPP::StringSink( CipherText ) ) );
return (CipherText);
}
string DECRYPTOR(const string& CipherText)
{
byte key[16]= "1234ff";
byte iv[16]= "123456";
std::string RecoveredText;
// Decryptor
CryptoPP::CFB_Mode< CryptoPP::AES >::Decryption decryptor( key, sizeof(key), iv );
// Decryption
CryptoPP::StringSource( CipherText, true,
new CryptoPP::StreamTransformationFilter( decryptor,
new CryptoPP::StringSink( RecoveredText ) ) );
return (RecoveredText);
}
int main()
{
string ciphertext;
string plaintext = "3555";
ciphertext= ENCRYPTOR(plaintext);
string retrivdat = DECRYPTOR(ciphertext);
cout<<"The plaintext data is: "<<plaintext<<endl;
cout<<"The ciphertextdata is: "<<ciphertext<<endl;
Coot<<"The retrieved data is: "<<retrivdat<<end;
return 0;
}
The output is
The plaintext data is: 3555
The chepertext data is: ï¥R_
The retrieved data is: 3555
Encrypt unsigned int value in form of bits stream by AES_CFB mode
Igor and Owlstead raised some valid points about size of integers and endianess. The easiest solution to avoid them is probably encode the integer as a string:
unsigned int n = ...;
ostringstream oss;
oss << n;
string plainText = oss.str();
Later, you can convert it back with:
string recovered = ...;
istringstream iss(recovered);
unsigned int n;
iss >> n;
byte key[16]= "1234ff";// byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ];
byte iv[16]= "123456";//byte iv[ CryptoPP::AES::BLOCKSIZE ];
Your key and IV are too small. You should be getting compiler warnings because of it. AES::DEFAULT_KEYLENGTH is 16, so you need at least 16 characters for the key. AES::BLOCKSIZE is 16, so you need at least 16 characters for the initialization vector.
If the code above happens to work, then its purely because of luck. You should probably visit CFB Mode on the Crypto++ wiki. It has a working example.
Alternately, use PBKDF to stretch the short key and short IV. You can find an example at Crypto++ pbkdf2 output is different than Rfc2898DeriveBytes (C#) and crypto.pbkdf2 (JavaScript) on Stack Overflow.
The chepertext data is: ï¥R_
You can make this printable with:
string encoded;
HexEncoder hexer(new StringSink(encoded));
hexer.Put((byte*)cipherText.data(), cipherText.size());
hexer.MessageEnd();
cout << encoded << endl;
Alternately, you can use the following (with pipelines):
string encoded;
StringSource ss(cipherText, true,
new HexEncoder(
new StringSink(encoded)));
cout << encoded << endl;
HexEncoder and HexDecoder are discussed on the Crypto++ wiki, too.
So you can:
encode the number into the minimum number of x bytes, for instance using an unsigned big endian number
encrypt with CFB, resulting in the same number of x bytes
decrypt the number
decode the number from the resulting x bytes (using the same encoding scheme of course)
If you want to see the ciphertext as number you'll have to decode the ciphertext as if it was a (signed or unsigned) number.
Note that you will still have to deal with the uniqueness of the IV. If you need to store the IV then there will be significant overhead.