简体   繁体   中英

How to exchange public keys?

I have Client and Server, and want to have encrypt communication channel between them. This is some simple code to generate public and private keys:

    RSA::PrivateKey privateKey;
    privateKey.Initialize()

    ///////////////////////////////////////
    // Generate Parameters
    InvertibleRSAFunction params;
    params.GenerateRandomWithKeySize(this->rng, 3072);

    ///////////////////////////////////////
    // Generated Parameters
    const Integer& n = params.GetModulus();
    const Integer& p = params.GetPrime1();
    const Integer& q = params.GetPrime2();
    const Integer& d = params.GetPrivateExponent();
    const Integer& e = params.GetPublicExponent();

    params.

    ///////////////////////////////////////
    // Dump
    cout << "RSA Parameters:" << endl;
    cout << " n: " << n << endl;
    cout << " p: " << p << endl;
    cout << " q: " << q << endl;
    cout << " d: " << d << endl;
    cout << " e: " << e << endl;
    cout << endl;

    ///////////////////////////////////////
    // Create Keys
    RSA::PrivateKey privateKey(params);
    RSA::PublicKey publicKey(params);

But how I can get client's public key on server side and server's public key on client side? may be exist more simple way than serialize public key in file, send file, receive file on the other side and deserialize it?

Class Chat have DataTransferingInterface instance, which point to Server or Client (it depends on whether the user has selected on the start). Some code for understanding:

Class Chat:

class Chat : public OwnerServerInterface, public OwnerClientInterface
    public:
        //a lot of methods
    protected:
        virtual void handshakeServerSide(int clientSocket, void *objectForSaveIn, void *dataToSend);
        virtual void handshakeClientSide(int serverSocket, void *objectForSaveIn, void *dataToSend);
    private:
        DataTransferingInterface* interface;

In methods handshakeServerSide() and handshakeClientSide() Server's Chat instance and Client's Chat instance make the handshake (data exchanging). In this methods server must send it's own public key, and get the client's public key. But how to do it?

... how I can get client's public key on server side and server's public key on client side?

That is known as the key distribution problem . It may (or may not be) manageable on a small scale, but its a very thorny problem when you scale it up.

The answer(s) depend on your particular instance problem, and that looks like a N-way chat program. There's really too much to the problem to answer on a programming site like Stack Overflow.

Maybe you should read up on the problem, including Multi-party or Group Diffie-Hellman schemes. Also think about what you want to happen when a member leaves a group. Then ask targeted questions on the Information Security Stack Exchange .

Follow code is very simple class-wrapper for Crypto++ RSA algorithm:

EncoderRSA.h

class EncoderRSA
{
    public:
        EncoderRSA();
        void keyGeneration();
        void substitutePublicKey(Integer e, Integer n);
        Integer encode(std::string plainText);
        std::string decode(Integer cypher);
        Integer getE();
        Integer getN();
    private:
        AutoSeededRandomPool prng;
        RSA::PublicKey publicKey;   // For encrypt plain text
        RSA::PrivateKey privateKey; // For decrypt plain text
};

EncoderRSA.cpp

void EncoderRSA::keyGeneration() {
    InvertibleRSAFunction params;
    params.GenerateRandomWithKeySize(this->prng, 3072);

    RSA::PrivateKey privateKey(params);
    RSA::PublicKey publicKey(params);

    //because you can't do:    this->privateKey(params);
    this->privateKey = privateKey;
    this->publicKey = publicKey;
}

void EncoderRSA::substitutePublicKey(Integer e, Integer n) {
    this->publicKey.Initialize(n, e);
}

Integer EncoderRSA::encode(std::string plainText) {
    Integer m((const byte*)plainText.data(), plainText.size());
    Integer c = this->publicKey.ApplyFunction(m);
    return c;
}

std::string EncoderRSA::decode(Integer cypher) {
    Integer r = this->privateKey.CalculateInverse(this->prng, cypher);

    std::string decoded;
    size_t req = r.MinEncodedSize();
    decoded.resize(req);

    r.Encode((byte*)decoded.data(), decoded.size());

    return decoded;
}

Integer EncoderRSA::getE() {
    return this->publicKey.GetPublicExponent();
}

Integer EncoderRSA::getN() {
    return this->publicKey.GetModulus();
}

Server must generate it's own keys (public and private), save it, save it's own public key (if exactly: PublicExponent and PublicModulus) separately (in Integer variables), get public key from Client, replace own public key by Client's public key.

The same about the Client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM