使C / C ++ ZeroMQ LibCurve无法在简单的示例中工作的问题

时间:2018-07-24 09:18:59

标签: c++ zeromq libsodium

我正在尝试使一个简单的铁房客户端/服务器应用程序正常工作。客户端二进制文件必须与服务器二进制文件分开。

我遇到的问题是ZMQ / CZMQ示例代码在客户端和服务器之间共享相同的证书变量。因此,它既没有演示密钥交换,也没有演示从磁盘读取公共密钥,实际上,这些示例对任何事情都没有用。

我遇到的问题是,当我尝试将示例源代码分成单独的客户端/服务器代码时,由于我无法解决如何在客户端和服务器之间交换公钥,因此出现挂起,段错误。

挂起的发送和接收数据非常令人沮丧,因为无法诊断它们为什么挂起。也很难在文档中找到任何内容来解释为什么如果存在密码问题,为什么发送和接收功能应该挂起而没有任何错误或其他任何原因。

CZMQ ironhouse2示例为:

//  The Ironhouse Pattern
//
//  This is exactly the same example but broken into two threads
//  so you can better see what client and server do, separately.
//
//  WARNING: CZMQ APIv2 will not compile with the current version of CZMQ
//
//
//  For more info see: http://hintjens.com/blog:49#toc7
//

#include <czmq.h>

//  The client task runs in its own context and receives the 
//  server public key as an argument.

static void *
client_task (void *args)
{
    //  Load our persistent certificate from disk
    zcert_t *client_cert = zcert_load ("client_cert.txt");
    assert (client_cert);

    //  Create client socket and configure it to use full encryption
    zctx_t *ctx = zctx_new ();
    assert (ctx);
    void *client = zsocket_new (ctx, ZMQ_PULL);
    assert (client);
    zcert_apply (client_cert, client);
    zsocket_set_curve_serverkey (client, (char *) args);
    int rc = zsocket_connect (client, "tcp://127.0.0.1:9000");
    assert (rc == 0);

    //  Wait for our message, that signals the test was successful
    char *message = zstr_recv (client);
    assert (streq (message, "Hello"));
    free (message);
    puts ("Ironhouse test OK");

    //  Free all memory we used
    zcert_destroy (&client_cert);
    zctx_destroy (&ctx);
    return NULL;
}

static void *
server_task (void *args)
{
    zctx_t *ctx = zctx_new ();
    assert (ctx);

    //  Start the authenticator and tell it do authenticate clients
    //  via the certificates stored in the .curve directory.
    zauth_t *auth = zauth_new (ctx);
    assert (auth);
    zauth_set_verbose (auth, true);
    zauth_allow (auth, "127.0.0.1");
    zauth_configure_curve (auth, "*", ".curve");

    //  Create server socket and configure it to use full encryption
    void *server = zsocket_new (ctx, ZMQ_PUSH);
    assert (server);
    zcert_apply ((zcert_t *) args, server);
    zsocket_set_curve_server (server, 1);
    int rc = zsocket_bind (server, "tcp://*:9000");
    assert (rc != -1);

    //  Send our test message, just once
    zstr_send (server, "Hello");
    zclock_sleep (200);

    //  Free all memory we used
    zauth_destroy (&auth);
    zctx_destroy (&ctx);
    return NULL;
}

int main (void) 
{
    //  Create the certificate store directory and client certs
    zcert_t *client_cert = zcert_new ();
    int rc = zsys_dir_create (".curve");
    assert (rc == 0);
    zcert_set_meta (client_cert, "name", "Client test certificate");
    zcert_save_public (client_cert, ".curve/testcert.pub");
    rc = zcert_save (client_cert, "client_cert.txt");
    assert (rc == 0);
    zcert_destroy (&client_cert);

    //  Create the server certificate
    zcert_t *server_cert = zcert_new ();

    //  Now start the two detached threads; each of these has their
    //  own ZeroMQ context.
    zthread_new (server_task, server_cert);
    zthread_new (client_task, zcert_public_txt (server_cert));

    //  As we're using detached threads this is the simplest way 
    //  to ensure they both end, before we exit the process. 200
    //  milliseconds should be enough for anyone. In real code,
    //  you would use messages to synchronize threads.
    zclock_sleep (200);

    //  Free the memory we used
    zcert_destroy (&server_cert);
    return 0;
}

尝试将公共密钥与文件分开加载会产生它们自己的问题。这是发生的情况的一个示例:

void SaveAndLoadCert(){
  zcert_t *ClientCertificate=zcert_new ();
  zsys_dir_create(".curve");
  zcert_set_meta(ClientCertificate,"name","Client test certificate");
  zcert_save_public(ClientCertificate,".curve/testcert.pub");
  zcert_t *CertFromDisk=zcert_load(".curve/testcert.pub");
  char *ClientKey=strdup(zcert_public_txt(CertFromDisk));
  if(zcert_eq(CertFromDisk,ClientCertificate)){
    puts("Certificates are the same");
  }
  else{
    puts("Certificates are not the same");
  }
}

输出为:

root@Battista:~/Encryption/Curve# g++ Test.cpp -lczmq
root@Battista:~/Encryption/Curve# ./a.out 
Certificates are not the same

因此,我将公共证书保存到磁盘,然后拉出相同的证书,而不是相同的证书。我不明白

但是,如果我通过将zcert_save_public更改为zcert_save来保存公共和私有证书,那是可行的,但这对任何人都没有用!

任何人都可以使用czmq / libcurve库为单独的客户/服务器铁屋加密示例提供代码吗?

0 个答案:

没有答案