實用的物聯網加密在濃縮咖啡esp8266

eSpressif esp8266芯片組是三美元的“事物互聯網”發展委員會的經濟現實。根據流行的自動固件建築工地Nodemcu-Builds,在過去的60天內有13,341個自定義固件為該平台構建。其中,只有19%的SSL支持,10%包括加密模塊。

我們往往批評IOT部門缺乏安全,經常覆蓋殭屍網絡和其他攻擊,但我們將把我們的項目置於我們需求的相同標準嗎?我們會停下來識別問題,還是我們可以成為解決方案的一部分?

本文將專注於使用運行Nodemcu固件的流行ESP8266芯片對MQTT協議應用AES加密和哈希授權功能。我們的目的不是提供複製/粘貼靈棍,而是逐步完成流程,沿途識別挑戰和解決方案。結果是一個系統,該系統是端到端加密和認證,防止沿途竊聽,並欺騙有效數據,而無需依賴於SSL。

我們知道還有更強大的平台,可以輕鬆地支持SSL(例如Raspberry PI,Orange Pi,FriendlyArm),但讓我們從我們大多數人躺在最便宜的硬件上開始,以及適合我們許多項目的協議。如果您需要,AES是您可以在AVR上實施的東西。

理論

MQTT是一個輕量化的消息傳遞協議,在TCP / IP之上運行,通常用於IOT項目。客戶端設備訂閱或發佈到主題(例如,傳感器/溫度/廚房),這些消息由MQTT代理中繼。有關MQTT的更多信息,可在其網頁或我們自己的入門系列中提供。

MQTT協議沒有超出用戶名/密碼身份驗證的任何內置安全功能,因此通過SSL對網絡進行加密和認證是通用的。但是,SSL對ESP8266和啟用時,SSL可能更加苛刻,因此您將留下更少的內存為您的應用程序。作為輕量級替代方案,您只能加密已發送的數據有效負載,並使用會話ID和散列函數進行身份驗證。

直接執行此操作的是使用Lua和Nodemcu加密模塊,包括支持CBC模式中AES算法以及HMAC哈希函數。使用AES加密正確需要三件事來生成密文:消息,密鑰和初始化向量(IV)。消息和鍵是簡單的概念,但初始化向量值得一些討論。

當您在具有靜態鍵的AES中對消息進行編碼時,它將始終產生相同的輸出。例如,用key“1234567890abcdef”加密的消息“UsernamePassword”可能會產生“E40D86C04D723AFF”等結果。如果使用相同的密鑰和消息再次運行加密,則會獲得相同的結果。這為您打開了幾種常見類型的攻擊,特別是模式分析和重放攻擊。

在模式分析攻擊中,您可以使用給定數據的知識始終產生相同的密文來猜測不同消息的目的或內容而沒有實際知道密鑰。例如,如果在所有其他通信之前發送消息“E40D86C04D723AFF”,則可能會迅速猜測它是登錄。簡而言之,如果登錄系統是簡單的,則發送該數據包(重播攻擊)可能足以將自己標識為授權用戶,並且混亂隨之而來。

IVS使模式分析更加困難。 IV是與修改結束密文結果的密鑰一起發送的數據。顧名思義,它在數據進入之前初始化加密算法的狀態。對於發送的每條消息,IV需要不同,以便重複的數據加密到不同的密文,以及一些密碼(如AES-CBC)需要它是不可預測的 – 實現這一目標的實用方法只是為了每次隨機調整它。 IVS不必保密,但典型以某種方式混淆它們是典型的。

雖然這可以防止模式分析,但它沒有幫助重播攻擊。例如,重傳給定的一組加密數據仍將重複結果。為防止,我們需要驗證發件人。我們將使用公共,偽偽裝生成的每條消息的會話ID。通過發佈到MQTT主題,可以由接收設備生成此會話ID。

防止這些類型的攻擊在幾種常見用例中是重要的。互聯網控制的爐灶存在,拋開效用,如果他們沒有使用不安全的命令,那將是很好的。其次,如果我是從一百個傳感器的數據記錄,我不希望任何人用垃圾填充我的數據庫。

實用加密

