c++ccryptographypublic-key-encryption

Public Private Key Encryption Tutorials


Do you know of a tutorial that demonstrates Public Private Key encryption(PPKE) in C++ or C?

I am trying to learn how it works and eventually use Crypto++ to create my own encryptions using public private keys. Maybe theres a Crypto++ PPKE tutorial?

Maybe someone can explain the relationship(if any) between the public and private keys? Could anyone suggest some very simple public and private key values I could use(like 'char*32','char/32') to create my simple PPKE program to understand the concept?


Solution

  • Here's a toy version of RSA I wrote some time back. The thing that makes it a toy is that it only uses 32-bit numbers. To provide any meaningful level of security, you need to support much larger numbers for the math (typical key ranges are something like 1024-4096 bits or so, though the latter probably doesn't accomplish much).

    Nonetheless, this does implement the real RSA algorithm. It would take relatively little to plug in a bignum package so this code could work with RSA keys of practical size (though most other implementations are probably faster).

    #include <iostream>
    #include <iterator>
    #include <algorithm>
    #include <vector>
    #include <functional>
    
    const int e_key = 47;
    const int d_key = 15;
    const int n = 391;
    
    struct crypt : std::binary_function<int, int, int> {
        int operator()(int input, int key) const { 
            int result = 1;
            for (int i=0; i<key; i++) {
                result *= input;
                result %= n;
            }
            return result;
        }
    };
    
    int main() {
        std::string msg = "Drink more Ovaltine.";
        std::vector<int> encrypted;
    
        std::transform(msg.begin(), msg.end(),  
            std::back_inserter(encrypted),
            std::bind2nd(crypt(), e_key));
    
        std::transform(encrypted.begin(), encrypted.end(), 
            std::ostream_iterator<char>(std::cout, ""), 
            std::bind2nd(crypt(), d_key));
        std::cout << "\n";
    
        return 0;
    }
    

    Of course, this only covers the encryption and decryption itself -- that's a long ways short of being a complete security system.

    Much like the comments have noted, this is intended purely to support understanding of the algorithm. I've never put it to serious use, and probably never will. Although supporting real key sizes would be fairly trivial, it's open to question whether I'll ever even do that -- if I did, somebody might mistake it for something that should be used on real data, which I don't really intend.

    Oh, there's one other point that makes this toy-level encryption. As it stands right now, each byte is encrypted individually. That means it's acting as a substitution cipher. There are 256 inputs, and each maps to one of 256 outputs. As such, the way this works right now, you can break it (pretty easily) like almost any other byte at time substitution cipher, completely ignoring how the substitution is done. In real use, you typically just use it to encrypt a key for something like AES-256, and encrypt the whole thing as a single block, which renders most attacks on substitution ciphers ineffective.