我正在尝试使一个简单的铁房客户端/服务器应用程序正常工作。客户端二进制文件必须与服务器二进制文件分开。
我遇到的问题是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库为单独的客户/服务器铁屋加密示例提供代码吗?