Home Upgrade Search Memberlist Extras Hacker Tools Award Goals Help Wiki Contact

The Brotherhood 

C++ Compile-time Encryption & Runtime Decryption w/ String Clearing

[Image: header4.gif]


This is a simple tool loosely based on skCrypter. It offers encryption of standard strings when compiling, with a decrypt function for runtime. You can then clear the string so it is completely emptied and no longer available in its encrypted or decrypted form.

Example of usage with visual message boxes:
Code
#include <windows.h>
#include "include/CompileTimeCrypt.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    auto encryptedHello = encrypt("Hello, World!"); // Encrypts at compile time
    MessageBoxA(NULL, encryptedHello.decrypt(), "Decrypted HW Message 1", MB_OK); // Decrypts at runtime
    encryptedHello.clear(); // this will write over / erase the original encrypted and decrypted strings
    MessageBoxA(NULL, encryptedHello.decrypt(), "Decrypted HW Message 2", MB_OK); // because the message was cleared, the window is blank

    auto encryptedTestMessage = encrypt("Second Test!"); // Encrypts at compile time
    MessageBoxA(NULL, encryptedTestMessage.decrypt(), "Test Message 1", MB_OK); // Decrypts at runtime
    MessageBoxA(NULL, encryptedTestMessage.decrypt(), "Test Message 2", MB_OK); // Expected to return decrypted string again, because uncleared
    encryptedTestMessage.clear(); // this will write over / erase the original encrypted and decrypted strings
    MessageBoxA(NULL, encryptedTestMessage.decrypt(), "Test Message 3", MB_OK); // because the message was cleared, the window is blank

    MessageBoxA(NULL, encrypt("Inline String Test").decrypt(), "Inline String Test - One Liner", MB_OK); // Encrypts at compile & decrypts at runtime - oneliner
    // not recommended if you need to clear the data as there will not be a way to do so
    
    return 0;
    
}

Header File:
Code
#pragma once
#pragma once

#include <cstddef> // For size_t

template <size_t N>
class EncryptedString {
public:
    constexpr EncryptedString(const char (&str)[N])
        : encrypted_{}, isEncrypted_(true), isCleared_(false) {
        for (size_t i = 0; i < N; ++i) {
            encrypted_[i] = str[i] ^ generateKey(i);
        }
    }

    const char* decrypt() const {

        if (isCleared_) {
            return ""; // Return an empty string if already cleared or decrypted.
        }

        if(!isEncrypted_){
            return decrypted_;
        }

        for (size_t i = 0; i < N; ++i) {
            decrypted_[i] = encrypted_[i] ^ generateKey(i);
        }
        isEncrypted_ = false; // Mark as decrypted
        return decrypted_;
    }

    void clear() {
        if (!isCleared_) {
            // Overwrite both encrypted and decrypted data to ensure it's irrecoverable.
            for (size_t i = 0; i < N; ++i) {
                encrypted_[i] = '\0';
                decrypted_[i] = '\0';
            }
            isEncrypted_ = false;
            isCleared_ = true; // Mark as cleared to block decryption.
        }
    }

    bool isEncrypted() const {
        return isEncrypted_;
    }

    bool isCleared() const {
        return isCleared_;
    }

private:
    mutable char encrypted_[N]; // Mutable to allow clearing
    mutable char decrypted_[N]{}; // Mutable for decryption
    mutable bool isEncrypted_;  // Tracks encryption status
    mutable bool isCleared_;    // Tracks whether data has been cleared

    static constexpr char generateKey(size_t position) {
        return '\xAA' ^ static_cast<char>((position * 33) % 256);
    }
};

// Helper function to deduce the size of the string at compile time and create an EncryptedString instance
template <size_t N>
constexpr EncryptedString<N> encrypt(const char (&str)[N]) {
    return EncryptedString<N>(str);
}

This is just the first prototype in this thread. I am working on this project here:
https://github.com/LNodesL/Compile-Time-...ypt-in-CPP


Give it a star / follow to receive updates for custom XOR improvements, AES-256, and function overloads for different types of strings, as well as size-required string types in an alternate encrypt(string, size) format.
I am looking into other ways to obfuscate rather than encrypt during runtime in c. I like the source of your crypter as well, especially the construction in memory.

I am going to test this out and debug, if you plan on adding XOR please let me know and I will gladly lend a hand, I have been trying to do xor on runtime and get it to work properly while maintaining a small stub size.
Although some of these methods could be modified and possibly used for polymorphism, as its being built during runtime
(Apr 5, 2024 12:29 PM)PulseLink Wrote:  I am looking into other ways to obfuscate rather than encrypt during runtime in c. I like the source of your crypter as well, especially the construction in memory.

I am going to test this out and debug, if you plan on adding XOR please let me know and I will gladly lend a hand, I have been trying to do xor on runtime and get it to work properly while maintaining a small stub size.
Although some of these methods could be modified and possibly used for polymorphism, as its being built during runtime

