AES/CFB Cipher mode decrypting from the string fail - c++

Seems like I misunderstand how is CFB cipher mode works. This leads to an error. Approaches 1 and 2 do not work because I am reading encrypted text from a created string. But approach 3 works because it gets crypted text from c string just encrypted. Can't figure it out why?
Code:
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include "modes.h"
#include "aes.h"
#include "filters.h"
using namespace std;
using namespace CryptoPP;
int main()
{
byte key[AES::DEFAULT_KEYLENGTH] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6' };
byte iv[AES::BLOCKSIZE] = { '3', '4', '5', '6', '7', '8', '9', '0', '1', '2', '3', '4', '5', '6', '7', '8' };
string data = "fur fur fur fur fur";
cout << "1: Original text: " << data << endl;
CFB_Mode<AES>::Encryption cfbEncryption(key, sizeof(key), iv);
const char* data_c_str = data.c_str();
cfbEncryption.ProcessData((byte*)data_c_str, (byte*)data_c_str, data.length() + 1);
cout << "2: Encrypted text: " << data_c_str << endl;
string d(data_c_str); // after assigning c str to a string. Can get it to work!
const char* data_c_str2 = d.c_str(); // get c str. Now the value of it the same as data_c_str.
// Approach 1 Failure
string decr;
CFB_Mode<AES>::Decryption cfbDecryption(key, sizeof(key), iv);
StreamTransformationFilter stfDecryptor(cfbDecryption, new StringSink(decr));
stfDecryptor.Put(reinterpret_cast<const unsigned char*>(data_c_str2), d.size() + 1);
stfDecryptor.MessageEnd();
cout << "3. Approach 1.: Decrypted text: " << decr << endl; // output "fur fur fur fur"
// Approach 2 Failure
CFB_Mode<AES>::Decryption cfbDecryption2(key, sizeof(key), iv);
cfbDecryption2.ProcessData((byte*)data_c_str2, (byte*)data_c_str2, data.length() + 1);
cout << "4. Approach 2.: Decrypted text: " << data_c_str2 << endl; // output "fur fur fur furЂuФX"
// Approach 3 Success. Note that below code works properly because of usage data_c_str taken from data after encryption.
CFB_Mode<AES>::Decryption cfbDecryption3(key, sizeof(key), iv);
cfbDecryption3.ProcessData((byte*)data_c_str, (byte*)data_c_str, data.length() + 1);
cout << "5. Approach 3.: Decrypted text: " << data_c_str << endl; // output "fur fur fur fur fur"
cin.get();
return 0;
}

I figured it out.
auto dl = data.length();
auto dl2 = d.length();
cout << "Encrypted data length: " << dl << endl; // output: 19
cout << "Encrypted data length at assigned string: " << dl2 << endl; // output: 14
The length of encrypted string and newly assigned string are not the same because the encrypted text contains '\0' char at 14th byte of an array.

Related

Why STL map's method "find" raise "core dumped" with the std::bitset type key? [duplicate]

I have a array consisting of chars like [1,2,3,4,5,.,..] and I have a loop that looks like
for (size_t i = 0; i < size; ++i)
os << data[i]; // os is std::ostream&
This loop prints the array in the correct order without any errors. But when I use this loop to print it backwards
for (size_t i = (size - 1); i >= 0; --i)
os << data[i];
I get a segmentation fault error. Any reason why this can happen?
The condition i >= 0 is always true (because size_t is an unsigned type). You've written an infinite loop.
Doesn't your compiler warn you about that? I know g++ -Wextra does here.
What you can do instead is this:
for (size_t i = size; i--; ) {
os << data[i];
}
This uses post-decrement to be able to check the old value of i, which allows the loop to stop just after i = 0 (at which point i has wrapped around to SIZE_MAX).
size_t is unsigned int so it always remain positive, so your loop is an infinite loop
You can use a C++ for-in loop to avoid the problem. Example:
#include <iostream>
#include <vector>
#include <boost/range/adaptor/reversed.hpp>
using std::vector;
using std::cout;
using boost::adaptors::reverse;
int main()
{
auto v = vector<char>{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X' };
char const* sep = "";
for (auto c : v)
{
cout << sep << c;
sep = " ";
}
cout << "\n";
sep = "";
for (auto c : reverse(v))
{
cout << sep << c;
sep = " ";
}
cout << "\n";
}

Cout giving garbage output when looping through a const char

When executing the following code I get what I expect plus some unexpected output:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca;
while (*cp)
{
cout << *cp << endl;
++cp;
}
}
Output:
h
e
l
l
o
ⁿ
■
m
What are the last remaining characters? Is there something in the const char array that is not being accounted for?
while (*cp)
This loop ends when cp points to a null character.
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
The array does not contain the null character.
Therefore the loop iterates over the array, and outside of its bounds. The behaviour of accessing an array outside of its bounds is undefined.
The while loops until *cp equal 0.
This fix:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char ca[] = { 'h', 'e', 'l', 'l', 'o', '\0' }; // <-- add '\0'
const char* cp = ca;
while (*cp) // loop until *cp equal '\0'
{
cout << *cp << endl;
++cp;
}
}
Or this:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
const char ca[] = { "hello" };
const char* cp = ca;
while (*cp)
{
cout << *cp << endl;
++cp;
}
}

