1. ZMQ 官方文档

ZMQ 的官方文档中关于 curve 的介绍如下:

Client and server roles

A socket using CURVE can be either client or server, at any moment, but not both. The role is independent of bind/connect direction.

A socket can change roles at any point by setting new options. The role affects all zmq_connect and zmq_bind calls that follow it.

To become a CURVE server, the application sets the ZMQ_CURVE_SERVER option on the socket, and then sets the ZMQ_CURVE_SECRETKEY option to provide the socket with its long-term secret key. The application does not provide the socket with its long-term public key, which is used only by clients.

To become a CURVE client, the application sets the ZMQ_CURVE_SERVERKEY option with the long-term public key of the server it intends to connect to, or accept connections from, next. The application then sets the ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SECRETKEY options with its client long-term key pair.

If the server does authentication it will be based on the client's long term public key.

  

官方文档中提到的几个点都很关键:

  • 一个 curve socket 既可以是服务端,也可以是客户端。但不可以既是服务端的同时又是客户端
  • 一个 socket 可以在任何 point (不知道怎么翻译 point 才合适)上通过设置新属性的方式改变角色, 改变一个 socket 角色后,会影响接下来对这个 socket 做的所有 zmq_connect() 和 zmq_bind() 调用, 也就是说需要在这两个调用之前进行 curve 属性的设置。
  • 如果要把一个 socket 作为 curve server ,需要设置 ZMQ_CURVE_SERVER 和 ZMQ_CURVE_SECRETKEY 属性
  • 如果要把一个 socket 作为 curve client,需要设置 ZMQ_CURVE_SERVERKEY 以及 ZMQ_CURVE_PUBLICKEY、ZMQ_CURVE_SECRETKEY 这三个属性

2. 几行核心代码

想要使用 ZMQ curve 进行加密通信,需要在 ZMQ 的 server 端和 client 端进行相应的配置, 几行需要进行的配置代码如下:

2.1 curve server 端

 char szsecertkey[] = {};
char szpublickey[] = {}; //需要把这个 curve 公钥发给 client
zmq_curve_keypair(szpublickey, szsecertkey); int option = ;
zmq_setsockopt(sock, ZMQ_CURVE_SERVER, &option, sizeof(option));
zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szsecertkey, strlen(szsecertkey)); zmq_bind(sock, szaddr);

2.2 curve client 端

//这个 server_publickey 就是从 server 端拿到的 curve 公钥
zmq_setsockopt(sock, ZMQ_CURVE_SERVERKEY, server_publickey, strlen(server_publickey)); char szpubkey[] = {};
char szprikey[] = {};
zmq_curve_keypair(szpubkey, szprikey);
zmq_setsockopt(sock, ZMQ_CURVE_PUBLICKEY, szpubkey, strlen(szpubkey));
zmq_setsockopt(sock, ZMQ_CURVE_SECRETKEY, szprikey, strlen(szprikey)); zmq_connect(sock, szaddr);

3. 完整代码及执行
3.1 完整代码

代码链接: https://pan.baidu.com/s/1ytJdEa2VmYWfSx6mxIKYVw 提取码: ebyv

下载代码后,解压,执行编译命令:

g++ -g -o server server.c -lzmq -lpthread
g++ -g -o client client.c -lzmq

3.2 程序执行

代码演示了两个模式,一个是使用 curve 加密的传输模式,另一个是不使用 curve 加密的传输模式。 如果要使用 curve 加密的传输模式,需要在执行 server 和 client 程序的时候都加上 -s 参数。

1) 先执行 server

 [root@fengbo :: curve]$ ./server -s