I do have some XOR examples, but I prefer aes > xor and AFAIK xor is not as secure. However, it's easy to use and I noticed that sometimes just using AES itself can cause a detection or at least suspicion.

Is there a reason you would want to obfuscate rather than encrypt?
(Mar 10, 2024 09:31 AM)Hackers Wrote:  This is a simple tool loosely based on skCrypter. It offers encryption of standard strings when compiling, with a decrypt function for runtime. You can then clear the string so it is completely emptied and no longer available in its encrypted or decrypted form.

Example of usage with visual message boxes:
Code
#include <windows.h>
#include "include/CompileTimeCrypt.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    auto encryptedHello = encrypt("Hello, World!"); // Encrypts at compile time
    MessageBoxA(NULL, encryptedHello.decrypt(), "Decrypted HW Message 1", MB_OK); // Decrypts at runtime
    encryptedHello.clear(); // this will write over / erase the original encrypted and decrypted strings
    MessageBoxA(NULL, encryptedHello.decrypt(), "Decrypted HW Message 2", MB_OK); // because the message was cleared, the window is blank

    auto encryptedTestMessage = encrypt("Second Test!"); // Encrypts at compile time
    MessageBoxA(NULL, encryptedTestMessage.decrypt(), "Test Message 1", MB_OK); // Decrypts at runtime
    MessageBoxA(NULL, encryptedTestMessage.decrypt(), "Test Message 2", MB_OK); // Expected to return decrypted string again, because uncleared
    encryptedTestMessage.clear(); // this will write over / erase the original encrypted and decrypted strings
    MessageBoxA(NULL, encryptedTestMessage.decrypt(), "Test Message 3", MB_OK); // because the message was cleared, the window is blank

    MessageBoxA(NULL, encrypt("Inline String Test").decrypt(), "Inline String Test - One Liner", MB_OK); // Encrypts at compile & decrypts at runtime - oneliner
    // not recommended if you need to clear the data as there will not be a way to do so
    
    return 0;
    
}

Header File:
Code
#pragma once
#pragma once

#include <cstddef> // For size_t

template <size_t N>
class EncryptedString {
public:
    constexpr EncryptedString(const char (&str)[N])
        : encrypted_{}, isEncrypted_(true), isCleared_(false) {
        for (size_t i = 0; i < N; ++i) {
            encrypted_[i] = str[i] ^ generateKey(i);
        }
    }

    const char* decrypt() const {

        if (isCleared_) {
            return ""; // Return an empty string if already cleared or decrypted.
        }

        if(!isEncrypted_){
            return decrypted_;
        }

        for (size_t i = 0; i < N; ++i) {
            decrypted_[i] = encrypted_[i] ^ generateKey(i);
        }
        isEncrypted_ = false; // Mark as decrypted
        return decrypted_;
    }

    void clear() {
        if (!isCleared_) {
            // Overwrite both encrypted and decrypted data to ensure it's irrecoverable.
            for (size_t i = 0; i < N; ++i) {
                encrypted_[i] = '\0';
                decrypted_[i] = '\0';
            }
            isEncrypted_ = false;
            isCleared_ = true; // Mark as cleared to block decryption.
        }
    }

    bool isEncrypted() const {
        return isEncrypted_;
    }

    bool isCleared() const {
        return isCleared_;
    }

private:
    mutable char encrypted_[N]; // Mutable to allow clearing
    mutable char decrypted_[N]{}; // Mutable for decryption
    mutable bool isEncrypted_;  // Tracks encryption status
    mutable bool isCleared_;    // Tracks whether data has been cleared

    static constexpr char generateKey(size_t position) {
        return '\xAA' ^ static_cast<char>((position * 33) % 256);
    }
};

// Helper function to deduce the size of the string at compile time and create an EncryptedString instance
template <size_t N>
constexpr EncryptedString<N> encrypt(const char (&str)[N]) {
    return EncryptedString<N>(str);
}

This is just the first prototype in this thread. I am working on this project here:
https://github.com/LNodesL/Compile-Time-...ypt-in-CPP


Give it a star / follow to receive updates for custom XOR improvements, AES-256, and function overloads for different types of strings, as well as size-required string types in an alternate encrypt(string, size) format.



dude i also wrote an encryption class using c++ time ago, that's what it requires to encrypt and decrypt a string:

--------------------------------------- PSEUDO CODE --------------------------------------

Code
#include "lib/viper.cpp"

using namespace std;
using namespace ViperCipher;

int main(int argc, char **argv)
{
    string  plain = "something to encrypt";
    Viper *viper = new Viper();

    string_view enc = viper->Encrypt(plain);
    string_view dec = viper->Decrypt(enc);
    
    std::cout << "Encrypted: " << enc << std::endl;
    std::cout << "Decrypted: " << dec << std::endl;

    delete viper;
    return EXIT_SUCCESS;
};