I am having more characters in the file that I am writing in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am writing to a file using ofstream in C++. Each line has to have a relative time, a comma, and the value that I am writing. The values are std::vector<unsigned char> in order to write any value that I want and to read back in another method. My test is writing 3 values. The first value is concatenated to a weird byte on the end, even if I use \0 or \n. But the other 2 values are fine.
This is the output file:
0,BAC�
1000,DEF
2000,GHI
And the second problem is when I read the values. I don't know how to set dynamically an array to read only the values that are written on the line and compare to the previous char vector that I wrote before.
Header file:
class SensorRecorder {
private:
std::ofstream outFile;
std::ifstream infile;
std::string path;
long duration = -1;
public:
const std::string OUTPUT_DIR = "out";
const std::string EXTENSION = ".out";
const char SEPARATOR = ',';
SensorRecorder(const char *classNameType);
~SensorRecorder();
int write(std::vector<unsigned char> value);
std::vector<unsigned char> read(long relativeTime);
void close();
std::string getFileName();
};
Implementation:
#include "utils/SensorRecorder.h"
#include "utils/DateTools.h"
#include <cstring>
#include <iostream>
#include <boost/filesystem.hpp>
SensorRecorder::SensorRecorder(const char *classNameType) {
boost::filesystem::path full_path(boost::filesystem::current_path());
full_path.append(OUTPUT_DIR, boost::filesystem::path::codecvt());
if (boost::filesystem::create_directory(full_path)) {
std::cout << "Directory Created: " << full_path << std::endl;
}
std::string fileName = classNameType + ((std::string) "-") + DateTools::getPlainDate() + EXTENSION;
full_path.append(fileName, boost::filesystem::path::codecvt());
path = full_path.c_str();
outFile.open(path);
}
int SensorRecorder::write(std::vector<unsigned char> value) {
if (outFile.is_open()) {
char *data = reinterpret_cast<char *>(value.data());
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto value = now_ms.time_since_epoch();
if (duration == -1) {
duration = 0;
} else {
duration = value.count() - duration;
}
// write in the file
outFile << duration << SEPARATOR << data << '\0' << '\n';
duration = value.count();
} else {
return 0;
}
return 1;
}
std::vector<unsigned char> SensorRecorder::read(long relativeTime) {
infile.open(path);
if (infile.is_open()) {
std::cout << "Reading from the file" << std::endl;
long duration;
char comma;
unsigned char data[300];
while (infile >> duration >> comma >> data) {
std::cout << "duration: " << duration << std::endl;
std::cout << "data: " << data << std::endl;
if (duration == relativeTime) {
std::cout << "INSIDE " << std::endl;
infile.close();
// cast the value
std::vector<unsigned char> outputValues(data, data + sizeof(data));
return outputValues;
}
}
infile.close();
}
return std::vector<unsigned char>();
}
My test:
TEST_F(SensorRecorderTest, TestWriteOnFile) {
std::vector<unsigned char> inputValues01 = {'B', 'A', 'C'};
std::vector<unsigned char> inputValues02 = {'D', 'E', 'F'};
std::vector<unsigned char> inputValues03 = {'G', 'H', 'I'};
mySensorRecorder = new SensorRecorder("SensorRecorderTest");
// write on the file
int ret = mySensorRecorder->write(inputValues01);
ASSERT_EQ(ret, 1);
std::this_thread::sleep_for(std::chrono::seconds(1));
ret = mySensorRecorder->write(inputValues02);
ASSERT_EQ(ret, 1);
std::this_thread::sleep_for(std::chrono::seconds(2));
ret = mySensorRecorder->write(inputValues03);
ASSERT_EQ(ret, 1);
mySensorRecorder->close();
// read from the file
std::vector<unsigned char> outputValues01 = mySensorRecorder->read(0);
ASSERT_EQ(inputValues01, outputValues01);
}
The error:
Expected equality of these values:
inputValues01
Which is: { 'B' (66, 0x42), 'A' (65, 0x41), 'C' (67, 0x43) }
outputValues01
Which is: { 'B' (66, 0x42), 'A' (65, 0x41), 'C' (67, 0x43), '\xE4' (228), '\x16' (22), '\x7F' (127), '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', ... }
The issue is null terminated strings.
char *data = reinterpret_cast<char *>(value.data());
outFile << duration << SEPARATOR << data << '\0' << '\n';
The contract of a char* on its own is that it ends with a \0 (to know how many characters to write, strlen will look up the first available \0). In your case, it doesn't. You should use a real string, or at least use:
outFile << duration << SEPARATOR << std::string(data, data+3) << '\n';
Adding a \0 on this instruction will not make the string null terminated by magic. You have to keep the size.
(read has the same flaw).
I changed the write method to not convert vector to char array and afterward I just push_back the \0 character.
int SensorRecorder::write(std::vector<unsigned char> value) {
if (outFile.is_open()) {
auto now = std::chrono::system_clock::now();
auto now_ms = std::chrono::time_point_cast<std::chrono::milliseconds>(now);
auto v = now_ms.time_since_epoch();
if (duration == -1) {
duration = 0;
} else {
duration = v.count() - duration;
}
// write in the file
value.push_back('\0');
std::cout << value.size() << " " << value.data() << std::endl;
outFile << duration << SEPARATOR << value.data() << '\n';
// evaluate duration time to the next write
duration = v.count();
} else {
std::cerr << "error writing..." << std::endl;
return 0;
}
return 1;
}

