1

I'm trying to obscure some code so when complied casual users can't see the plain text strings if they cat the file.

I've found this and it does do what I want.

string encryptDecrypt(string toEncrypt) {
    char key = 'Q';
    string output = toEncrypt;

    for (int i = 0; i < toEncrypt.size(); i++)
        output[i] = toEncrypt[i] ^ key;

    return output;
}

It's run like:

    foo[0] = encryptDecrypt("/path/jon/files");
    cout << "Encrypted:" << foo[0] << "\n";

    string decrypted = encryptDecrypt(foo[0]);
    cout << "Decrypted:" << decrypted << "\n";

Which results in:

Encrypted:~!0%9~;>?~78=4"
Decrypted:/path/jon/files

My plan(!) was to create a new app that just produced the encrypted strings and then in my my app store all the encrypted strings in an array and decrypt then as needed.

From the above output I know the string /path/jon/files is encrypted to ~!0%9~;>?~78=4" but how do I write that into an array?

I had thought:

string foo[2];
foo[0] = "~!0%9~;>?~78=4"";
foo[1] = "XXXXXXX";

But I can't see that working becuase the string contains quotes.

Any way to do this?

UPDATE

I seem to have an issue when I have capital letters in my initial string.

string encrypted = encryptDecrypt("/Path/Jon/Files");
cout << "Encrypted:" << encrypted << "\n";

string decrypted = encryptDecrypt(encrypted);
cout << "Decrypted:" << decrypted << "\n";

string test = "~0%9~?~8=4\"";
decrypted = encryptDecrypt(test);
cout << "Decrypted:" << decrypted << "\n";

Results in:

Encrypted:~0%9~?~8=4"
Decrypted:/Path/Jon/Files
Decrypted:/ath/n/iles

Any idea how to get around that?

Biffen
  • 6,249
  • 6
  • 28
  • 36
Rocket
  • 1,065
  • 2
  • 21
  • 44

3 Answers3

2

escape it

foo[0] = "~!0%9~;>?~78=4\"";

need to be carfully with this, charachter encoding and code pages may joke with you.

UPD: possible will be actual links base64 encode-decode How do I base64 encode (decode) in C? and base64 decode snippet in c++

Community
  • 1
  • 1
oklas
  • 7,935
  • 2
  • 26
  • 42
  • Thanks I've escaped the quotes but the resulting decoded string is different.. If the initial string contains capital letters then they are missing from the decrypted string.. I'll update my original post with an example. – Rocket Feb 09 '16 at 15:06
  • yes, there is a joke smile of charachter encoding.Work with binary read-write cripted data into file, but not with manual edit text – oklas Feb 09 '16 at 15:14
  • If you need to work manually, one way else is to use conversion crypted into base64 or to text hexadecimal when show and deconvert back when read from user input – oklas Feb 09 '16 at 15:19
  • Thanks for the comments. I'm only trying to make the text harder to read if someone tries to read the compiled file. Any ideas on the best way to do that ? – Rocket Feb 09 '16 at 16:20
1

You're 'losing' your capitals because you're xoring them with 'Q' and so losing most of their significant bits and they come back as control codes.

Here's a program that encrypts a string as a std::vector<char> for inclusion in your source-code. The problem with your plan to use std::string is some of the values might be invalid characters (e.g. out of place pieces of a UTF-8 multi-byte encoding). The behaviour of std::string containing invalid characters is unspecified. However an `std::vector can contain the full range of byte values.

#include <iostream>
#include <sstream>
#include <vector>

std::vector<char> encrypt(const std::string& toEncrypt) {
    char key = 'Q';
    std::vector<char> output;
    output.reserve(toEncrypt.size());

    for (const auto chr : toEncrypt){
        output.push_back(chr ^ key);
    }
    return output;
}

std::string sourcify(const std::vector<char>& toSource,const std::string& comment){
    
    std::stringstream buffer;
    buffer<<"const std::vector<char> code={";
    bool first=true;
    for(const auto chr : toSource){
        if(!first){
            buffer<<',';
        }else{
            first=false;
        }
        buffer<<static_cast<int>(chr);
    }
    buffer<<"}; /* "<<comment<<" */";
    return buffer.str();
}

std::string decrypt(const std::vector<char>& toDecrypt) {
    char key = 'Q';
    std::string decrypted;
    decrypted.reserve(toDecrypt.size());
    for(const auto chr:toDecrypt){
        decrypted.push_back(chr ^ key);
    }
    return decrypted;
}