the class has a lot of features such as easy SSL key generation, hashing, crack ciphers, etc... check it out on github, i also made a documentation for people who like documentations :)


and this is how you generate a pair of ssl public/private keys saving them either locally or in a file...

Code
#include "lib/viper.cpp"

using namespace std;
using namespace ViperCipher;

int main(int argc, char **argv) {
    Viper *viper = new Viper();                                                
                          
    auto FlagLocal = ViperCipher::RSA_KEY_FLAG::SCRIPT_COLLECTOR;  // save key/s locally
    auto FlagFile = ViperCipher::RSA_KEY_FLAG::FILE_COLLECTOR;          // save key/s to file

    viper->GenRsaPrivateKey("private.pem", Flag);  // generate
    string_view get_key = viper->getPrivateKey();    // collect
    delete viper;
    return 0;
};


tell me what you think, i shared it because i see you also created something similar...
(Apr 13, 2024 02:31 PM)nucleo_type09 Wrote:  dude i also wrote an encryption class using c++ time ago, that's what it requires to encrypt and decrypt a string:

--------------------------------------- PSEUDO CODE --------------------------------------

Code
#include "lib/viper.cpp"

using namespace std;
using namespace ViperCipher;

int main(int argc, char **argv)
{
    string  plain = "something to encrypt";
    Viper *viper = new Viper();

    string_view enc = viper->Encrypt(plain);
    string_view dec = viper->Decrypt(enc);
    
    std::cout << "Encrypted: " << enc << std::endl;
    std::cout << "Decrypted: " << dec << std::endl;

    delete viper;
    return EXIT_SUCCESS;
};

the class has a lot of features such as easy SSL key generation, hashing, crack ciphers, etc... check it out on github, i also made a documentation for people who like documentations :)


and this is how you generate a pair of ssl public/private keys saving them either locally or in a file...

Code
#include "lib/viper.cpp"

using namespace std;
using namespace ViperCipher;

int main(int argc, char **argv) {
    Viper *viper = new Viper();                                                
                          
    auto FlagLocal = ViperCipher::RSA_KEY_FLAG::SCRIPT_COLLECTOR;  // save key/s locally
    auto FlagFile = ViperCipher::RSA_KEY_FLAG::FILE_COLLECTOR;          // save key/s to file

    viper->GenRsaPrivateKey("private.pem", Flag);  // generate
    string_view get_key = viper->getPrivateKey();    // collect
    delete viper;
    return 0;
};


tell me what you think, i shared it because i see you also created something similar...

Nice, you should make your own thread and post the full source to the Viper class!
Thanks for sharing here though, I always appreciate seeing other examples, it'll help any of us be better the more we can compare & learn from eachother.
(Apr 14, 2024 04:47 AM)Hackers Wrote:  Nice, you should make your own thread and post the full source to the Viper class!
Thanks for sharing here though, I always appreciate seeing other examples, it'll help any of us be better the more we can compare & learn from eachother.

i also created a thread on it but nobody seems to care tho haha, i think people here tend to be more interested in python coding rather then c++,
(Apr 14, 2024 05:06 AM)nucleo_type09 Wrote:  i also created a thread on it but nobody seems to care tho haha, i think people here tend to be more interested in python coding rather then c++,

I will go check it out now - and yeah, a lot more people are going to want a higher level solution, something that feels more manageable, perhaps is easier to setup, is more cross-platform, and is more common. Unfortunately this means higher level languages are always in more demand than lower level, but this phenomenon is also why lower level programmers make more money, can do more advanced things, etc. so it's a balance of pros & cons I guess
(Apr 14, 2024 10:16 AM)Hackers Wrote:  I will go check it out now - and yeah, a lot more people are going to want a higher level solution, something that feels more manageable, perhaps is easier to setup, is more cross-platform, and is more common. Unfortunately this means higher level languages are always in more demand than lower level, but this phenomenon is also why lower level programmers make more money, can do more advanced things, etc. so it's a balance of pros & cons I guess

what do you prefer? lower or higher?
(Apr 14, 2024 10:55 AM)nucleo_type09 Wrote:  what do you prefer? lower or higher?

Lower for my long-term career plans, higher for small projects that don't require low level.
Depends on the project, team skills, etc.

For example at work I have brought in some of my C++. One was a utility tool for starting up some server processes. Another is to let a codebase have different versions of certain files, but shared files for the rest - like having site1 use 'page1-A' and site2 uses 'page1-B' but both share the same code for 'page2'. And then I did a couple small things, but other than that our company doesn't use C/C++ at all for anything other than what I've chosen to bring over in last few months. So if someone asked what language would be best for a project at my current job - probably always a high level language because no other devs mess around with low level except me currently, even if it would make sense to.
(Apr 14, 2024 11:04 AM)Hackers Wrote:  Lower for my long-term career plans, higher for small projects that don't require low level.
Depends on the project, team skills, etc.

