淺議NetMQ常見模式和消息加密機(jī)制
文末本文轉(zhuǎn)載自微信公眾號「DotNET技術(shù)圈」,作者鄒溪源。轉(zhuǎn)載本文請聯(lián)系DotNET技術(shù)圈公眾號。
概述
在傳統(tǒng)企業(yè)級開發(fā)中,消息隊列機(jī)制已經(jīng)成為一種非常常見的技術(shù)實現(xiàn)手段,而基于NetMQ則看起來有點像一朵“奇葩”,看起來從名字似乎是一個消息隊列(Message Quene),但事實上更多的卻是一個類似于socket機(jī)制的消息庫。它雖然提供了消息隊列的能力,但又與傳統(tǒng)消息隊列中間件如kafka、rabbitmq等有一定的區(qū)別。
不過,不管它是啥,它提供的一些類似于消息隊列的機(jī)制,使得開發(fā)者能夠快速在項目中使用起來,例如類似于發(fā)布訂閱模式、推拉模式等機(jī)制,接入簡便,功能也挺強(qiáng)大。而且當(dāng)如果我們要實現(xiàn)消息加密時,還可能通過一些簡單的操作實現(xiàn),例如我們可以選擇對內(nèi)容進(jìn)行Rsa加密,或者也許還有其他的實現(xiàn)方法?
TL;DR:本文首先介紹NETMQ及其常用的使用模式,進(jìn)而討論如何基于NETMQ實現(xiàn)消息的加密傳輸機(jī)制。
NetMq簡介和基本特性
ZeroMQ
NETMQ是一種輕量級的消息隊列組件,是著名的ZeroMQ的重要成員。2010年,AMQP的最初設(shè)計者Pieter Hintjens帶領(lǐng)其團(tuán)隊退出了該開源項目,并發(fā)起成立了ZeroMQ這個新的消息庫,并發(fā)展至今。Pieter Hintjens 后由于膽管癌復(fù)發(fā),于2016年接受了安樂死。
在ZeroMQ的官方網(wǎng)站中,其介紹到ZeroMQ看起來似乎是一個消息隊列框架,實際上更像一個并發(fā)處理框架。它除了提供了多種消息隊列機(jī)制(如Pub-Sub、Pull-Push、Dealer、XPub-XSub機(jī)制)外,更是為開發(fā)者提供了跨多種傳輸能力的套接字,它不僅適用于進(jìn)程間的消息傳輸,也同樣適用于進(jìn)程內(nèi)、TCP和多播的傳輸機(jī)制,基于其提供的框架,開發(fā)者能快速的實現(xiàn)原子消息的傳輸能力。ZeroMQ的輕量級體現(xiàn)在其框架靈活簡單,性能優(yōu)異,無需依賴外部組件,即可輕松實現(xiàn)優(yōu)秀的性能。它也支持異步I/O的傳輸機(jī)制,可為多核應(yīng)用程序提供擴(kuò)展,且能成為集群部署的核心傳輸組件。
ZeroMQ提供了多種語言實現(xiàn),參見其官方網(wǎng)站,包括C語言,C#,Java等主流后端語言,都支持良好,同樣,也支持包括Go、Node.JS等最近比較熱門的新興語言。ZeroMQ自然也支持不同語言間的數(shù)據(jù)傳輸,使其可以成為跨語言傳輸?shù)囊环N消息協(xié)議。
ZeroMQ的Zero,代表一種極簡文化,可以代表零代理層(與Mqtt等隊列機(jī)制不同,ZeroMQ提供的是一種無代理層的隊列機(jī)制),零延遲,零成本和零管理。ZeroMQ致力于打造極簡的通信組件,通過消除組件的復(fù)雜性來提升其功能應(yīng)用效果。
NETMQ和ClrZmq
對于C#開發(fā)者來說,可以使用NetMQ和ClrZmq兩種不同的方式來獲得ZeroMQ的魔力,前者是基于C#語言原生實現(xiàn)的ZeroMQ通信協(xié)議,后者則是通過C#調(diào)用基于C語言實現(xiàn) 的Libzmq庫來使用。
相對而言,前者可能更受歡迎。NETMQ也同樣繼承了ZeroMQ的優(yōu)雅性能和輕量化,開發(fā)者可通過Nuget下載NetMQ的的組件,通過幾行代碼就可以集成消息隊列和套接字傳輸能力。如圖所示,NetMQ獲得了約175w的下載量,算是一個比較受歡迎的基礎(chǔ)組件。
而同樣在nuget上,ClrZmq的下載量則遠(yuǎn)遠(yuǎn)少于NetMQ,僅僅8w多的下載量,可能說明它只是一種小眾框架吧。值得一提的是,ClrZmq需要根據(jù)構(gòu)建平臺來選擇不同的架構(gòu)。
NETMQ的組成部分
截止本文撰寫時,NETMQ的版本為4.0.1.6,作為輕量級組件的一個評判標(biāo)準(zhǔn),依賴項復(fù)雜度也是個重要指標(biāo),而NetMQ只依賴了AsyncIO、NaCI.NET、System.ServiceModel.Primitives、System.Threading.Tasks.Extension、System.ValueTuple五個組件,算是名副其實,此處重點介紹兩個非System開頭的組件。
AsyncIO:該組件是一個高性能的異步的消息套接字庫,事實上在Nuget上,該消息庫比NetMQ更受歡迎,基于該組件,可減少套接字開發(fā)的成本。
NaCI:該組件是一個加密組件,實現(xiàn)了包括Curve25519x、Salsa20、Poly1305加密算法。Curve25519是一種橢球曲線加密算法,被設(shè)計用于橢圓曲線迪菲-赫爾曼(ECDH)密鑰交換方法。Salsa20是一種流加密算法。Poly1305是一種消息認(rèn)證碼,可用于檢測消息的完整性和驗證消息的真實性,現(xiàn)常在網(wǎng)絡(luò)安全協(xié)議(SSL/TLS)中與salsa20或ChaCha20流密碼結(jié)合使用。這三種算法都是由密碼專家丹尼爾·J·伯恩斯坦設(shè)計的加密算法。
這兩個組件都是由NETMQ的創(chuàng)建者somdoron[1](Doron Somech)創(chuàng)建,并引入到NETMQ中。
官方網(wǎng)站
NETMQ官方網(wǎng)站地址為https://netmq.readthedocs.io/,該網(wǎng)站提供了較為完整的學(xué)習(xí)示例,開發(fā)者可參考該示例快速學(xué)會該組件的用法。
常見模式實現(xiàn)
NETMQ提供了多種消息通信機(jī)制,例如發(fā)布訂閱模式,推拉模式,
發(fā)布訂閱模式(Pulish-Subscriber Pattern)
簡介
發(fā)布-訂閱是一種消息傳遞模式,其中消息的發(fā)送者(稱為發(fā)布者)不會將消息編程為直接發(fā)送給特定的接收者(稱為訂閱者)。發(fā)布的消息按照主題進(jìn)行特征化,作為發(fā)布者事先不用知道可能有哪些訂閱者(如果有)。
類似地,訂閱者可訂閱多個主題,也可只訂閱一個主題。訂閱者也同樣無需關(guān)注發(fā)布者是否真實存在,不過由于ZeroMQ本身沒有代理層,且需要綁定服務(wù)端端口,事實上看起來似乎必須給定發(fā)布者。但由于ZeroMQ本身也可以作為一種微服務(wù)架構(gòu)的基礎(chǔ)設(shè)施[2],實際上也可以通過一些機(jī)制,例如消息代理,地址代理,DNS網(wǎng)關(guān)如ZeroConf,Gossip協(xié)議等機(jī)制,將發(fā)布者隱藏在消息網(wǎng)關(guān)背后,從而使得訂閱者無需關(guān)注發(fā)布者具體在哪里。
代碼示例
該需要首先創(chuàng)建一個發(fā)布者,并通過主題的形式發(fā)布消息。
- class Program
- {
- private static string _address = "";
- static void Main(string[] args)
- {
- Console.WriteLine("Hello World!");
- _address = "tcp://127.0.0.1:5556"; //設(shè)置端口
- var task = Task.Factory.StartNew(async() =>
- {
- await BeginPublisherAsync();
- });
- var taskSubScriber = Task.Factory.StartNew(() =>
- {
- BeginSubscriberSocket();
- });
- while(Console.ReadKey().Key!=ConsoleKey.Escape);
- }
- /// <summary>
- /// 啟動消息發(fā)布
- /// </summary>
- /// <returns></returns>
- private static async Task BeginPublisherAsync()
- {
- using (var publisher = new PublisherSocket())
- {
- publisher.Bind(_address); //綁定端口
- while (true)
- {
- publisher
- .SendMoreFrame("DotNET技術(shù)圈") // Topic
- .SendFrame("test"); // Message
- await Task.Delay(TimeSpan.FromSeconds(1));
- }
- }
- }
- /// <summary>
- /// 訂閱消息
- /// </summary>
- private static void BeginSubscriberSocket()
- {
- using (var subscriber = new SubscriberSocket())
- {
- subscriber.Connect(_address);
- subscriber.SubscribeToAnyTopic();
- while (true)
- {
- var topic = subscriber.ReceiveFrameString();
- var msg = subscriber.ReceiveFrameString();
- Console.WriteLine("收到消息: {0} {1}", topic, msg);
- }
- }
- }
- }
在上述代碼中,發(fā)布者綁定了tcp://127.0.0.1:5556端口,并通過同步阻塞的方式,發(fā)布主題為Topic的消息內(nèi)容。也可以指定主機(jī)的固定ip地址來進(jìn)行消息發(fā)布,還能通過inproc://inproc-demo的方式進(jìn)行進(jìn)程內(nèi)通信。
- using var subscriber = new SubscriberSocket()
- subscriber.Connect("tcp://127.0.0.1:5556");
- subscriber.Subscribe("TopicA"); //訂閱到TopicA主題,也可通過SubscribeToAnyTopic訂閱所有主題,也可通過UnSubcribe取消訂閱相關(guān)主題
- while (true)
- {
- var topic = subscriber.ReceiveFrameString();
- var msg = subscriber.ReceiveFrameString();
- Console.WriteLine("From Publisher: {0} {1}", topic, msg);
- }
請求響應(yīng)模式(Request-Response Pattern)
請求響應(yīng)模式也是NETMQ眾多消息模式中最為簡單的一種模式,這種模式實際上有點像http協(xié)議,可通過一問一答的同步阻塞的模式進(jìn)行消息的應(yīng)答,當(dāng)然,發(fā)送HTTP請求我們也可以不必接收響應(yīng),NETMQ的請求響應(yīng)模式也同樣如此。
示意圖
- private static void BeginResponseSocket()
- {
- using var responseSocket = new ResponseSocket(_address);
- string request=responseSocket.ReceiveFrameString();
- responseSocket.SendFrame("Hello DotNET技術(shù)圈");
- }
- private static async Task BeginRequestSocketAsync()
- {
- using var requestSocket = new RequestSocket();
- requestSocket.Connect(_address);
- while (requestSocket.TrySignalOK())
- {
- try
- {
- requestSocket.TrySendFrame("Hallo I am DotNET技術(shù)圈碼農(nóng)");
- requestSocket.TrySendFrame("Hallo I am DotNET技術(shù)圈碼農(nóng)"); ---這里會引發(fā)錯誤。。
- }
- catch(Exception ex)
- {
- Console.Out.WriteLine(ex);
- }
- await Task.Delay(1000);
- }
- }
由于該模式的同步阻塞特性,如果同時發(fā)送兩條消息,可能會觸發(fā)NETMQ重復(fù)發(fā)送異常,如:
推拉模式
推拉模式與我們傳統(tǒng)意義上理解的類似于手機(jī)推送的模式有一些區(qū)別,ZeroMQ中說該模式主要將消息下發(fā)到提供了一組Push-Pull的套接字,實現(xiàn)消息下發(fā)。
值得一提的是,即便的同為ZeroMQ模式下不同語言的版本,對于相同模式的說明,文字描述也不盡相同,例如,在NetMQ的開發(fā)者文檔中,
Well a PushSocket is normally used to push to a PullSocket, whilst the PullSocket will pull from a PushSocket. Sounds obvious right!
PushSocket 負(fù)責(zé)把消息推給PullSocket,同樣PullSocket負(fù)責(zé)從PushSocket 拉消息。
這樣的說明似乎什么都說了,但又似乎啥都沒說,看看其他語言的實現(xiàn),例如基于Python的PyZmq中,其描述為這樣:
Push and Pull sockets let you distribute messages to multiple workers, arranged in a pipeline. A Push socket will distribute sent messages to its Pull clients evenly. This is equivalent to producer/consumer model but the results computed by consumer are not sent upstream but downstream to another pull/consumer socket.
推拉模式允許你基于通過管道的機(jī)制實現(xiàn)消息分發(fā)給多個工作者。單個PushSocket分發(fā)會將消息均勻的分發(fā)給其Pull客戶端。這樣的操作等效于生產(chǎn)者-消費者模型,但消費者計算的結(jié)果不是向上發(fā)送,而是向下游發(fā)送到另一個拉/消費者套接字。
兩種不同的實現(xiàn),在描述上區(qū)別還是顯著不同,通過兩者的對比,我們可以這樣理解:Push-Pull模式下,兩者都可以互為服務(wù)端或客戶端,但無論如何,其消息都是單向傳輸?shù)?。消息總是沿著管道向下流動,沿著我們設(shè)計的方向傳輸,實現(xiàn)消息在不同節(jié)點間的負(fù)載均衡。
例如,可以實現(xiàn)如下的效果,通過一個Ventilator來生產(chǎn)數(shù)據(jù),通過多個Pull來拉取數(shù)據(jù),進(jìn)而實現(xiàn)數(shù)據(jù)向下流動,可以參考NetMq官方文檔來實現(xiàn)該代碼。
基于推拉模式,可以設(shè)計非常負(fù)責(zé)的業(yè)務(wù)模型,例如類似于MapReduce的數(shù)據(jù)處理器[3]就是一個這樣的教學(xué)工具。(當(dāng)然,該工具只是一個演示ZeroMQ模式實現(xiàn)的分布式計算的Demo,可能不適合作為生產(chǎn)用途)。
代碼示意
本示例中,僅僅簡單介紹Push-Pull的用法,暫不涉及復(fù)雜的模式。
- private static async Task BeginPushSocketAsync()
- {
- using var pushSocket = new PushSocket(_address);
- while (true)
- {
- pushSocket.SendFrame("Hello Clients");
- await Task.Delay(1000);
- }
- }
- private static async Task BeginPullSocketAsync()
- {
- using var pullSocket = new PullSocket(_address);
- while (true)
- {
- string message = pullSocket.ReceiveFrameString();
- Console.WriteLine(message);
- await Task.Delay(1000);
- }
- }
netmq加密傳輸機(jī)制實現(xiàn)
當(dāng)我們使用NetMQ進(jìn)行消息傳輸時,上述示例均沒有對消息進(jìn)行任何加密處理,這種策略可能導(dǎo)致一些不可控的安全性風(fēng)險,例如在開發(fā)基于NetMQ的聊天室功能時,發(fā)布的信息若未采取任何加密措施,事實上可能意味著消息是以廣播的形式對外發(fā)布,從而會造成某些隱私信息泄漏?;蛘?,如果你需要向外Publish某些消息,未授權(quán)的訂閱者訂閱了你的數(shù)據(jù),雖然可能數(shù)據(jù)中不包含直接的隱私數(shù)據(jù),但同樣可能會引起你的不適。
因此,從安全性的角度來說,無論你計劃基于NetMQ實現(xiàn)何種場景,事實上可能都得考慮以盡可能安全的形式“發(fā)布”你的消息。目前我們可通過三種方式來實現(xiàn)消息的加密傳輸功能。第一種是使用基于Tls協(xié)議的NetMQ.Security組件,一種是基于非對稱密鑰算法,如RSA加密算法,還有一種是基于ZeroMQ所提供的兩種加密方式,ECC橢球曲線加密算法和Z85加密算法,以對稱密鑰的方式。
基于Tls的NetMq.Security?
NetMQ.Security[4]也是由NetMQ的主要貢獻(xiàn)者somdoron開發(fā)的組件,目前該組件處于不活躍的狀態(tài),截至目前僅有5次更新,上一次更新依然是4年前,通過一些早期帖子,作者Doron Somech也同樣不認(rèn)為該組件可以在生產(chǎn)環(huán)境下使用[5](??),所以事實上可能不太適合作為專業(yè)團(tuán)隊的技術(shù)選型。
目前比較詳細(xì)的介紹來自杰哥很忙[6],且優(yōu)秀的杰哥對fork了該組件的代碼[7],并開發(fā)了許多功能,由于主干倉庫已經(jīng)塵封太久了,開發(fā)者有興趣可以參詳參詳。
使用時,我們可通過Nuget下載由NetMQ官方發(fā)布的組件,不過,似乎下載量有點慘淡,那么,此處就不再贅述了。。。。
非對稱密鑰算法-Rsa加密
對于文本來說,使用Rsa這種非對稱算法族進(jìn)行加密是一種非常常見的選擇,RSA是由羅納德·李維斯特[8](Ron Rivest)、阿迪·薩莫爾[9](Adi Shamir)和倫納德·阿德曼[10](Leonard Adleman)在1977年一起提出的,當(dāng)時他們?nèi)硕荚诼槭±砉W(xué)院[11]工作。RSA 就是他們?nèi)诵帐祥_頭字母拼在一起組成的。
RSA算法的核心是極大整數(shù)做因數(shù)分解,換言之,對一極大整數(shù)做因式分解越困難,RSA算法越可靠。目前傳統(tǒng)計算機(jī)只能破解較為簡單的RSA密鑰,如果使用的密鑰長度足夠長,理論上用RSA加密的信息也很難以被破解。在RSA算法中,密鑰由私鑰和公鑰組成。由私鑰負(fù)責(zé)對內(nèi)容進(jìn)行解密,并用公鑰進(jìn)行加密。分配公鑰的過程必須足夠安全,若被中間人攻擊,則可能導(dǎo)致公鑰失效。
影響RSA密鑰安全性的要素首先是其密鑰長度,目前推薦的RSA算法公鑰長度為2048位。其次是RSA密鑰的填充模式,共有三種填充模式,RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_NO_PADDING。填充技術(shù)實現(xiàn)的不好,RSA也不會安全,應(yīng)盡量選擇最安全的填充模式,例如RSA_PKCS1_PADDING。
原因如下[12]:
1.RSA加密是確定的,即給定一個密鑰,特定明文總會映射到特定的密文。攻擊者可以根據(jù)密文中統(tǒng)計信息獲取明文的一些信息。
2.填充技術(shù)如果比較弱,那么較小的明文和小型公開指數(shù)e將易于受到攻擊。
3.RSA有個特性叫做延展性,如果攻擊者可以將一種密文轉(zhuǎn)換為另一種密文,這種新密文會導(dǎo)致對明文的轉(zhuǎn)換變得可知,這種特性并沒有解密明文,而是以一種可預(yù)測的方式操縱了明文,比如:銀行交易系統(tǒng)中,攻擊者根據(jù)新密文,直接去修改原密文中金額的數(shù)據(jù),可以在用戶和接受方無法感知的情況下進(jìn)行修改。
在RSA算法中提供了以下功能提供[13]:
- 密鑰對生成:生成隨機(jī)私鑰(通常大小為 1024-4096 位)和相應(yīng)的公鑰。
- 加密:使用公鑰加密秘密消息(范圍為 [0...key_length] 的整數(shù)),并使用秘密密鑰將其解密。
- 數(shù)字簽名:簽署消息(使用私鑰)并驗證消息簽名(使用公鑰)。
- 密鑰交換:安全地傳輸一個秘密密鑰,用于以后的加密通信。
RSA 可以使用不同長度的密鑰:1024、2048、3072、4096、8129、16384 甚至更多位的密鑰。3072 位及以上的密鑰長度被認(rèn)為是安全的。更長的密鑰提供更高的安全性,但消耗更多的計算時間,因此需要在安全性和速度之間進(jìn)行權(quán)衡。很長的 RSA 密鑰(例如 50000 位或 65536 位)對于實際使用來說可能太慢,例如密鑰生成可能需要幾分鐘到幾個小時。
網(wǎng)上也有基于RSA進(jìn)行NetMQ進(jìn)行消息加密的示例[14],可供參考。其核心流程為,在進(jìn)行消息發(fā)送時,使用RSA公鑰進(jìn)行加密,
- MsgObject sendmsg = EventQueue.Dequeue ( ) ;
- sendmsg.Content = RSAEncryption.RSAEncrypt(sendmsg.Content);
- sendmsg.MachineName= msg.MachineName;
- SendMessageQueue.Enqueue(sendmsg) ;
并在客戶端接收到消息后,對正文進(jìn)行RSA解密,解密代碼略。
使用對稱密鑰加密算法-Ecc加密算法進(jìn)行消息加密
RSA算法雖好,但由于私鑰由客戶端管理,公鑰由服務(wù)端管理,且RSA必須密鑰位數(shù)足夠長才安全,例如2048位,使用這么長的密鑰進(jìn)行加密時間開銷也令人吃不消的,有沒有一種更簡單、快速的算法來實現(xiàn)呢?
使用AES算法?
我們或許會想到AES算法,例如AES256算法這種“對稱密鑰加密算法[15]”。在“對稱密鑰加密算法”中,加密和解密使用秘密密鑰或密碼短語(從中派生出密鑰)。
該秘密密鑰用于加密和解密數(shù)據(jù),通常是128位或256位,并被稱為“加密密鑰”。有時它以十六進(jìn)制或 base64 編碼的整數(shù)形式給出,或者通過密碼到密鑰派生方案派生,當(dāng)輸入數(shù)據(jù)被加密時,它被轉(zhuǎn)換為加密的密文,當(dāng)密文被解密時,它被轉(zhuǎn)換回原始輸入數(shù)據(jù)。
通常,對稱加密過程使用一系列步驟,涉及不同的加密算法:
密碼到密鑰派生算法(如 Scrypt 或 Argon2):允許使用密碼而不是密鑰,并使密碼破解變得困難而緩慢。
塊到流密碼轉(zhuǎn)換算法(塊密碼模式如CBC或CTR )+消息填充算法如PKCS7 (在某些模式下):允許使用塊密碼算法(如AES)加密任意大小的數(shù)據(jù)。
塊密碼算法(如AES ):使用密鑰安全地加密固定長度的數(shù)據(jù)塊。
消息認(rèn)證算法(如HMAC ):檢查解密后得到的結(jié)果是否與加密前的原始消息匹配。
NETMQ的原生解決方案?
不過上述AES加密算法實質(zhì)上也需要開發(fā)者手工處理消息體,存在的內(nèi)存開銷和時間可能對于用戶來說依然無法接受,或許最好的辦法依然是基于NETMQ框架來入手看看是否有什么“原生”的解決方案。
所幸ZeroMQ在設(shè)計之初就已經(jīng)將安全作為其認(rèn)為非常重要的一個方面,在這篇博客[16]中,ZeroMQ提到了其對于安全層的目標(biāo),包括:
- 它使用起來必須非常簡單,而且不可能出錯。復(fù)雜性是密碼學(xué)的第一大風(fēng)險和第一大漏洞。每一個額外的選項都是一種出錯的方式,最終導(dǎo)致一個不安全的系統(tǒng)。
- 對于實際工作,它必須足夠快。如果安全性使系統(tǒng)變得太慢而無法使用,人們就會將其關(guān)閉,因為今天能夠工作的務(wù)實需求勝過明天被入侵的風(fēng)險。
- 它必須基于標(biāo)準(zhǔn)化協(xié)議,以便任何團(tuán)隊都可以重新實施、獨立驗證并在軟件堆棧之外進(jìn)行改進(jìn)。
- 等等。
并從2013年起,在ZeroMQ版本(4.0.0)中就已經(jīng)引入了安全架構(gòu)設(shè)計,包括:
- 一種新的有線協(xié)議ZMTP 3.0[17],為所有 ZeroMQ 連接添加了安全握手。
- 一種新的安全協(xié)議CurveZMQ[18],它通過 TCP 連接在兩個 ZeroMQ 對等點之間實現(xiàn)“完美的前向安全”。我將在下面解釋 CurveZMQ。
- ZMTP 的一組安全機(jī)制:NULL、PLAIN 和 CURVE,每個機(jī)制都由它們自己的 RFC 描述。NULL 本質(zhì)上是我們之前所擁有的。PLAIN 允許簡單的用戶名和密碼驗證。CURVE 實現(xiàn)了 CurveZMQ 協(xié)議。、
- 等等。
在ZeroMQ中集成的橢球曲線算法為Curve25519[19] ,目前,在我們所使用的NetMQ中也同樣集成了該算法。在搞清楚原理后,我們再來使用該算法,發(fā)現(xiàn)一切就變得非常簡單明了了。
- var serverPair = NetMQ.NetMQCertificate.CreateFromSecretKey(UTF8Encoding.UTF8.GetBytes(”這里是密鑰“));;
- using var server = new PublishSocket();
- server.Options.CurveServer = true;
- server.Options.CurveCertificate = serverPair;
- server.Bind($"tcp://127.0.0.1:55367");
- using (var server = new SubscriberSocket())
- {
- var cert = NetMQ.NetMQCertificate.CreateFromSecretKey(UTF8Encoding.UTF8.GetBytes(”這里是密鑰“));
- var curveServerCertificate = serverPair;
- var clientCertificate = new NetMQCertificate(); ---這里是客戶端密鑰,
- server.Options.CurveServerCertificate = curveServerCertificate; ---這里是使用服務(wù)端密鑰
- server.Options.CurveCertificate = clientCertificate; ---這里是客戶端密鑰
- }
結(jié)語
本文對NetMQ進(jìn)行了簡單的概述,包括其常見模式和加密傳輸機(jī)制,開發(fā)者若有興趣,可通過NetMQ官網(wǎng)獲得更多學(xué)習(xí)資料。如果開發(fā)者加密算法感興趣,還可以通過這個網(wǎng)站(https://cryptobook.nakov.com)讀到許多有關(guān)加密的基礎(chǔ)知識。
References
[1] somdoron: https://github.com/somdoron
[2] 微服務(wù)架構(gòu)的基礎(chǔ)設(shè)施: https://zguide.zeromq.org/docs/chapter8/
[3] 類似于MapReduce的數(shù)據(jù)處理器: https://github.com/sdiehl/kaylee
[4] NetMQ.Security: https://github.com/NetMQ/NetMQ.Security
[5] 同樣不認(rèn)為該組件可以在生產(chǎn)環(huán)境下使用: https://groups.google.com/g/netmq-dev/c/3tcsLvxUWgc
[6] 杰哥很忙: https://www.cnblogs.com/Jack-Blog/p/9015783.html
[7] 該組件的代碼: https://github.com/GuojieLin/NetMQ.Security
[8] 羅納德·李維斯特: https://zh.wikipedia.org/wiki/羅納德·李維斯特
[9] 阿迪·薩莫爾: https://zh.wikipedia.org/wiki/阿迪·薩莫爾
[10] 倫納德·阿德曼: https://zh.wikipedia.org/wiki/倫納德·阿德曼
[11] 麻省理工學(xué)院: https://zh.wikipedia.org/wiki/麻省理工學(xué)院
[12] 原因如下: https://blog.csdn.net/makenothing/article/details/88429511
[13] 以下功能提供: https://cryptobook.nakov.com/asymmetric-key-ciphers/the-rsa-cryptosystem-concepts
[14] 消息加密的示例: https://blog.actorsfit.in/a?ID=01400-85ae6267-6c93-41e3-b06b-5d9792a422ba/
[15] 對稱密鑰加密算法: https://cryptobook.nakov.com/symmetric-key-ciphers
[16] 這篇博客: https://jaxenter.com/using-zeromq-security-part-1-119346.html
[17] ZMTP 3.0: http://zmtp.org/
[18] CurveZMQ: http://curvezmq.org/
[19] Curve25519: http://cr.yp.to/ecdh.html