int main() {
    
    std::string original="Hello World";
    std::vector<char> encrypted=encrypt(original);
    std::string sourced=sourcify(encrypted,original);
    std::string decrypted=decrypt(encrypted);
    
    std::cout<<original<<std::endl;
    std::cout<<sourced<<std::endl;
    std::cout<<decrypted<<std::endl;
    
    return 0;
}
Persixty
  • 8,165
  • 2
  • 13
  • 35
  • When I try and compile this I lots of errors. How do I do it ? – Rocket Feb 09 '16 at 16:05
  • @Rocket It's in C++14. What are you using? What are the errors? – Persixty Feb 09 '16 at 16:07
  • Name : gcc Version : 4.7 Release : 7.1.1 `In function ‘std::vector encrypt(const string&)’: error: ‘chr’ does not name a type error: expected ‘;’ before ‘return’ error: expected primary-expression before ‘return’ error: expected ‘;’ before ‘return’ error: expected primary-expression before ‘return’ error: expected ‘)’ before ‘return’` – Rocket Feb 09 '16 at 16:19
  • `In function ‘std::string sourcify(const std::vector&, const string&)’: error: ‘chr’ does not name a type error: expected ‘;’ before ‘buffer’ error: expected primary-expression before ‘return’ error: expected ‘)’ before ‘return’` – Rocket Feb 09 '16 at 16:19
  • `In function ‘std::string decrypt(const std::vector&)’: error: ‘chr’ does not name a type error: expected ‘;’ before ‘}’ token error: expected primary-expression before ‘}’ token error: expected ‘;’ before ‘}’ token error: expected primary-expression before ‘}’ token error: expected ‘)’ before ‘}’ token error: expected primary-expression before ‘}’ token error: expected ‘;’ before ‘}’ token` – Rocket Feb 09 '16 at 16:19
  • ahh.. no I didn't ! I'll re test this. I have found this link which does work `http://create.stephan-brumme.com/hide-strings-executable/` – Rocket Feb 10 '16 at 13:22
  • @Rocket will probably work but may have the same problem as your approach. Most implementations are relatively tolerant of invalid character sequences but technically it is unspecified behavior. You shouldn't (really) treat any old sequence of bytes as a string. Though to be fair C++s conflation of byte and char does lead you that way. – Persixty Feb 10 '16 at 15:46
  • 1
    Aren't you missing a " return decrypted;" in your source code? – BmyGuest Apr 16 '21 at 17:37
0

I have automated my string encryption with:

https://github.com/PELock/StringEncrypt-WebAPI

and it looks like this right now (I took your string so you can see the result)

// encrypted with https://www.stringencrypt.com (v1.3.0) [C/C++]
// foo = "/path/jon/files"
wchar_t foo[16];

foo[8] = 0x29F5; foo[15] = 0x591E; foo[14] = 0x10DF; foo[6] = 0x28D7;
foo[2] = 0x538B; foo[12] = 0x5691; foo[7] = 0x2996; foo[1] = 0x240C;
foo[4] = 0x29D9; foo[13] = 0x5890; foo[10] = 0x5553; foo[3] = 0x2B2A;
foo[0] = 0x518D; foo[9] = 0x54F4; foo[5] = 0x57B8; foo[11] = 0x5472;

for (unsigned int vHlTZ = 0, WgRam = 0; vHlTZ < 16; vHlTZ++)
{
        WgRam = foo[vHlTZ];
        WgRam += vHlTZ;
        WgRam ^= 0x4EE7;
        WgRam = (((WgRam & 0xFFFF) >> 6) | (WgRam << 10)) & 0xFFFF;
        WgRam ^= 0xF4F6;
        WgRam += vHlTZ;
        WgRam ^= vHlTZ;
        WgRam = ~WgRam;
        WgRam = ((WgRam << 14) | ( (WgRam & 0xFFFF) >> 2)) & 0xFFFF;
        WgRam += vHlTZ;
        WgRam = ((WgRam << 4) | ( (WgRam & 0xFFFF) >> 12)) & 0xFFFF;
        WgRam -= 0x184C;
        WgRam ^= 0xDE4A;
        WgRam += 0x5463;
        WgRam += vHlTZ;
        foo[vHlTZ] = WgRam;
}

wprintf(foo);

It works like this:

  1. Provide string label
  2. Set string / file to encrypt
  3. String is encrypted with random algorithm
  4. Decryption code is generated in C/C++