c++ Segmentation fault when trying to reverse print an array

I have a array consisting of chars like [1,2,3,4,5,.,..] and I have a loop that looks like
for (size_t i = 0; i < size; ++i)
os << data[i]; // os is std::ostream&
This loop prints the array in the correct order without any errors. But when I use this loop to print it backwards
for (size_t i = (size - 1); i >= 0; --i)
os << data[i];
I get a segmentation fault error. Any reason why this can happen?
The condition i >= 0 is always true (because size_t is an unsigned type). You've written an infinite loop.
Doesn't your compiler warn you about that? I know g++ -Wextra does here.
What you can do instead is this:
for (size_t i = size; i--; ) {
os << data[i];
}
This uses post-decrement to be able to check the old value of i, which allows the loop to stop just after i = 0 (at which point i has wrapped around to SIZE_MAX).
size_t is unsigned int so it always remain positive, so your loop is an infinite loop
You can use a C++ for-in loop to avoid the problem. Example:
#include <iostream>
#include <vector>
#include <boost/range/adaptor/reversed.hpp>
using std::vector;
using std::cout;
using boost::adaptors::reverse;
int main()
{
auto v = vector<char>{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'X' };
char const* sep = "";
for (auto c : v)
{
cout << sep << c;
sep = " ";
}
cout << "\n";
sep = "";
for (auto c : reverse(v))
{
cout << sep << c;
sep = " ";
}
cout << "\n";
}

How do I convert hex numbers to a character in c++?

I'm trying to convert a hex number to a character in C++.
I looked it up but I can't find an answer that works for me.
Here is my code:
char mod_tostring(int state, int index, int size) {
int stringAddress = lua_tolstring(state, index, 0);
const char* const Base = (const char* const)stringAddress;
return Base[0];
};
Base[0] would return a hex number like:
0000005B
If you go here http://string-functions.com/hex-string.aspx and put 0000005B as the input it outputs the character "[". How would I also output [?
To print a number as a character, you can either assign it to a char variable or cast it to a char type:
unsigned int value = 0x5B;
char c = static_cast<char>(value);
cout << "The character of 0x5B is '" << c << "` and '" << static_cast<char>(value) << "'\n";
You could also use snprintf:
char text_buffer[128];
unsigned int value = 0x5B;
snprintf(&text_buffer[0], sizeof(text_buffer),
"%c\n", value);
puts(text_buffer);
Example program:
#include <iostream>
#include <cstdlib>
int main()
{
unsigned int value = 0x5B;
char c = static_cast<char>(value);
std::cout << "The character of 0x5B is '" << c << "` and '" << static_cast<char>(value) << "'\n";
std::cout << "\n"
<< "Paused. Press Enter to continue.\n";
std::cin.ignore(1000000, '\n');
return EXIT_SUCCESS;
}
Output:
$ ./main.exe
The character of 0x5B is '[` and '['
Paused. Press Enter to continue.
Try this:
std::cout << "0x%02hX" << Base[0] << std::endl;
Output should be: 0x5B assuming Base[0] is 0000005B.