【译】Ethereum Wallet in a Trusted Execution Environment / Secure Enclave
介紹
在過去的幾周里, Weeve團(tuán)隊(duì)已經(jīng)從社區(qū)中獲得了很多關(guān)于我們?nèi)绾?strong>將以太坊錢包應(yīng)用到我們的 weeveOS中的興趣 。 weeveOS是一個(gè)開源操作系統(tǒng),針對(duì)IoT-to-Ethereum進(jìn)行了優(yōu)化(在未來的版本中,我們將增加對(duì)其他區(qū)塊鏈技術(shù)的支持)應(yīng)用程序利用最先進(jìn)的安全機(jī)制來保護(hù)以太網(wǎng)錢包免受網(wǎng)絡(luò)攻擊( GitHub )。 通過WeeveOS,該項(xiàng)目旨在為區(qū)塊鏈實(shí)施安全可靠的物聯(lián)網(wǎng)神諭。
您可能會(huì)問自己,為什么有必要在可信執(zhí)行環(huán)境(TEE)中使用錢包解決方案,有時(shí)也稱為可信安全區(qū)? 錢包基本上是用于管理數(shù)字貨幣的軟件應(yīng)用程序。 由于軟件永遠(yuǎn)是網(wǎng)絡(luò)攻擊者的“簡(jiǎn)單”目標(biāo),而且這個(gè)錢包將包含您的私鑰,因此我們需要確保此軟件在最安全的環(huán)境中。 通過TEE方法,我們能夠以高度安全和可信的方式保護(hù)錢包軟件,而無需額外的硬件。 或者,換句話說,現(xiàn)在汽車,充電站,集裝箱或冰箱都可以擁有自己的物聯(lián)網(wǎng)錢包,并自主參與金融活動(dòng),如購買食品,能源或出售運(yùn)輸空間,而不存在錢包成為網(wǎng)絡(luò)盜竊的風(fēng)險(xiǎn)。
在本文中,我概述了我們?nèi)绾螌⒁蕴诲X包作為受信任的應(yīng)用程序?qū)崿F(xiàn),或者更簡(jiǎn)單地將其作為C中的錢包實(shí)現(xiàn)。在詳細(xì)介紹之前,我將簡(jiǎn)要介紹可信執(zhí)行環(huán)境的新概念,描述以太坊虛擬機(jī)( EVM)并詳細(xì)說明了如何在可信執(zhí)行環(huán)境(TEE)中生成事務(wù)。
可信執(zhí)行環(huán)境
TEE提供了一個(gè)執(zhí)行空間,可以提供比商品操作系統(tǒng)更高的安全性。 令人驚訝的安全功能包括:(1)隔離執(zhí)行,(2)安全存儲(chǔ),例如加密密鑰材料,以及(3)設(shè)備配置的遠(yuǎn)程證明,僅舉幾例。 我們的weeveOS實(shí)現(xiàn)了ARM的TEE版本。 將CPU的權(quán)限分離為安全和非安全的世界以及兩個(gè)世界中的不同中斷為我們提供了大量工具來大大提高安全性。 Trustzone可以看作是ARM的安全擴(kuò)展,就像SGX是Intel的安全擴(kuò)展。 這兩種硬件擴(kuò)展都利用(幾乎)相同的操作系統(tǒng)安全加固功能,因此僅在目標(biāo)領(lǐng)域有所不同:英特爾面向PC和服務(wù)器領(lǐng)域,而ARM則主導(dǎo)嵌入式/物聯(lián)網(wǎng)設(shè)備領(lǐng)域。 這兩種技術(shù)都有共同的程序隔離。 英特爾稱主體為Trusted Enclave,ARM將其稱為可信執(zhí)行環(huán)境。
在下文中我們堅(jiān)持使用ARM術(shù)語。 Trustzone將計(jì)算環(huán)境(例如,內(nèi)存區(qū)域,CPU權(quán)限)劃分為兩個(gè)隔離的隔離區(qū),稱為安全和非安全世界:
非安全 世界是CPU的“正?!杯h(huán)境,沒有更高的權(quán)限可用。 僅分配必要的權(quán)限和中斷以確保不可能未經(jīng)授權(quán)訪問安全世界。
Secure World是ARM TrustZone架構(gòu)的主要特性。 它包含安全操作系統(tǒng),安全監(jiān)視器,加密接口,安全存儲(chǔ)和可信應(yīng)用程序。
該圖顯示了weeveOS的非安全和安全的世界。 我們的GitHub中提供了該實(shí)現(xiàn)。
獨(dú)自一人,Trustzone硬件不足以掌握可信執(zhí)行環(huán)境的所有優(yōu)點(diǎn)。 除硬件外,還需要一個(gè)支持TEE的操作系統(tǒng),以激活全部安全潛力。 這就是Weeve團(tuán)隊(duì)開發(fā)weeveOS的原因。 實(shí)際上,TEE包括(至少)兩個(gè)操作系統(tǒng)。 第一個(gè)實(shí)現(xiàn)正常世界,第二個(gè)實(shí)現(xiàn)安全世界。 我們的方法是選擇精益安全的世界操作系統(tǒng)和豐富的普通世界操作系統(tǒng)。 該論點(diǎn)如下,通過降低安全OS的復(fù)雜性,發(fā)現(xiàn)漏洞的可能性比具有全面內(nèi)核和中間層的OS的情況要短。 如圖所示,三個(gè)TEE模塊增強(qiáng)了商品操作系統(tǒng)的系統(tǒng)架構(gòu),有助于在安全世界中執(zhí)行稱為可信應(yīng)用程序的程序:
另一個(gè)值得一提的重點(diǎn)是,以太坊基于虛擬機(jī)而不是數(shù)據(jù)庫,例如比特幣網(wǎng)絡(luò)就是這種情況。 由于這個(gè)事實(shí),以太坊智能合約允許執(zhí)行命令,而不僅僅是交易(作為一種特殊情況)。 錢包是與EVM交互的客戶端軟件。
通過TEE以太坊錢包,我們可以創(chuàng)建EVM可以解析和執(zhí)行的事務(wù)。 更準(zhǔn)確一點(diǎn),TEE以太坊錢包向EVM發(fā)送命令(通過我們的網(wǎng)關(guān),與EVM連接)。 為了不破壞任何命令,必須對(duì)命令進(jìn)行格式化。 我們?cè)趯?shí)施過程中必須解決的微妙障礙是應(yīng)對(duì)安全世界提供的相當(dāng)有限的編程機(jī)會(huì)。 原因是安全監(jiān)視器根據(jù)定義允許與安全世界的有限交互。
為什么以太坊錢包很重要
但是,當(dāng)有足夠的免費(fèi)替代解決方案時(shí),為什么需要一個(gè)以太坊錢包,尤其是可靠應(yīng)用中的錢包呢? 答案非常簡(jiǎn)單,所有這些解決方案首先不是用C語言構(gòu)建的,其次不是在TEE中構(gòu)建的。 對(duì)古典硬件錢包的巨大優(yōu)勢(shì)是不需要額外的硬件,因?yàn)門EE的范例我們能夠保持硬件錢包的優(yōu)勢(shì)。 因此,可以容易地實(shí)現(xiàn)加密算法的改變或其他錢包(例如,多錢包)的改編。 另一個(gè)優(yōu)點(diǎn)是,如果您想使用錢包,則無需額外的人工干預(yù)。 這尤其具有吸引力,因?yàn)槲锫?lián)網(wǎng)設(shè)備是現(xiàn)在可以在沒有用戶干預(yù)的情況下自主參與公平交換數(shù)字資產(chǎn)的機(jī)器。
創(chuàng)建以太坊地址
我們的錢包需要的第一件事是以太坊地址和我們的公鑰和私鑰對(duì)。 該密鑰對(duì)使用基于橢圓曲線密碼(ECC)的數(shù)字簽名算法(DSA)計(jì)算,該算法使用SECP256K1曲線進(jìn)行參數(shù)化。 由于錢包是在受信任的應(yīng)用程序中構(gòu)建的,因此我們可以毫不猶豫地將密鑰對(duì)保存在安全的存儲(chǔ)中。 公鑰現(xiàn)在用于生成我們的以太坊地址。
以太網(wǎng)地址基本上是來自散列公鑰的最后20個(gè)字節(jié)。 因此,我們使用公鑰并使用SHA3-256(Keccak)哈希算法對(duì)其進(jìn)行哈希處理。 輸出將是32字節(jié)長。然后只需刪除前12個(gè)字節(jié)以獲取我們的以太坊地址。
例如(輸出以十六進(jìn)制表示形式打印):
hash(public_key)= 45c1442cbfeebe459c91636455c2d462b27e49df96ae923a131bdf81548e3b2e比我們的以太坊地址將是:
55c2d462b27e49df96ae923a131bdf81548e3b2e干得好,憑借我們的密鑰對(duì)和以太坊地址,我們創(chuàng)建了我們的安全錢包。 下一步是生成交易。 這里有令人興奮的東西......
創(chuàng)建交易
RLP編碼
通過使用MQTTS與我們的客戶和我們的網(wǎng)關(guān)進(jìn)行通信,我們可以將所需的交易參數(shù)(如汽油價(jià)格,天然氣限制等)直接推送到我們可信賴的應(yīng)用程序中。 這將確保沒有正常的世界應(yīng)用程序可以操縱這些參數(shù)。
為了將事務(wù)參數(shù)推送到所需的客戶端, 網(wǎng)關(guān)將所有協(xié)商的參數(shù)設(shè)置為JSON-String并通過MQTTS將其推回。 該客戶端上的受信任應(yīng)用程序?qū)⒔馕鯦SON-String并生成具有所有必需值的結(jié)構(gòu)。 我們將使用這些值來創(chuàng)建我們的交易。 基本上我們從結(jié)構(gòu)中獲取每個(gè)參數(shù),并使用遞歸長度前綴(RLP)編碼對(duì)所有值進(jìn)行編碼,以便以太坊網(wǎng)絡(luò)可以處理我們的事務(wù)。
RLP編碼定義如下:
- 如果一個(gè)字節(jié)值的值在0x01和0x7f之間,我們只需將此值作為rlp編碼。 0x00值為0x80。 [檢查0 == 0x80]
- 對(duì)于長度為2-55字節(jié)的字節(jié),編碼由長度前綴加上字符串本身組成。 長度前綴是字符串的長度加上值(偏移量)0x80。
例如,字符串“hello world”的長度為11(或十六進(jìn)制0x0b),因此RLP的第一個(gè)字節(jié)為0x80 + 0x0b = 0x8b。 與字符串連接將給我們:
“hello world”= 0x8b,0x68,0x65,0x6c,0x6c,0x6f,0x20,0x77,0x6f,0x72,0x6c,0x64- 如果字符串長度超過55個(gè)字節(jié),則編碼定義字節(jié)值0xb7加上字符串長度加上字符串長度的字節(jié)長度。 之后,在末尾添加實(shí)際的字符串長度和字符串本身。
Imagen一個(gè)1024“s”的字符串:
“sss ...”= 0xb9,0x04,0x00,0x73,0x73,0x73所以0x73s定義了字符串本身。 0x04,0x00定義字符串的長度(1024 = 0x0400)。 最后,第一部分0xb7加上第二部分的長度(0xb9 = 0xb7 + 0x02)。
- 如果我們編碼孔有效負(fù)載并且有效負(fù)載是一個(gè)列表,我們確定該列表的總長度并檢查它是否在0到55字節(jié)之間。 編碼由列表的長度+ 0xc0加上RLP編碼的有效載荷組成
- 最后一條規(guī)則,如果我們有一個(gè)有效載荷列表且長度超過55個(gè)字節(jié),則RLP編碼由0xf7加上有效載荷長度的字節(jié)長度,后跟RLP編碼的有效載荷。
顯然我們創(chuàng)建了一些輔助函數(shù),它接受RLP編碼步驟。
v,r,s值
v值確定我們想要發(fā)布我們的事務(wù)的鏈,并且是十進(jìn)制數(shù)的十六進(jìn)制表示(即如果我們想要處理鏈id“4”,我們的v值在第一步中是0x04)。
r和s值稍后將簽名拆分為每個(gè)32字節(jié)。 但是,對(duì)于第一步,我們必須將其保持為0(如上所述,RLP編碼將在我們的事務(wù)中將其更改為0x80)。
必要的交易價(jià)值
此外,交易需要填寫以下字段:
- 天然氣價(jià)格:天然氣價(jià)格決定了創(chuàng)建者為兌換交易而想要支付多少錢。
- 天然氣限制:通過天然氣限制,我們定義了我們希望在單筆交易中支付多少的上限。
- 收件人:此字段包含收件人的以太坊地址。
- Nonce:nonce是一個(gè)任意數(shù)字,只能使用一次,并向我們顯示W(wǎng)allet使用了多少交易。
- 價(jià)值:在這里我們決定我們想要轉(zhuǎn)移多少以太
- 鏈ID:如前所述,此值位于v字段中并定義使用的鏈ID。
- 數(shù)據(jù)[可選]:數(shù)據(jù)字段是事務(wù)中唯一的可選字段。 我們?cè)谶@里定義一個(gè)交易ID來跟蹤以太坊網(wǎng)絡(luò)中的交易。
交易價(jià)值的順序
接下來我們要?jiǎng)?chuàng)建我們的交易。 這可以通過使用我們的RLP編碼對(duì)所有上述值進(jìn)行編碼并將所有內(nèi)容連接在一起來完成。 這里以正確的順序連接值非常重要。 以太坊無法解析具有不同訂單的交易。
Nonce + gas_price + gas_limit + to + value + data + v + r + s => transaction在將此連接字符串用作事務(wù)之前,我們需要對(duì)孔有效負(fù)載進(jìn)行編碼。 如RLP規(guī)則中所述,我們沒有有效負(fù)載列表,只有一個(gè)字符串,因此該步驟的偏移量為0xc0。
所以從我們的價(jià)值觀(以十六進(jìn)制表示):
nonce =“00” gas_price =“01” gas_limit =“0186a0” to =“f125691d24a6b5cdcb87a89cb825fdf4487c2a34” value =“0401” data =“fe3d61b7cd6eff03698c0303b056e0fe3116206e” v =“04”我們使用鏈ID 4 r =“00” s =“00”我們得到一個(gè)編碼交易:
0xf84a8001830186a094f125691d24a6b5cdcb87a89cb825fdf4487c2a34820401a866653364363162376364366566663033363938633033303362303536653066653331313632303665048080現(xiàn)在我們已經(jīng)完成了編碼交易,我們已準(zhǔn)備好對(duì)其進(jìn)行簽名。
簽署交易
在我們將事務(wù)編碼為所需格式后,我們可以開始簽署此消息。
簽名算法采用我們的編碼事務(wù)并從中生成哈希(再次使用的哈希算法是SHA3-256 Keccak)。 此哈希和私鑰將生成我們的簽名。 簽名本身由一對(duì)(r,s)組成,其中每個(gè)元素長度為32個(gè)字節(jié)。
再次編碼
最后我們使用簽名,將該對(duì)分成兩個(gè)32字節(jié)的字符串并將它們移動(dòng)到我們的結(jié)構(gòu)中。 顯然r被推到我們的r結(jié)構(gòu)值,s被推到s。
v值將(如事務(wù)描述中所述)確定使用的鏈,并用于稍后從簽名中恢復(fù)公鑰。
恢復(fù)公鑰
要從橢圓曲線數(shù)字簽名算法(ECDSA)恢復(fù)公鑰,我們必須知道
a)該算法使用什么曲線
b)使用了什么哈希函數(shù)
c)簽署了什么消息
幸運(yùn)的是,我們知道所有這些要求,但我們現(xiàn)在無法唯一恢復(fù)公鑰。
如果我們嘗試使用這些參數(shù)恢復(fù)它,我們將獲得兩個(gè)公鑰; 一個(gè)在正y坐標(biāo)上,一個(gè)在負(fù)面上。 要唯一地恢復(fù)公鑰,我們還需要一個(gè)恢復(fù)ID,它將確定正確的公鑰。 以太坊通過重新計(jì)算以下內(nèi)容將此恢復(fù)ID保存在v字段中:
chain_id * 2 + 35 +(0或1)0或1確定我們是否具有公鑰y點(diǎn)的正位置或負(fù)位置。 要獲得此值,我們只需讀取公鑰y點(diǎn)的最后一位,并確定其是0還是1。
因此,對(duì)于我們之前的示例事務(wù),我們得到:
0xf88a8001830186a094f125691d24a6b5cdcb87a89cb825fdf4487c2a34820401a8666533643631623763643665666630333639386330333033623035366530666533313136323036652ba0d5c8eaca6a7bc128065bf7ed3fa053863cdff64b8910f1325099eb89328877fba073fc3184cf468d163296543433c31213ebcf83b3a076a8765461e81c79b1ebc7使用重置的v,r,s值,我們像以前一樣再次編碼孔事務(wù)。 輸出現(xiàn)在將填充到我們的正常世界應(yīng)用程序中,并可用于推進(jìn)以太坊鏈。
結(jié)論:以太坊鏈安全錢包的成功
由于我們?cè)诎踩I(lǐng)域內(nèi)創(chuàng)建這個(gè)受信任的應(yīng)用程序的進(jìn)步,我們現(xiàn)在能夠安全地為以太坊鏈創(chuàng)建錢包和交易。 這使我們能夠利用TEE(可信執(zhí)行環(huán)境)的安全功能來對(duì)抗針對(duì)物聯(lián)網(wǎng)設(shè)備的網(wǎng)絡(luò)攻擊。
如果你做到這一點(diǎn),首先祝賀,其次,我們確信你要么有幾個(gè)問題,要么想和我們聊聊。 請(qǐng)聯(lián)系我們Gitter并在這里查看我們的Github或加入Telegram上的對(duì)話。
我們注意到TEE以太坊錢包是weeveOS的一部分,這是一個(gè)開源項(xiàng)目。 我們征求反饋或任何形式的社區(qū)貢獻(xiàn)來發(fā)展項(xiàng)目。
?
https://medium.com/weeves-world/ethereum-wallet-in-a-trusted-execution-environment-secure-enclave-b200b4df9f5f
總結(jié)
以上是生活随笔為你收集整理的【译】Ethereum Wallet in a Trusted Execution Environment / Secure Enclave的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LinkedList源码阅分析
- 下一篇: C++ 函数重载碰到默认的参数