server.c : test tZMQ with curve
server.c : szsecertkey = [I%43ZHg-Bnls&6rZ&)<J6hwGlD&I5l7]mi]{Ch-]
server.c : szpublickey = [kvIP^po{(kRL<eib#Zv=.cE%BpNom2DY#jl0-Ro[]
server.c : start secert comunication
server.c : recv msg : [I say ]
server.c : send msg : [I say , too]

2) 再执行 Client

 [root@fengbo :: curve]$ ./client -s
client.c : test tZMQ with curve
client.c : server publickey : [kvIP^po{(kRL<eib#Zv=.cE%BpNom2DY#jl0-Ro[]
client.c : start secert comunication
client.c : send msg : [I say ]
client.c : recv msg : [I say , too]

4. ZMQ curve 加密效果分析
通过对加密前与加密后的 ZMQ 消息进行 tcpdump 抓包,可以看到 ZMQ curve 的加密效果如何。

因为使用的是 127.0.0.1 作为测试地址,所以在使用 tcpdump 抓包的时候选择 lo 网口:

tcpdump -i lo -A -vv -X

4.1 加密前的抓包记录

对于不可打印的字符,tcpdump 都以点号 '.' 进行了显示

 ::49.788893 >.E.........
::07.333841 <.E.>.E.....
::49.788919 >.E.
::49.788990 <.E...........
::49.788997 >.E.
::49.789294 <.E............
::49.789303 >.E.
::49.789634 <.E...NULL................................................
::49.789875 >.E..NULL................................................
::49.789900 <.E..).READY.Socket-Type....DEALER.Identity....
::49.790309 >.E.
::49.790369 <.E..).READY.Socket-Type....DEALER.Identity......I.say.
::49.790561 >.E...I.say.,.too
::49.829945 <.E.

上面显示的信息是经过简化后的解析数据,不过可以看到 ZMQ 的两个 socket 之间通信的细节,例如可以看到几个 ZMQ 的关键字: DEALERSocket-TypeIdentity

以及 client 发送的数据 I say 1 ,和 server 返回的数据 I say 1, too。

很明显,数据在 ZMQ 中是以明文进行传输的。

4.2 加密后的抓包记录

::06.178841 ....>./........
::44.849972 ....>./>./....
::06.178864 >./>./
::06.178975 >./>./..........
::06.178982 >./>./
::06.179369 >./>./...........
::06.179376 >./>./
::06.180410 >.>./..NULL................................................
::06.180571 >.>..NULL................................................
::06.180588 >.>..).READY.Socket-Type....DEALER.Identity....
::06.181017 >.>.
::06.181064 >.>..).READY.Socket-Type....DEALER.Identity......request.publickey
::06.181191 >.>..((#65P{?aJEt@lWf/DDeQo@QX@gN{4nF3:?jz<^-
::06.183369 ....>.........
::02.029846 ....>.>.....
::06.183389 >.>.
::06.183485 >.>...........
::06.183491 >.>.
::06.183676 >.>............
::06.183681 >.>.
::06.184210 >.>...CURVE...............................................
::06.185457 >.>..CURVE...............................................
::06.188362 >.>....HELLO........................................................
....................{...:H_....."R&.....w.N..r..L...........Rv(b...F...
-+u.w....M...j).B.!<j.'...(..j...*..Qw........G.....c.....Y....:...
::06.190931 >.;>....WELCOME..6k.......,......a}.R..C.....>....|..a.z#...A[;..Yy..
..F`......k.......~...k.fDa./../.A7..m..J......i.b.......<.k.....T.....
..{......Y.........b..B....@w..t.MM
::06.196571 >.6A>.;........$.INITIATEX......fXA..{J%D<...O\.i?4.3$.../.../J#....ZpF
xZ...r...pj...C.&.k,...]`KF..|.i4.H(K..W..Fm".BU...........!...x....<..
....T....Z...6a....A....P.......c.V...........[E.n...|`@.~...aua..p...
#..N....._.....A....!.}....^Y2=..)..K.(.+.e6]..`..$;..k".g.].~.A.Hn
...GS%.U.ot..whb<..>..D\
::06.201254 >.6E>.6A.A.READY.........H.f.n....sS.....p\.y.ZM..F........l........wY.?G.
::06.202853 >.6G>.6E.(.MESSAGE..........t.oR..&:.SI..QI.m.....
::06.203034 >.6G>.6G.-.MESSAGE.............O]i........M....to....#
::06.220452 >.6Y>.
::06.242435 >.6o>.6G
::08.539483 >.?h>.6G.(.MESSAGE.........3n..l6~~..N.....\..[:T.
::08.539814 >.?h>.?h.-.MESSAGE...........<...A...Mq..=.........vs
::08.539824 >.?h>.?h

从 tcpdump 抓取的数据可以看到 CURVE 这样的字符,这说明 ZMQ 开始建立 curve 加密链接了。 不过在建立 curve 链接之前,有一个 client 向 server 请求公钥的操作,我们甚至可以在抓到的数 据中看到 server 发送给 client 的公钥 [(#65P{8?aJEt@lWf/DDeQo@QX@gN{4nF3:?jz<^-]。

因为传输公钥是在建立 curve 链接之前进行的, 所以我们还是可以看到明文数据的。

在上面的抓包数据中, CURVE 关键字出现的时候,就是 server 和client 开始进行 curve 链接的过程了, 可以看到这几个关键字:HELLO、WELCOME、INITIATEX、READY、MESSAGE。这些都是 ZMQ 的 curve 协议的一部分。

在上面的抓包数据中,我们没有看到 I say 1,也没有看到 I say 1, too。因为这些数据已经被加密传输了。 不过我们可以猜到,I say 1 和 I say 1, too 就跟在最后三行的两个 MESSAGE 的后面,只不过被加密了,我们看不到。


同步发表:https://www.fengbohello.top/archives/zeromq-curve

ZMQ示例:使用 curve 进行加密通信的更多相关文章

  1. 单片机上使用TEA加密通信(转)

    源:单片机上使用TEA加密通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.72 单片机:STM32 说 ...

  2. 开源项目SMSS发开指南(四)——SSL/TLS加密通信详解

    本文将详细介绍如何在Java端.C++端和NodeJs端实现基于SSL/TLS的加密通信,重点分析Java端利用SocketChannel和SSLEngine从握手到数据发送/接收的完整过程.本文也涵 ...

  3. Oracle TDE的数据加密示例并用logminer验证加密效果

    1.确认数据库版本 2创建密钥钱包 3创建加密列的表并初始值 4演示TDE的数据加密示例 5 logminer验证加密效果

  4. bugzilla4的xmlrpc接口api调用实现分享: xmlrpc + https + cookies + httpclient +bugzilla + java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能

    xmlrpc .  https . cookies . httpclient.bugzilla . java实现加密通信下的xmlrpc接口调用并解决登陆保持会话功能,网上针对bugzilla的实现很 ...

  5. Crypto API加密通信流程

    应用程序使用Crypto API进行加密通信的一般步骤如下: 1,include wincrypt.h 2,调用CryptAcquireContext()获得某个CSP模块中的密钥容器(key con ...

  6. SSL及其加密通信过程

    SSL及其加密通信过程 什么是SSL SSL英文全称Secure Socket Layer,安全套接层,是一种为网络通信提供安全以及数据完整性的安全协议,它在传输层对网络进行加密.它主要是分为两层: ...

  7. Python3+ssl实现加密通信

    一.说明 1. python标准库ssl可实现加密通信 2. ssl库底层使用openssl,做了面向对像化改造和简化,但还是可以明显看出openssl的痕迹 3. 本文先给出python实现的soc ...

  8. RSA加密通信小结(二)-新版本APP与后台通信交互内容修改方案

    注1:本次修改分为两步,首先是内容相关的修改,待其完成之后,再进行加密通信项(粗体字备注)修改. 1.新的提交后台的格式包括:data,token(预留字段,暂时后台不校验),userId(已有的不删 ...

  9. RSA加密通信小结(一)

    一.背景描述 帮朋友完成相关方案的改进. 二.计划与方案 1.加密方式采用RSA 1024加密. 2.发送与接收都采用RSA加密,采用两套不同的密钥. 3.统一的加解码函数.(此处除了对于传输数据进行 ...

随机推荐

  1. POJ 3258 River Hopscotch (最大最小距离)【二分】

    <题目链接> 题目大意:现在有起点和终点两个石块,这两个石块之间有N个石块,现在对这N个石块移除M个石块,使得这些石块之间的最短距离最大,注意,起点和终点这两个石块不能被移除. 解题分析: ...

  2. 实现简单的web框架

    实现简单的web框架 流程: 服务端启动---服务端等待请求---客户端访问---服务端响应请求 代码: from wsgiref.simple_server import make_server # ...

  3. python数据结构之quick_sort

    Quick sort , also known as partition-exchange sort, divides the data to be sorted into two separate ...

  4. react 15.5版本的警告问题

    一.问题描述 前几天从git上拉下一个项目,cnpm i 安装依赖,项目跑起来后,发现有两个警告.之前这个项目都好好的,怎么突然报错了? Warning: Accessing PropTypes vi ...

  5. C#选择文件、选择文件夹、打开文件

    1.选择文件用OpenDialog OpenFileDialog dialog = new OpenFileDialog(); dialog.Multiselect = true;//该值确定是否可以 ...

  6. prufer编码

    看51nod的一场比赛,发现不会大家都A的一道题,有关prufer的 我去年4月就埋下prufer这个坑,一直没解决 prufer编码是什么 对于一棵无根树的生成的序列,prufer序列可以和无根树一 ...

  7. Java并发编程(四)-- Java内存模型

    Java内存模型 前面讲到了Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见.从抽象的角 ...

  8. [SPOJ-CIRU]The area of the union of circles/[BZOJ2178]圆的面积并

    [SPOJ-CIRU]The area of the union of circles/[BZOJ2178]圆的面积并 题目大意: 求\(n(n\le1000)\)个圆的面积并. 思路: 对于一个\( ...

  9. PAT Basic 1008

    1008 数组元素循环右移问题 (20 分) 一个数组A中存有N(>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(≥0)个位置,即将A中的数据由(A​0​​A​1​​⋯A​N ...

  10. 【织梦dedecms安全设置】dedecms如何防止被黑?dedecms被黑了怎么办?

    [织梦dedecms安全设置]dedecms如何防止被黑?dedecms被黑了怎么办?010-63495805很多所谓的“黑客”都是用工具来扫描入侵,厉害点的人是不屑来黑我们的小网站的,所以我们一般做 ...