在Nodemcu上實施上述需要一些努力。您將需要編譯的固件,除了任何其他人之外,還包括“加密”模塊您的申請。不需要SSL支持。

首先,讓我們假設您與以下內容的內容連接到MQTT代理。您可以將其實現為來自加密學的單獨功能,以保持清潔。客戶端訂閱了SessionID頻道,該頻道適當地發布了很長的偽隨機會話ID。您可以加密它們,但這不是必需的。

1
2
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
m = mqtt.client(“ClientId”,120)

M:連接(“myserver.com”,1883,0,
功能(客戶)
打印(“連接”)
客戶:訂閱(“mytopic / sessionid”,0,
功能(客戶)打印(“訂閱成功”)結束
的)
結尾,
功能(客戶,原因)
打印("失敗原因:“..原因)
結尾
的)

M:ON(“消息”,函數(客戶端,主題,SessionID)結束)

繼續前進,節點ID是幫助識別數據源的便捷方式。您可以使用您希望的任何字符串:nodeId = node.chipid()。

然後,我們設置了靜態初始化向量和密鑰。這僅用於使用每條消息發送的隨機初始化向量,不用於任何數據。我們還為數據選擇一個單獨的鍵。這些鍵是16位十六進制,只需用您的方式替換它們。

最後,我們將需要一個密碼,以便哈希函數我們稍後使用。一串合理的長度很好。

1
2
3.
4.
staticiv =“abcdef2345678901”abcdef2345678901“
IVKEY =“2345678901ABCDEF”
datakey =“0123456789abcdef”
passphrase =“myPassphrase”。

我們還假設您有一些數據來源。對於此示例,它將是從ADC讀取的值。 DATA = ADC.READ(0)

現在,我們生成偽隨機初始化向量。對於偽隨機數函數,一個16位十六進制號碼太大,因此我們將其生成兩半(16 ^ 8.1減1)並連接它們。

1
2
3.
4.
5.
half1 = node.random(4294967295)
half2 = node.random(4294967295)
i = string.format(“%8x”,半)
v = string.format(“%8x”,harm2)
IV = I .. V

我們現在可以運行實際加密。在這裡,我們正在加密當前初始化向量,節點ID和一條傳感器數據。

1
2
3.
Encrypted_iv = crypto.encrypt(“AES-CBC”,Ivkey,IV,Staticiv)
加密_NodeDID = Crypto.encrypt(“AES-CBC”,Datakey,NodeID,IV)
加密_data = crypto.encrypt(“aes-cbc”,datakey,data,iv)

現在我們應用哈希函數進行身份驗證。首先,我們將NodeID,IV,數據和會話ID組合成一個消息,然後使用我們之前定義的密碼來計算HMAC SHA1哈希。我們將其轉換為Hex,使其對任何調試更具人性化。

1
2
fullmessage = nodeid .. IV ..數據..會話方式
hmac = crypto.tohex(Crypto.hmac(“sha1”,fullmessage,passphrase))

既然,既有加密和認證檢查都已到位,我們可以將所有這些信息放在某些結構中並發送它。在這裡,我們將使用逗號分隔值,因為它方便:

1
2
payload = table.concat({encrypted_iv,eid,data1,hmac},",“)
M:發布(“yourmqtttttttttopic”,有效載荷,2,1,功能(客戶端)p =“發送”打印(P)結束)

當我們在實際的nodemcu上運行上面的代碼時,我們會得到這樣的輸出:

1d54dd1af0f75a91a00d4dcd8f4ad28d,
D1A0B14D187C5ADFC948DFD77C2B​​2EE5,
564633A4A053153BCBD6ed25370346D5,
C66697DF7E7D467112757C841BFB6BCE051D6289

總之,加密程序如下(用於清晰度的MQTT部分):

1
2
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
nodeId = node.chipid()
staticiv =“abcdef2345678901”abcdef2345678901“
IVKEY =“2345678901ABCDEF”
datakey =“0123456789abcdef”
passphrase =“myPassphrase”。

DATA = ADC.READ(0)
half1 = node.random(4294967295)
half2 = node.random(4294967295)
i = string.format(“%8x”,半)
v = string.format(“%8x”,harm2)
IV = I .. V

Encrypted_iv = crypto.encrypt(“AES-CBC”,Ivkey,IV,Staticiv)
加密_NodeDID = Crypto.encrypt(“AES-CBC”,Datakey,NodeID,IV)
加密_data = crypto.encrypt(“aes-cbc”,datakey,data,iv)
fullmessage = nodeid .. IV ..數據..會話方式
hmac = crypto.tohex(Crypto.hmac(“sha1”,fullmessage,passphrase)))
payload = table.concat({encrypted_iv,encrypted_nodeid,encrypted_data,hmac},",“)

解密

現在,您的MQTT經紀人不知道或關心數據加密,它只通過它。因此,您的其他MQTT客戶端訂閱主題將需要知道如何解密數據。在Nodemcu上,這很容易。只需通過逗號將所接收的數據拆分為字符串,並執行以下操作。注意此目端將生成會話ID所以已經知道它。

1
2
3.
4.
5.
6.
7.
8.
9.
10.
staticiv =“abcdef2345678901”abcdef2345678901“
IVKEY =“2345678901ABCDEF”
datakey =“0123456789abcdef”
passphrase =“myPassphrase”。

IV = crypto.decrypt(“AES-CBC”,IVKEY,ENCRYPTED_IV,STATIDIV)
nodeId = crypto.decrypt(“AES-CBC",代購,加密_NodeID,IV)
data = crypto.decrypt(“aes-cbc”,datakey,crecrypted_data,iv)
fullmessage = nodeid .. IV ..數據..會話方式
hmac = crypto.tohex(Crypto.hmac(“sha1”,fullmessage,passphrase)))

然後將接收和計算的HMAC進行比較,而無論結果如何,都會通過生成新的結果使得該會話ID無效。

再次,在Python

對於一點品種,請考慮我們如何在Python中處理解密,如果我們在同一虛擬機上作為正在分析數據或將其存儲在數據庫中的經紀人的MQTT客戶端。假設您已收到數據作為字符串“有效載荷”,從類似於Python的優秀Paho MQTT客戶端。

在這種情況下,在發送之前,它方便十六進制在Nodemcu上編碼加密數據。所以在Nodemcu上,我們將所有加密數據轉換為hex,例如:encrypted_iv = crypto.ctohex(Crypto.encrypt(“AES-CBC”,IVKEY,IV,STOTYIV))

發布隨機化的SessionID未在下面討論,但使用OS.urandom()和Paho MQTT客戶端很容易。解密處理如下:

1
2
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35
來自Crypto.Cipher Import AES
進口Binascii.
來自Crypto.Hash進口沙,HMAC

#定義所有鍵
IVKEY =’2345678901abcdef’
datakey =’0123456789abcdef’
staticiv =’abcdef2345678901′
passphrase =’mypassphrase’

#將收到的字符串轉換為列表
data = payload.split(“,”)

#提取列表項
Encrypted_iv = binascii.unhexlify(數據[0])
加密_nodeid = binascii.unhexlify(數據[1])
Encrypted_data = binascii.unhexlify(數據[2])
收到_hash = binascii.unhexlify(數據[3])

#解密初始化向量
IV_DECRYPTION_SUITE = AES.NEW(IVKEY,AES.MODE_CBC,Staticiv)
IV = IV_DECRYPTION_SUITE.DECRYPT(ENCRYPTED_IV)

#使用初始化向量解密數據
id_decryption_suite = aes.new(datakey,aes.mode_cbc,iv)
nodeId = id_decryption_suite.decrypt(加密_nodeid)
data_decryption_suite = aes.new(datakey,aes.mode_cbc,iv)
sensoldata = data_decryption_suite.decrypt(encrypted_data)

#compute哈希函數比較收到_hash
fullmessage = s.join([nodeid,iv,sensoldata,sessionid])
hmac = hmac.new(passphrase,fullmessage,sha)
computed_hash = hmac.hexdigest()

#查看docs.python.org/2/library/hmac.html如何牢固地比較散列

結束,開始

現在我們有一個系統,通過MQTT服務器向另一個ESP8266客戶端或正在運行Python的更大系統發送加密的身份驗證消息。如果你自己實施這個,仍有重要的鬆散目的是為了捆綁。鍵全部存儲在ESP8266S的閃存中,因此您需要控制對這些設備的訪問,以防止逆向工程。鍵也存儲在接收數據的計算機上的代碼中,在此處運行Python。此外,您可能希望每個客戶端都有一個不同的密鑰和密碼。這是許多秘密材料,以在必要時保持安全和可能更新。解決關鍵分佈問題是留作動機讀者的練習。

在閉幕筆記上,關於編寫涉及密碼學的文章的可怕事物之一是在互聯網上有錯誤的可能性。這是一種相當簡單的應用與HMAC的測試和真正的AES-CBC模式應用,所以它應該非常堅固。儘管如此,如果您在上面找到了任何有趣的缺點,請在評論中告知我們。

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Post

2個適用於Android2個適用於Android

保持健康的最佳卡路里計數器應用程序很難。隨著肥胖症成為一個主要的健康問題,尤其是在青少年中,維持健康飲食的需求至關重要。您可能每週要鍛煉5次,但是如果您無法控制自己的飲食並繼續嚼垃圾食品,您將永遠不會看到所希望的結果。 您應該已經知道,要看到所需的結果,您應該燃燒比消耗更多的卡路里。這可以通過健康飲食來實現。我想說的是,您不應該吃在面前的任何東西。花點時間思考您是否要吃的東西對您有好處。這是兩個最好的Android應用程序,可以幫助您這樣做。 不要錯過:追踪健康活動的前5個健身應用程序 卡路里計數器 – myfitnesspal MyFitnessPal是Android的最高和絕對最好的卡路里櫃檯。下載計數為5000萬+以及4.6星的評分足以表明這一點。它帶有您可以從卡路里櫃檯獲得的所有功能。它具有超過600萬糧的大量數據庫。也可以在跨設備上同步以滿足跨平台需求。 安裝MyFitnessPal後,它將要求一些個人細節,例如重量,身高,目標體重,日常體育鍛煉等,以計算您的日常卡路里需求。堅持下去,你會很好。它還具有基本的有氧運動和力量訓練跟踪器,其中350多個運動。該應用程序還顯示了主頁上與健康和健身有關的一系列有用的文章。您可以連接許多其他服務,例如Fitbit,Garmin,MapMyFitness,Runkeeper等,以共享其中的數據。 [Google Play url =“”/] Healthifyme減肥教練 healthifyme是另一個功能強大的卡路里櫃檯,完美地使用了其印度起源卡。印度是一個有不同文化的城市,有很多不同的美食。每個狀態都以美味而聞名。該應用程序具有超過100萬印度食品的數據庫,並且幾乎涵蓋了各地的所有內容。 healthifyme的UI是我的最愛,也許是最好的。就像MyFitnessPal一樣,該應用程序在安裝時要求提供個人詳細信息以形成卡路里攝入量。之後,它將該數字分為各個部分,即您在一頓飯中應該消耗的卡路里數量。如果您傾向於在一頓飯中吃得過分並餓死自己,那將是有價值的。 如果您選擇高級會員資格,則可以通過應用程序,語音通話和視頻通話來獲得專家製定的定制健身計劃以及實時諮詢。 必須閱讀:您應該使用的5個最佳健康與健身應用程序 最後,healthifyme還提供了一項首要的公司健康計劃,以改善員工的健康。它已將幾家享有聲望的公司裝袋,例如Cognizant,Philips,Unilever,Shell等。 [Google Play url =“”/] MyFitnessPal和healthifyme都非常好,並且在某種程度上有些相似。選擇一個人的選擇僅取決於您的個人喜好。我首先安裝了MyFitnessPal,並且從未發現任何問題以搬遷到任何其他應用程序。為了使您保持動力,這些應用程序利用遊戲化,即您可以添加好朋友並與他們競爭積分,並在排行榜上的位置更高。

Apple ID鎖定錯誤困擾著某些iOS 10 Beta 2個人Apple ID鎖定錯誤困擾著某些iOS 10 Beta 2個人

,如果任何人都需要及時的提示來安裝beta軟件,尤其是在不明確用於測試的小工具上的操作系統,那麼就在這裡。 報告已經開始浮出水面表明,在其小工具上使用iOS 10 Beta 2軟件應用程序運行的個人正在鎖定在其Apple ID中,以及與“ Apple ID鎖定錯誤”的關聯服務。 據蘋果公司的說法,當遭受該問題的個人聯繫時,原因可能是兩因素身份驗證或兩步驗證。 雖然蘋果尚未真正了解正在發生的事情,但建議iOS 10 beta 2本身或其鏈接到身份驗證的服務器之一。 並非所有具有兩因素身份驗證的人都遇到了問題,但是那些被告知蘋果目前沒有什麼可以做的。 事實證明,當您無法訪問自己的帳戶時,通常並不是您所需要的。 在這一點上,雖然目前似乎還沒有為受到影響的人進行維修,但我們只能建議任何利用iOS 10的Beta(包括最近發布的公共Beta)的任何個人,但可以禁用兩因素身份驗證。 這樣一個步驟的明顯缺點是,如果某人擁有您的密碼,劫持您的Apple ID也會容易得多,但是即使您擁有正確的憑據,這可能是有利的 。 蘋果在iOS 10上的工作將繼續進行一些Beta版本,最終在9月左右的最終版本中。 希望這樣的問題不會在今年秋天發現iOS 10的最終運輸發布中的方法! (來源:reddit) 您可能同樣喜歡檢查: iOS 10公共測試版:確切的下載以及設置理想方式 如何將iOS 10

如何在LG G3(3種方法)如何在LG G3(3種方法)

上進行屏幕截圖,您一定已經看到人們在不同的社交媒體和網站上共享手機和平板電腦的屏幕截圖。曾經有一段時間,Android用戶不得不安裝單獨的屏幕快照應用程序來捕獲其設備上的屏幕。但是,在果凍豆升級後,Android操作系統的本地配備了屏幕截圖功能,可與鑰匙組合一起使用。 您可以通過同時按功率 +音量鍵組合來在大多數Android設備上屏幕截圖。一些設備支持捕獲屏幕的多種方法 – 天然Android方法,以及來自OEM的另一種方法。 如果您擁有全新的LG G3,並且一直想知道如何在手機上捕獲屏幕截圖,那麼您將找到兩種方法。實際上,在LG G3 I上拍攝屏幕截圖就像按下物理鑰匙或刷手指一樣容易。而且,如果您已經從上一代LG設備中升級,那麼您甚至不需要閱讀我們的教程。通常,大多數Android設備上的關鍵組合方法涉及使用兩隻手按下音量和電源按鈕。由於LG G2/G3在背面具有相鄰位置的這些按鈕,因此您可以使用單個或兩個手指屏幕截圖。 如何在LG G3上拍攝屏幕截圖 方法1:使用鑰匙組合 首先,在手機上獲取屏幕要捕獲。 現在,用2個手指按下電源按鈕 +音量鍵,然後同時按它們。您也可以做到這一點:將手機握在手中,將指尖放在電源和音量下降鍵之間,以同時按下它們。快速按下,您會聽到屏幕截圖的聲音和屏幕截圖的簡短預覽。 完畢!默認情況下,所有捕獲的屏幕都保存在圖片>內部存儲上的屏幕截圖文件夾中。您的屏幕截圖也將在畫廊應用程序中顯示。 如果您想立即共享屏幕截圖,只需拉下通知面板,然後點擊屏幕截圖預覽下方的共享選項即可。 方法2:使用快速備忘錄+應用 如果您不願意使用電源和音量鑰匙組合來在LG G3上進行屏幕截圖,則有一種替代且相當簡單的方法,可以讓您用手指滑動捕獲所需的屏幕。這是您可以做到的。 轉到您要捕獲的屏幕。 將您的手指放在導航桿上的房屋(軟鍵)上,然後快速向上滑動手指。您會在屏幕上看到三個圖標(語音伴侶,Google和Quick Memo+)。 只需將指尖帶到右側的快速備忘錄+圖標即可突出顯示即可。 現在移開手指。 屏幕快照將被拍攝並顯示在屏幕上。 只需點擊頂部欄上的保存圖標,然後在提示時選擇圖庫。 如果您想在屏幕截圖上寫入/繪製某些內容,或者通過在頂欄中敲擊相應的圖標來寫入/繪製。 方法3:使用G3