Как использовать SocketSource и SocketSink в crypto ++ - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь написать сетевую программу с использованием инструментов сокета crypto ++.Но это всегда работает неправильно.

Вопрос 1:

Я хочу написать две программы.Одним из них является сервер.Другой клиент.Сервер может отправлять много данных (много раз) клиенту.

Ниже приведен мой код.

Код сервера:

#include<iostream>
#include<socketft.h>
#include<string>
using namespace std;
using namespace CryptoPP;

int main()
{
    try
    {
        Socket::StartSockets();//strating sockets
        Socket socServer;
        socServer.Create(SOCK_STREAM);//create a socket's object
        unsigned int iport;
        string send_str;
        cout << "input port:" ;
        cin >> iport;

        socServer.Bind(iport);//binding
        socServer.Listen();//listening
        Socket socClient;//client's socket
        socServer.Accept(socClient);//accept


        while(true)
        {
            cout << "input string:" ;
            cin >> send_str;
            //cin.clear();
            //getline(cin,send_str);
            StringSource str_send_Src1(send_str,true,new SocketSink(socClient));
        }

        /*
        cout << "input string:" ;
        cin >> send_str;
        StringSource str_send_Src1(send_str,true,new SocketSink(socClient));

        cout << "input string:" ;
        cin >> send_str;
        StringSource str_send_Src2(send_str,true,new SocketSink(socClient));
        */

        socServer.CloseSocket();
        socClient.CloseSocket();
        Socket::ShutdownSockets();
    }
    catch(const Exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;
}

Код клиента:

#include<iostream>
#include<socketft.h>
#include<string>
using namespace std;
using namespace CryptoPP;

int main()
{
    try
    {
        Socket::StartSockets();
        Socket socClient;
        socClient.Create(SOCK_STREAM);
        string straddr;
        unsigned int iport;
        cout << "input connecting ip:" ;
        cin >> straddr;
        cout << "input connecting port:" ;
        cin >> iport;
        socClient.Connect(straddr.c_str(),iport);//connecting


        while(true)
        {
            string receive;
            SocketSource receiverSrc(socClient.GetSocket(),true,new StringSink(receive));
            cout << receive ;
        }

        socClient.CloseSocket();
        Socket::ShutdownSockets();
    }
    catch(const Exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;
}

Проблема:

При запуске сервера, а затем при запуске клиента они будут работать правильно.Однако я могу вводить данные только один раз.Тогда сервер застрял и не принимает ввод.

Как решить эту проблему?кто может мне помочь?

Вопрос 2:

Я хочу создать безопасный канал, используя сокет crypto ++ и другие алгоритмы криптографии.Но я не могу правильно отправить данные между сервером и клиентом.

Ниже приведен мой код.

Код сервера:

#include<iostream> 
#include<socketft.h>
#include<files.h>
#include<osrng.h>
#include<string>
#include<tiger.h>
#include<eccrypto.h>
#include<integer.h>
#include<dh.h>
#include<hex.h>
using namespace std;
using namespace CryptoPP;

int main()
{
    try
    {
        //server
        Socket::StartSockets();
        Socket socServer;
        socServer.Create(SOCK_STREAM);
        unsigned int iport;

        string filename;
        cout << "input port:" ;
        cin >> iport;
        //iport = 5050;

        socServer.Bind(iport);
        socServer.Listen();
        Socket socClient;
        socServer.Accept(socClient);

        string testStr = "you have connected...";
        StringSource testSenSrc(testStr,true,new SocketSink(socClient.GetSocket()));
        SocketSource testRecSrc(socClient.GetSocket(),true,new StringSink(testStr));
        cout << "client'"+testStr+" have connected...";


        AutoSeededRandomPool rng;
        ECDSA<ECP,Tiger>::PrivateKey prikey_server;


       prikey_server.Load(
         FileSource("sin_prikey_server.der",true).Ref());
       ECDSA<ECP,Tiger>::PublicKey pubkey_client;
       pubkey_client.Load(
         FileSource("sin_pubkey_client.der",true).Ref());

        ECDSA<ECP,Tiger>::Signer sig_server(prikey_server);

        ECDSA<ECP,Tiger>::Verifier ver_client(pubkey_client);


        Integer p("B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
            "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
            "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
            "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
            "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
            "DF1FB2BC2E4A4371h");
        Integer g("A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
            "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
            "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
            "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
            "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
            "855E6EEB22B3B2E5h");
        Integer q("F518AA8781A8DF278ABA4E7D64B7CB9D49462353h");
        DH dh(p,q,g);

        SecByteBlock dh_prikey_server(dh.PrivateKeyLength());

        SecByteBlock dh_pubkey_server(dh.PublicKeyLength());

        dh.GenerateKeyPair(rng,dh_prikey_server,dh_pubkey_server);


        ArraySource Sig_dh_pubkey_Src(
          dh_pubkey_server,dh_pubkey_server.size(),true,
          new SignerFilter(rng,sig_server,
          new SocketSink(socClient),true));


        SecByteBlock dh_pubkey_client(dh.PublicKeyLength());

        SocketSource ArrSrc(socClient,true,
            new SignatureVerificationFilter(ver_client,
            new ArraySink(dh_pubkey_client,dh_pubkey_client.size()),
            SignatureVerificationFilter::SIGNATURE_AT_END
            |SignatureVerificationFilter:: PUT_MESSAGE));   


        SecByteBlock agreedkey(dh.AgreedValueLength());

        boolbResult=dh.Agree(
          agreedkey,dh_prikey_server,dh_pubkey_client);
        if(bResult)
            cout << "key aggrement success..." << endl;
        else
        {
            throw Exception(Exception::INVALID_ARGUMENT,
                "key aggrement failure...");
        }


        socServer.CloseSocket();
        socClient.CloseSocket();
        Socket::ShutdownSockets();
    }
    catch(const Exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;
}

Код клиента:

#include<iostream>
#include<socketft.h>
#include<files.h>
#include<string>
#include<osrng.h>
#include<files.h>
#include<tiger.h>
#include<eccrypto.h>
#include<integer.h>
#include<dh.h>
#include<hex.h>
#include<secblock.h>
using namespace std;
using namespace CryptoPP;

int main()
{
    try
    {
        //Client
        Socket::StartSockets();
        Socket socClient;
        socClient.Create(SOCK_STREAM);
        string straddr;
        unsigned int iport;

        cout << "input ip:" ;
        cin >> straddr;
        //straddr = "127.0.0.1";
        cout << "input port:" ;
        cin >> iport;
        //iport = 5050;
        socClient.Connect(straddr.c_str(),iport);


        StringSource testSenSrc(straddr,true,
            new SocketSink(socClient));
        string testStr;
        SocketSource testRecSrc(socClient,true,
            new StringSink(testStr));
        cout << testStr << endl;


        AutoSeededRandomPool rng;
        ECDSA<ECP,Tiger>::PrivateKey prikey_client;

        prikey_client.Load(
          FileSource("sin_prikey_client.der",true).Ref());
        ECDSA<ECP,Tiger>::PublicKey pubkey_server;
        pubkey_server.Load(
          FileSource("sin_pubkey_server.der",true).Ref());


        ECDSA<ECP,Tiger>::Signer sig_client(prikey_client);

        ECDSA<ECP,Tiger>::Verifier ver_server(pubkey_server);

        Integer p("B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
            "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
            "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
            "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
            "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
            "DF1FB2BC2E4A4371h");
        Integer g("A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
            "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
            "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
            "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
            "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
            "855E6EEB22B3B2E5h");
        Integer q("F518AA8781A8DF278ABA4E7D64B7CB9D49462353h");
        DH dh(p,q,g);

        SecByteBlock dh_prikey_client(dh.PrivateKeyLength());
        SecByteBlock dh_pubkey_client(dh.PublicKeyLength());
        dh.GenerateKeyPair(rng,dh_prikey_client,dh_pubkey_client);



        ArraySource Sig_dh_pubkey_Src(
          dh_pubkey_client,dh_pubkey_client.size(),true,
        new SignerFilter(rng,sig_client,
        new SocketSink(socClient.GetSocket()),true));


        SecByteBlock dh_pubkey_server(dh.PublicKeyLength());
        SocketSource ArrSrc(socClient,true,
            new SignatureVerificationFilter(ver_server,
            new ArraySink(dh_pubkey_server,dh_pubkey_server.size()),
            SignatureVerificationFilter::SIGNATURE_AT_END 
            |SignatureVerificationFilter:: PUT_MESSAGE));   

        SecByteBlock agreedkey(dh.AgreedValueLength());

        boolbResult=dh.Agree(
          agreedkey,dh_prikey_client,dh_pubkey_server);
        if(bResult)
            cout << "key agreement success..." << endl;
        else
        {
            throw Exception(Exception::INVALID_ARGUMENT,
                "key agreement failure...");
        }


        socClient.CloseSocket();
        Socket::ShutdownSockets();
    }
    catch(const Exception& e)
    {
        cout << e.what() << endl;
    }
    return 0;
}

Проблема:

при загрузке сервера, затем при запуске клиента, он не будет работать правильно.Но когда я удаляю некоторые коды на сервере и клиенте, он показывает «успех соглашения о ключе ...».

Ниже приведены коды, удаленные с сервера.

string testStr = "you have connected...";
StringSource testSenSrc(testStr,true,new 
   SocketSink(socClient.GetSocket()));
SocketSource testRecSrc(socClient.GetSocket(),true,new 
   StringSink(testStr));
cout << "client'"+testStr+" have connected...";

Ниже приведены кодыудалено из клиента.

StringSource testSenSrc(straddr,true,
            new SocketSink(socClient));
string testStr;
SocketSource testRecSrc(socClient,true,
            new StringSink(testStr));
cout << testStr << endl;

Это похоже на первый вопрос.Потому что второй вопрос вызван «два раза отправкой и получением».При удалении вышеуказанных кодов он работает правильно.

SocketSink позволяет отправлять данные только один раз?Кто может мне сказать?

Спасибо, очень-очень жутко. ​​

Я нашел похожий вопрос: CryptoPP: как использовать SocketSource и SocketSink

1 Ответ

0 голосов
/ 30 ноября 2018

Как сказал jww, мы должны отказаться от сетевых инструментов crypto ++.Потому что он довольно старый и всегда вызывает проблемы.Мы можем попробовать libevent, asio и т. Д.

Следующие ссылки показывают некоторую сетевую библиотеку о c ++.

Best C / C ++ Network Library

...