For example at work I have brought in some of my C++. One was a utility tool for starting up some server processes. Another is to let a codebase have different versions of certain files, but shared files for the rest - like having site1 use 'page1-A' and site2 uses 'page1-B' but both share the same code for 'page2'. And then I did a couple small things, but other than that our company doesn't use C/C++ at all for anything other than what I've chosen to bring over in last few months. So if someone asked what language would be best for a project at my current job - probably always a high level language because no other devs mess around with low level except me currently, even if it would make sense to.

c++ idk about others, but to me it just boosts my brain activity at the highest level because you know it requires you to think alot about what you writing, i like the feeling, that's why i prefer to use it over higher level haha,
did you worked with networking in c++? maybe some socket programming? what are your opinions about it compared to higher level langs when working with networking? are higher level langs faster to work with but maybe lower quality or just the same?
(Apr 14, 2024 11:20 AM)nucleo_type09 Wrote:  c++ idk about others, but to me it just boosts my brain activity at the highest level because you know it requires you to think alot about what you writing, i like the feeling, that's why i prefer to use it over higher level haha,
did you worked with networking in c++? maybe some socket programming? what are your opinions about it compared to higher level langs when working with networking? are higher level langs faster to work with but maybe lower quality or just the same?

I only started writing C++ a few months ago, I'm still very new to it. I've done some networking things, but only through win API so far & common functions. I haven't gone too low level with anything networking related really, and haven't done too much with sockets. I had GPT whip up some examples for it, as well as some wininet functionality and they were easy to work with.

I think higher level langs can be faster to work with in many cases (for dev speed, not runtime speed) but if the project becomes more and more complicated, using a higher level lang may end up being a mistake in the long run.

Lately I'm a fan of lower > higher, at least for personal dev. Anything I do outside of work is in C/C++ for the most part, for the sole sake of learning more, but also the final programs are smaller & faster from what I've seen.
(Apr 14, 2024 01:49 PM)Hackers Wrote:  I only started writing C++ a few months ago, I'm still very new to it. I've done some networking things, but only through win API so far & common functions. I haven't gone too low level with anything networking related really, and haven't done too much with sockets. I had GPT whip up some examples for it, as well as some wininet functionality and they were easy to work with.

I think higher level langs can be faster to work with in many cases (for dev speed, not runtime speed) but if the project becomes more and more complicated, using a higher level lang may end up being a mistake in the long run.

Lately I'm a fan of lower > higher, at least for personal dev. Anything I do outside of work is in C/C++ for the most part, for the sole sake of learning more, but also the final programs are smaller & faster from what I've seen.

for me is a bit different, im not working in the field, actually, i don't really have a job yet, i didn't even try to get one so far, i always thought that if you intersect hobby and job, you get annoyed by both haha, from your experience working and hobbying with the same subject, how is it? does it feel better?
(Apr 14, 2024 02:01 PM)nucleo_type09 Wrote:  for me is a bit different, im not working in the field, actually, i don't really have a job yet, i didn't even try to get one so far, i always thought that if you intersect hobby and job, you get annoyed by both haha, from your experience working and hobbying with the same subject, how is it? does it feel better?

You have to be careful bout burnout, but you also get double the efficiencies. And skill improvements over time. Imagine if I coded at work and knitted at home. I'd be good at coding and knitting, but if you code at work and code at home ... well, you get the point
interesting approach bud,what would be interesting is to add and ensure compatibility across different platforms.
Nice share bud, I like how you are developing day by day.
(Apr 14, 2024 03:39 PM)Hackers Wrote:  You have to be careful bout burnout, but you also get double the efficiencies. And skill improvements over time. Imagine if I coded at work and knitted at home. I'd be good at coding and knitting, but if you code at work and code at home ... well, you get the point

bro lot of people are sending me popularity points, i DO really appreciate what u just did, it really shows how you people here in this community are well structured, but i think the job and hobby thing, it also depends don't u think? because CSS developers and system developers are both IT paths but the level on knowledge and advanced concepts implementation are on different sides, so yeah, i would say with honesty, i do thing working and hobbying with it is advantageous ... but it also depends a bit, don't u agree? :)


Possibly Related Threads...
Thread / Author Replies Views Last Post
[C] by PELockApr 14, 2026 01:15 PM 0 128 Apr 14, 2026 01:15 PM
Last Post: PELock
by KlonopinApr 10, 2026 02:08 AM 10 644 Apr 10, 2026 02:08 AM
Last Post: PELock
[Lua] by PELockApr 10, 2026 02:03 AM 0 168 Apr 10, 2026 02:03 AM
Last Post: PELock