當前位置:首頁 » 編程語言 » keccak演算法c語言
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

keccak演算法c語言

發布時間: 2023-05-03 04:30:35

① 密碼學系統

本文分為7個部分,第1部分介紹密碼學的基本概念,第2部分講解常見的對稱加密演算法,第3部分講解常見的非對稱加密演算法,第4部分講解 數字簽名, 第5部分講解PKI(Public Key Infrastructure),第6部分講解哈希函數加密,第7部分講解密碼學在區塊鏈里的應用, 最後一部分會講解隨機數。

比較常見的對稱加密演算法有: Digital Encryption Standard(DES), Triple-DES, IDEA, BLOWFISH。

對稱加密的挑戰:

非對稱加密的挑戰:

比較常見的非對稱加密演算法有: RSA, ElGamal, ECC。

菲斯特爾結構的塊加密演算法是著名的一個分組密碼加密的設計模型。

1990年後對DES進行徹底的密鑰搜索的速度開始引起DES用戶的不適。 然而,用戶並不想取代DES,因為它需要花費大量的時間和金錢來改變廣泛採用並嵌入到大型安全架構中的加密演算法。

務實的做法不是完全放棄DES,而是改變DES的使用方式。 這導致了三重DES(3DES)的修改方案。

三重DES
在使用3TDES之前,用戶首先生成並分配一個3TDES密鑰K,它由三個不同的DES密鑰K1,K2和K3組成。

詳細可以看 Triple-DES

高級加密標准(Advanced Encryption Standard,AES)是目前比較流行和廣頌橋扮泛採用的對稱加密演算法。 發現至少比三重DES快6倍。
AES的功能如下:

對稱密鑰對稱分組密碼
128位數據,128/192/256位密鑰
比Triple-DES更強更快
提供完整的規格和設計細節

詳細可以看 AES

這個密碼系統是最初的系統之一。 即使在今天,它仍然是最多被使用的密碼系統。 該系統由三位學者Ron Rivest,Adi Shamir和Len Adleman發明,因此被稱為RSA密碼系統。

下面給出生成RSA密鑰對的一個例子(為了便於理解,這里採用的素數p&q值很小,實際上這些值非常高)。

設兩個素數為p = 7且q = 13。因此,模數n = pq = 7×13 = 91。

選擇 e = 5,這是一個有效的選擇,因為沒有數字是公因子5和(p - 1)(q - 1)= 6×12 = 72,除了1。

這對數字(n,e) = (91, 5)形成公鑰,可以讓任何我們希望能夠向我們發送加密消息的人使用。

向擴展歐幾里德演算法輸入p = 7,q = 13和e = 5。 輸出將是d = 29。
因此,公鑰是(91, 5),私鑰是(91, 29)。

假設發送者希望發送一些文本消息給公鑰為(n,e)的人。然後發件人將明文表示為一系列小於n的數字。
為了加密第一個明消茄文P,它是一個模n的數字。 加密過程是簡單的數學步驟:
C = Pe mod n
換句話說,密文C等於明文P乘以自己e次,然後減去模n。 這意味著C也是一個小於n的數字。
回到我們的密鑰生成例子,明文P = 10,我們得到密文C:
C = 105 mod 91

屬於ECC的一種變化。加密的核心理念與RSA相似,也是利用離散對數很難求解。
但與RSA不同的野灶是 公鑰的組成部分,EIGamal的公鑰有三部分組成, 質模數 p, 生成元素 g, 以及 公共的 Y = gx(g的x次方) mod p。
詳細可以看 ElGamal Crytosystem

橢圓曲線密碼術(ECC)是用來描述一套密碼工具和協議的術語,其安全性基於特殊版本的離散對數問題。它不使用數字模p。ECC基於與稱為橢圓曲線的數學對象相關聯的數字集合。有這些數字的加法和計算倍數的規則,就像數字模p一樣。

ECC包含許多最初為模塊化數字設計的密碼方案的變體,如ElGamal加密和數字簽名演算法。

相信當應用於橢圓曲線上的點時,離散對數問題更加困難。這會提示從數字模p切換到橢圓曲線上的點。如果我們使用基於橢圓曲線的變體,也可以用較短的密鑰獲得等效的安全級別。

較短的密鑰有兩個好處:
易於管理
高效的計算
這些優點使基於橢圓曲線的加密方案變體對計算資源受到限制的應用程序非常有吸引力。

詳細可以看 Elliptic Curve Cryptography

^符號表示為多少次方
簽名 = 消息^D mod N (D和N 為簽名者的私鑰,計算消息的D次方並求mod N,所得余數即為簽名)
消息 = 簽名^E mod N (E和N 為簽名者的公鑰,計算簽名的E次方並求mod N)

舉個例子:
私鑰: D = 29; N = 323
公鑰: E = 5; N = 323
消息: 123

由於 N 的值為 323, 因此消息需要為 0 ~ 322 這個范圍內的整數. 假設需要對 123 這個消息進行簽名.
用私鑰(D,N) = (29,323) 對消息 123 進行簽名.

消息^D mod N = 123^29 mod 323 = 157
因此 (消息, 簽名) = (123, 157)

用公鑰(E,N) = (5,323)對消息進行驗證
簽名^E mod N = 157^5 mod 323 = 123

得到消息 123 與發送者發送過來的消息 123 是一致的,因此簽名驗證成功.

https://andrea.corbellini.name/2015/05/17/elliptic-curve-cryptography-a-gentle-introction/

加法逆: a在集合中, -a在集合中的定義為使 a + (-a) = 0, 這就是加法逆元運算
乘法逆: a在集合中,且不為0, a^-1 在集合中定位為使 a* a^-1 = 1, 這就是乘法逆元運算

在聊橢圓曲線前,我們先打一些基礎然後再討論一下對數問題.

在一個集合上定義一個二元運算,這就是數學中的群。一個集合 G 要成為一個群,必須滿足下面 4 個條件:

從平常的加法概念來看, 整數集 Z 是一個群(而且是阿貝爾群). 自然數集 N 不是一個群.

我們可以在橢圓曲線上定義一個群:

https://andrea.corbellini.name/ecc/interactive/reals-add.html

如下圖: 點 A 的自我相加過程就是做 乘法的過程 這個過程叫 Point Doubling

計算 nP 需要做 n次加法 如果 n 為 k 位二進制 時間復雜度為 O(2^k)

倍加演算法 比如 n = 151 二進制為 10010111

用倍加演算法 時間復雜度有了很大的改進 O(logN) or O(k)

Q = nP

這只是 p = 211, 像 Secp256k1 這條橢圓曲線的 p = 34671663 一個78位的數字 要怎麼求出 n?

一個通俗的比喻: 假設這些點是有個人 A 在一個很大的房間里玩彈珠的游戲 玩了兩年 兩年後 A 的朋友 B來了 B看到了最後的點 以及 A 告訴B 起點 但是B怎麼能知道 A 是彈了多少次才從起點彈到終點?

上面這兩張圖是 橢圓曲線 - Secp256K1: y^2 = x^3 + 7
第一張圖: 定義在 實數域
第二張圖: 定義在 有限域Zp
是用下面的參數(p,a,b,G,n,h)形成的:

p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F = 2^256 - 2^32 - 997
a = 0
b = 7
G = [0x79BE667E_F9DCBBAC_55A06295_CE870B07_029BFCDB_2DCE28D9_59F2815B_16F81798,
0x483ADA77_26A3C465_5DA4FBFC_0E1108A8_FD17B448_A6855419_9C47D08F_FB10D4B8]
n = 0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_BAAEDCE6_AF48A03B_BFD25E8C_D0364141
h = 1

如果橢圓曲線上一點P, 存在最小的正整數 n 使得數乘 nP=O∞, 則將 n 稱為 P 的階

計算可得 27P = -P = (3, 13) 所以 28P = 0∞ P的階為28

如何簽名?
Sig = F sig ( F keccak256 ( m ) , k )

如何計算 r

如何計算 s
s ≡ q^-1 (Keccak256(m) + r * k) (mod p)

如何驗證簽名?

P.S. 上述驗證簽名的過程中 沒有用到發送者的 私鑰

RSA 密鑰大小(bits) ECC 密鑰大小 (bits)
1024 160
2048 224
3072 256
7680 384
15360 521

有一個研究例子 同一台計算能力的計算機

為什麼 比特幣和以太坊要選擇 Secp256k1 這條橢圓曲線?

假如有人提供一條橢圓曲線比如 Secp256r1 如何驗證這條曲線的安全性?

因為公鑰是公開的,很容易被破壞或者篡改,因此需要建立和維持一種可信的基礎機制來管理公鑰。

PKI由5部分組成:

作為比喻,證書可以被視為發給該人的身份證。人們使用駕照,護照等身份證來證明自己的身份。數字證書在電子世界中具有相同的基本功能。
但有一點不同,數字證書不僅發給人,還可以發給電腦,軟體包或任何其他需要證明電子世界身份的東西。

數字證書基於ITU標准X.509,該標準定義了公鑰證書和認證驗證的標准證書格式。因此數字證書有時也被稱為X.509證書。

與用戶客戶端相關的公鑰與證書頒發機構(CA)一起存儲在數字證書中,以及其他相關信息,例如客戶信息,到期日期,使用情況,發行者等。

CA對此整個信息進行數字簽名並在證書中包含數字簽名。

任何需要對客戶的公共密鑰和相關信息進行保證的人,他都會使用CA的公鑰進行簽名驗證過程。成功的驗證可確保證書中給出的公鑰屬於在證書中給出詳細信息的人員。

下圖了展示了個人/實體獲取數字證書的過程:

如圖所示,CA接受來自客戶端的申請以證明其公鑰。 CA在適當驗證客戶身份後,向該客戶發出數字證書。

如上所述,CA向客戶頒發證書並協助其他用戶驗證證書。 CA負責正確識別要求頒發證書的客戶的身份,並確保證書中包含的信息是正確的並對其進行數字簽名。

CA的關鍵功能:

證書類別
有四種典型的證書類別:

第1類 - 通過提供電子郵件地址可輕松獲取這些證書。

第2類 - 這些證書要求提供額外的個人信息。

第3類 - 這些證書只有在對請求者的身份進行檢查後才能購買。

第4類 - 它們被需要高度信任的政府和金融機構使用。

CA可以使用第三方注冊機構(RA)對要求證書確認其身份的人或公司進行必要的檢查。 RA可能在客戶端看起來像一個CA,但它們實際上並不簽署發布的證書。

這是發布證書的管理系統,暫時或永久暫停,續訂或撤銷證書。 證書管理系統通常不會刪除證書,因為可能有必要在某個時間點證明其身份,這是出於法律原因。 CA和相關RA運行證書管理系統,以便能夠跟蹤他們的責任。

雖然客戶端的公鑰存儲在證書中,但關聯的私鑰可以存儲在密鑰所有者的計算機上。 這種方法一般不採用。 如果攻擊者能夠訪問計算機,他可以輕松訪問私鑰。 出於這個原因,私鑰存儲在通過密碼保護的安全可移動存儲令牌上。

不同的供應商經常使用不同的專有的存儲格式來存儲密鑰。 例如,Entrust使用專有的.epf格式,而Verisign,GlobalSign和Baltimore使用標準的.p12格式。

1.6 Hierarchy of CA:
由於擁有龐大的網路和全球通信的要求,所有用戶從唯一一個可信的CA獲得證書是不切實際的。其次,只有一個CA的可用性可能會導致大的阻礙,如果CA受到影響。

在這種情況下,層次認證模型很受關注,因為它允許在兩個通信方與相同CA沒有信任關系的環境中使用公鑰證書。

根CA位於CA層次結構的頂部,根CA的證書是自簽名證書。

直接隸屬於根CA(例如,CA1和CA2)的CA具有由根CA簽名的CA證書。

層次結構中下級CA(例如,CA5和CA6)下的CA具有由上級下級CA簽名的CA證書。

證書頒發機構(CA)層次體現在證書鏈中。證書鏈跟蹤從層次結構中的分支到層次結構根的證書路徑。

下圖顯示了具有從實體證書到兩個從屬CA證書(CA6和CA3)到根證書頒發機構CA證書的證書鏈的CA層次結構:

驗證證書鏈是確保特定證書鏈有效,正確簽署和可信的過程。 以下過程驗證證書鏈,從提供驗證的證書開始 -

一個正在驗證其真實性的客戶端提供他的證書,通常連同證書鏈一直到根CA.

驗證者獲取證書並使用發行者的公鑰進行驗證。 發行人的公鑰在發行人的證書中找到,該證書位於客戶證書旁邊的鏈中。

現在,如果已簽署發行人證書的較高的CA由驗證方信任,則驗證成功並在此停止。

否則,發行人證書的驗證方式與客戶在上述步驟中完成的相似。 此過程將繼續進行,直到在其中找到可信的CA,否則它將持續到根CA。

哈希函數非常有用,並且出現在幾乎所有信息安全應用程序中。

哈希函數是將數字輸入值轉換為另一個壓縮數值的 數學函數。 哈希函數的輸入具有任意長度,但輸出始終為固定長度。

哈希函數返回的值稱為消息摘要或簡單的散列值。 下面的圖片說明了哈希函數:

為了成為一個有效的加密工具,哈希函數具有以下屬性:

散列的核心是一個數學函數,該函數在兩個固定大小的數據塊上運行以創建散列碼。 這個哈希函數構成哈希演算法的一部分。

每個數據塊的大小因演算法而異。 通常塊大小從128位到512位。 下圖演示了哈希函數:

哈希演算法涉及上述哈希函數,如分組密碼。 每一輪都會輸入一個固定的大小,通常是最近消息塊和最後一輪輸出的組合。

這個過程重復進行多次,以散列整個消息。 哈希演算法的示意圖如下圖所示:

因為第一消息塊的散列值變成第二散列操作的輸入,其輸出改變第三操作的結果,等等。 這種效應被稱為散列的雪崩效應。雪崩效應對兩個即使是單個數據位也不相同的消息產生明顯不同的散列值。理解哈希函數和演算法之間的區別。 哈希函數通過對兩個固定長度的二進制數據塊進行操作來生成哈希碼。哈希演算法是一個使用哈希函數的過程,指定如何分解消息以及如何將先前消息塊的結果鏈接在一起。

後來在1995年,SHA-1被設計用於糾正SHA-0的所謂弱點。SHA-1是現有SHA哈希函數中使用最廣泛的。它被用於幾個廣泛使用的應用程序和協議,包括安全套接字層(SSL)安全。

2005年,發現了一種在實際時間框架內發現SHA-1沖突的方法,使SHA-1的長期可用性受到懷疑。

SHA-2系列具有四個更進一步的SHA變體,SHA-224,SHA-256,SHA-384和SHA-512,取決於其散列值中的位數。還沒有成功的攻擊報道過SHA-2哈希函數。

雖然SHA-2是一個強大的哈希函數。雖然有很大的不同,但其基本設計仍然遵循SHA-1的設計。因此,NIST要求提供新的競爭性散列函數設計。

2012年10月,NIST選擇Keccak演算法作為新的SHA-3標准。 Keccak提供了許多好處,例如高效的表現和良好的攻擊抵抗力。

該集包括RIPEND,RIPEMD-128和RIPEMD-160。此演算法還有256位和320位版本。

原始的RIPEMD(128位)基於MD4中使用的設計原則,並且發現提供可疑的安全性。 RIPEMD 128位版本是解決原始RIPEMD漏洞的快速修復替代品。

RIPEMD-160是一個改進版本,是使用最廣泛的版本。與RIPEMD-128和RIPEMD-160相比,256和320位版本分別減少了意外沖突的可能性,但沒有更高的安全等級。

Merkle Tree 默克爾樹

哈希演算法的一個重要應用是默克爾樹(Merkle tree),默克爾樹是一種數據結構,通常是一個二叉樹,也有可能是多叉樹,它以特定的方式逐層向上計算,直到頂部,最頂層叫做默克爾根(Merkle Root),默克爾樹最為常見和最簡單的是二叉默克爾樹。

② 密碼技術

密碼演算法的特性
1、是否需要事先配送私鑰:對稱密碼需猜老要考慮
2、是否會遭到中間人攻擊:非對稱密碼分發公鑰時需要考慮
3、不可抵賴(可被雙方 和 第三方 用原理證明):非對稱密碼分發公鑰時需要考慮
4、能否保證消息的機密性:即不可破譯
5、能否保證消息的完整性(一致性):即不可篡改
6、不可冒充(偽造)

總結:對稱密碼(解決456)--非對稱密碼之單向通信--> 混合密碼(解決1) --非對稱密碼之數字簽名--> 公鑰證書(解決23)

概念
密碼演算法:加密演算法 + 密鑰 + 解密演算法,簡稱密碼
密鑰空間:密鑰的所有取值
隱蔽式安全性:以密碼演算法不為人所知,來保證機密性
分組密碼:對明文進行分組加密,而非以全文作為輸入
流密碼:不分組,整體加密

破解密文的方法
1、竊聽 + 破譯
2、社會工程學
破解密鑰的方法
1、暴力破解(密鑰窮舉),例如破譯凱撒密碼
2、頻率分析,例如破譯簡單替換密碼
3、選擇明文攻擊(對分組進行明文窮舉)

加密系統的可選技術
隱寫術:將消息藏在更大的數據中,例如藏頭詩
偽隨機數生成器
散列值(摘要,哈希值,指紋):原文經過散列函數(摘要函數,哈希函數,雜湊函晌兆慶數,單向加密)計算出來的值
對稱密碼(共享密鑰密碼):加密和解密用同一個私鑰
非對稱密碼(公鑰密碼):公鑰加密,私鑰解密
消息認證碼
數字簽名
公鑰證書

碰撞:兩個消息的散列值相同
弱抗碰撞性:給定一條消息,很難找到另一條消息與其散列值相同。防止以下情形,Bob持有一個消息A,計算其摘要;Alice找到與A散列值相同的另一條消息B,用B將A調包;由於摘要不變,不被Bob發覺
強抗碰撞性:很難找到兩條散列值相同的消息。防止以下情形,Alice拿兩個摘要相同的消息A和B,將A發給Bob;Bob計算其摘要;Alice再用B將A調包;由於摘要不變,不被Bob發覺
MD5(Message Digest 5)
歷史:1991年Ronald Rivest 設計出MD5
現狀:2004年王小雲提出了MD5碰撞攻擊演算法
SHA
歷史:1993年NIST發布SHA,1995年發布SHA-1,2002年發布SHA-2
現狀:2004年王小雲提出了SHA-0的碰撞攻擊演算法;2005年王小雲提出了SHA-1的碰撞攻擊演算法
SHA-3
歷史:2007年NIST發起選拔SHA-3,2012年Joan Daemen等人設計的Keccak演算法被選定為SHA-3

弱偽隨機數:隨機性
強偽隨機數:不可預測性
真隨機數:不可重現性

隨機數生成器:硬體可以通過熱雜訊實現真隨機數
偽隨機數生成器:軟體只能生成偽隨機數,需要一種子seed來初始化

偽隨機數演算法:線性同餘法、散列法、密碼法等

好的對稱密碼解決:不可破譯
缺點:需要事先配送密鑰
凱撒密碼
加密演算法:字母平移
密鑰:平移位數
解密演算法:逆向平移
破解密鑰:窮舉可能的密鑰
簡單替換密碼
加密演算法:一個字母替換成另一個字母
密鑰:替換表
解密演算法:逆向替換
破解密鑰:對密文的字母 和 字母組合進行頻率分析,與通用頻率表對比;用破譯出來的明文字母,代入密文,循環分析
Enigma密碼
發明者:德國人Arthur Sherbius
加密演算法:雙重加密,每日密鑰作為密鑰1,想一個密鑰2;用密鑰1加密密鑰2,得到密鑰2密文;用密鑰2加密消息;將密鑰2密文和消息密文一起發出
密鑰:密鑰冊子記錄的每天不同的密鑰
解密演算法:宴握用每日密鑰解密密鑰2密文,得到密鑰2;用密鑰2解密消息密文
破譯者:Alan Turing 圖靈

DES密碼(Data Encryption Standard)
歷史:1974年IBM公司的Horst Feistel開發出了Lucifer密碼,1977年被美國國家標准學會(American National Standards Institute,ANSI)確定為DES標准
加密演算法:以64比特為一組,進行16輪運算。在一輪中,把一組分為左側和右側,並從密鑰中提取子密鑰;輪函數用一側和子密鑰生成一個比特序列,用這個比特序列對另一側進行異或運算(XOR)
密鑰:長度56位
破譯:可在現實時間內被暴力破解

三重DES密碼(triple-DES,TDEA,3DES)
加密演算法:將DES重復三次
密鑰:長度 56 * 3

AES密碼(Advanced Encryption Standard)
歷史:1997年,美國國家標准與技術研究院(National Institute of Standards and Technology,NIST)公開募集AES,2000年比利時密碼學家Joan Daemen 和 Vincent Rijmen提交的Rijndael方案,被選為標准
加密演算法:以128比特為一組,進行多輪的替換、平移、矩陣運算
密鑰:有128,192,256三種長度

分組密碼的迭代模式
ECB模式:Electronic CodeBook mode,電子密碼本模式;明文分組 和 密文分組 順序對應。主動攻擊者可以改變密文分組的順序,復制 或 刪除密文分組,使得接受者解密後得到錯誤的明文
CBC模式:Cipher Block Chaining mode,密碼分組鏈接模式;將本組明文 和 上組密文 進行異或運算後,在進行加密;如果被篡改,則不能正常解密
CFB模式:Cipher Feedback mode,密文反饋模式;將本組明文 和 上組密文 進行異或運算後,就得到本組的密文
OFB模式:Output Feedback mode,輸出反饋模式;用隨機比特序列作為初始化組(初始化向量);用初始化組的密文和 明文分組 異或運算,得到密文分組;再次對初始化組密文進行加密運算,得到新的初始化組密文,跟下組明文進行異或運算,以此類推
CTR模式:CounTeR mode,計數器模式;用隨機比特序列作為計數器的初始值,加密後與明文分組進行異或操作,得到密文分組;計數器加一,對下組明文進行加密

對稱密碼中,發送方發送密文時,帶上消息的MAC值A;接收方用相同方法計算出MAC值B;對比A和B,確保消息不被篡改
Encrypt-then-MAC:MAC值為消息密文的散列值
Encrypt-and-MAC:MAC值為消息明文的散列值
MAC-then-Encrypt:MAC值為明文散列值的密文

重放攻擊:攻擊者竊聽到Alice給Bob發送的消息後,重復給Bob發送,Bob以為都是Alice發的
預防重放攻擊:消息里帶有一個id

比對稱密碼:不可篡改、不可偽造
缺點:需要實現配送私鑰

基於口令的密碼:Password Based Encryption,PBE
解決:密鑰(會話密鑰)保存問題
CEK:會話密鑰
KEK:用來加密CEK的密鑰
方案
1、隨機數作為鹽salt,口令 + 鹽 的散列值作為KEK
2、用KEK加密CEK,得到CEK密文
3、只保存鹽和CEK密文,人腦記住口令,丟棄KEK

字典攻擊:如果沒有鹽參與生成KEK,那麼口令決定了KEK,常用的口令對應一個常用KEK字典,攻擊者直接拿常用KEK去解密CEK密文
鹽的作用:KEK由鹽參與形成,不可能有KEK字典包含這樣的KEK

非對稱密碼單向通信,不能單獨用於通信,只用在混合密碼中
方案:Alice 給 Bob 分發加密密鑰(公鑰);Bob用公鑰加密消息,發送給Alice;Alice用解密密鑰(私鑰)解密
總結:消息接收者是密鑰對主人,即私鑰持有人;公鑰用於加密,私鑰用於解密

RSA密碼
歷史:1978年,Ron Rivest、Adi Shamir、Reonard Adleman共同發表了RSA
加密演算法:密文 = 明文 E mode N
公鑰:E 和 N的組合
解密演算法:明文 = 密文 D mode N
私鑰:D 和 N的組合

生成密鑰對
生成質數:用偽隨機數生成隨機數,通過Miller-Rabin測試法測試它是不是質數,直到得到質數
求最大公約數:歐幾里得的輾轉相除法
1、求N
生成兩個512位的質數p和q,N = p * q
2、求L
L是p-1 和 q-1 的最小公倍數
3、求E
用偽隨機數生成(1,L)范圍內的隨機數,直到滿足E和L的最大公約數為1
4、求D
用偽隨機數生成(1,L)范圍內的隨機數,直到滿足(E * D) mod L = 1

破解:對N進行質因數分解,得到p和q,從而求出D。但是對大數的質因數分解,未有快速有效的方法

首次通信為混合密碼,後續通信為對稱密碼
比消息認證碼:無需事先配送私鑰
總體思路:Bob 用會話密鑰加密消息,用Alice的公鑰加密會話密鑰,一起發給Alice;Alice用私鑰解密會話密鑰,用會話密鑰解密消息
會話密鑰:用來加密消息的 對稱密碼的密鑰
1、Alice 給 Bob 發送公鑰
2、Bob隨機生成會話密鑰,用會話密鑰加密消息,得到消息密文
3、Bob用公鑰加密會話密鑰,得到會話密鑰密文
4、Bob將會話密鑰密文和消息密文一起發給Alice
5、Alice用私鑰解密會話密鑰,再用會話密鑰解密消息
6、雙方都有了會話密鑰,從此以後,可以用對稱密碼通信了,帶上消息認證碼

缺點:分發公鑰時,可能遭受中間人攻擊;Alice可能對給Bob發送公鑰這件事進行抵賴
中間人攻擊:中間人從一開始Alice向Bob發放公鑰時,就攔截了消息,得到Alice的公鑰;然後偽裝成Alice,向Bob發送自己的公鑰;從而Bob打算發給Alice的消息,能被中間人解密

不能單獨用於通信,只用在公鑰證書中
明文簽名:Alice用簽名密鑰(私鑰)加密消息的摘要,把摘要密文和消息明文一起發給Bob;Bob解密摘要密文,得到摘要A;算出明文摘要B,對比A和B
總結:私鑰用於加密,公鑰用於解密,與 非對稱加密之單向通信,剛好反過來

公鑰證書:Public-Key Certificate,PKC,簡稱證書
認證機構:Certification Authority,CA
證書標准:國際電信聯盟ITU 和 國際標准化組織ISO指定的X.509標准
流程:
1、Alice在CA登記
2、CA生成Alice的證書明文,包含Alice登記的信息、Alice的公鑰、CA信息
3、CA用自己的私鑰加密證書明文部分,得到數字簽名
4、證書明文部分 和 數字簽名 組成PKC,頒發給Alice
5、Bob向Alice獲取這個PKC,拿本地已有的CA公鑰去驗證證書,就得到了可信的Alice的公鑰
6、從此Alice 和 Bob之間可以進行混合密碼通信

首次通信為從CA獲取PKC,後續通信為混合密碼
比混合密碼:防止了中間人攻擊;CA不能抵賴自己的證書

歷史:1994年網景公司設計出SSL,2014年SSL 3.0被發現安全漏洞,1999年IEIF發布TLS
TLS(Transport Layer Security)是SSL(Secure Socket Layer)的後續版本,在tcp和http之間加一層TLS,就是https
OpenSSL:OpenSSL是實現SSL/TLS協議的工具包
以https為例
0、瀏覽器安裝時,存有幾個CA公鑰;伺服器在CA登記,拿到證書
1、瀏覽器訪問一個https地址,伺服器返回自己的證書
2、瀏覽器根據證書上的CA信息,拿對應的CA公鑰驗證證書,得到可信的伺服器公鑰
3、瀏覽器生成對稱密碼的密鑰(會話密鑰),用伺服器公鑰加密後發給伺服器
4、伺服器解密後得到會話密鑰,從此用對稱密碼通信,帶上消息認證碼

1、生成JKS證書:keytool -genkeypair -alias "別名" -keyalg "RSA" -keystore "D:app.jks"
2、將JKS轉換成PKCS12:keytool -importkeystore -srckeystore D:app.jks -destkeystore D:app.p12 -deststoretype pkcs12
3、將PKCS12轉成pem:openssl pkcs12 -in ./app.p12 -out app.pem
4、提取加密後的私鑰:將pem中 「—–BEGIN ENCRYPTED PRIVATE KEY—–」 至 「—–END ENCRYPTED PRIVATE KEY—–」 的內容拷貝出來,保存為ciphertext.key
5、將密文私鑰轉成明文私鑰:openssl rsa -in ciphertext.key -out plaintext.key

.jks(Java Key Storage):二進制格式,包含證書和私鑰,有密碼保護
.pfx 或 .p12(Predecessor of PKCS#12):二進制格式,包含證書和私鑰,有密碼保護
.pem(Privacy Enhanced Mail):文本格式,包含證書,可包含私鑰,私鑰有密碼保護
.der 或 .cer:二進制格式,只包含證書
.crt(Certificate):可以是der格式,也可以是pem格式,只包含證書

SSL證書:SSL證書必須綁定域名,不能綁定IP
加密服務、密鑰管理服務

③ 區塊鏈密碼演算法是怎樣的

區塊鏈作為新興技術受到越來越廣泛的關注,是一種傳統技術在互聯網時代下的新的應用,這其中包括分布式數據存儲技術、共識機制和密碼學等。隨著各種區塊鏈研究聯盟的創建,相關研究得到了越來越多的資金和人員支持。區塊鏈使用的Hash演算法、零知識證明、環簽名等密碼演算法:

Hash演算法

哈希演算法作為區塊鏈基礎技術,Hash函數的本質是將任意長度(有限)的一組數據映射到一組已定義長度的數據流中。若此函數同時滿足:

(1)對任意輸入的一組數據Hash值的計算都特別簡單;

(2)想要找到2個不同的擁有相同Hash值的數據是計算困難的。

滿足上述兩條性質的Hash函數也被稱為加密Hash函數,不引起矛盾的情況下,Hash函數通常指的是加密Hash函數。對於Hash函數,找到使得被稱為一次碰撞。當前流行的Hash函數有MD5,SHA1,SHA2,SHA3。

比特幣使用的是SHA256,大多區塊鏈系統使用的都是SHA256演算法。所以這里先介紹一下SHA256。

1、 SHA256演算法步驟

STEP1:附加填充比特。對報文進行填充使報文長度與448模512同餘(長度=448mod512),填充的比特數范圍是1到512,填充比特串的最高位為1,其餘位為0。

STEP2:附加長度值。將用64-bit表示的初始報文(填充前)的位長度附加在步驟1的結果後(低位位元組優先)。

STEP3:初始化緩存。使用一個256-bit的緩存來存放該散列函數的中間及最終結果。

STEP4:處理512-bit(16個字)報文分組序列。該演算法使用了六種基本邏輯函數,由64 步迭代運算組成。每步都以256-bit緩存值為輸入,然後更新緩存內容。每步使用一個32-bit 常數值Kt和一個32-bit Wt。其中Wt是分組之後的報文,t=1,2,...,16 。

STEP5:所有的512-bit分組處理完畢後,對於SHA256演算法最後一個分組產生的輸出便是256-bit的報文。

2、環簽名

2001年,Rivest, shamir和Tauman三位密碼學家首次提出了環簽名。是一種簡化的群簽名,只有環成員沒有管理者,不需要環成員間的合作。環簽名方案中簽名者首先選定一個臨時的簽名者集合,集合中包括簽名者。然後簽名者利用自己的私鑰和簽名集合中其他人的公鑰就可以獨立的產生簽名,而無需他人的幫助。簽名者集合中的成員可能並不知道自己被包含在其中。

環簽名方案由以下幾部分構成:

(1)密鑰生成。為環中每個成員產生一個密鑰對(公鑰PKi,私鑰SKi)。

(2)簽名。簽名者用自己的私鑰和任意n個環成員(包括自己)的公鑰為消息m生成簽名a。

(3)簽名驗證。驗證者根據環簽名和消息m,驗證簽名是否為環中成員所簽,如果有效就接收,否則丟棄。

環簽名滿足的性質:

(1)無條件匿名性:攻擊者無法確定簽名是由環中哪個成員生成,即使在獲得環成員私鑰的情況下,概率也不超過1/n。

(2)正確性:簽名必需能被所有其他人驗證。

(3)不可偽造性:環中其他成員不能偽造真實簽名者簽名,外部攻擊者即使在獲得某個有效環簽名的基礎上,也不能為消息m偽造一個簽名。

3、環簽名和群簽名的比較

(1)匿名性。都是一種個體代表群體簽名的體制,驗證者能驗證簽名為群體中某個成員所簽,但並不能知道為哪個成員,以達到簽名者匿名的作用。

(2)可追蹤性。群簽名中,群管理員的存在保證了簽名的可追蹤性。群管理員可以撤銷簽名,揭露真正的簽名者。環簽名本身無法揭示簽名者,除非簽名者本身想暴露或者在簽名中添加額外的信息。提出了一個可驗證的環簽名方案,方案中真實簽名者希望驗證者知道自己的身份,此時真實簽名者可以通過透露自己掌握的秘密信息來證實自己的身份。

(3)管理系統。群簽名由群管理員管理,環簽名不需要管理,簽名者只有選擇一個可能的簽名者集合,獲得其公鑰,然後公布這個集合即可,所有成員平等。

鏈喬教育在線旗下學碩創新區塊鏈技術工作站是中國教育部學校規劃建設發展中心開展的「智慧學習工場2020-學碩創新工作站 」唯一獲準的「區塊鏈技術專業」試點工作站。專業站立足為學生提供多樣化成長路徑,推進專業學位研究生產學研結合培養模式改革,構建應用型、復合型人才培養體系。

④ Solidity - 內存布局

在 Solidity - 引用類型 中提到,當沒有給局部變數的 uint[] storage p 賦值的時候, p 會默認指向 storage 的第一個 slot 。
首先, slot 的英文翻譯是指容器的插槽、投幣口,暫時先不解釋這個東西。先看看 storage ,官方對 storage 的解釋是

簡單理解就是, storage 是一個超大的數組,數組可以看成儲物櫃, slot 就是一個個的小櫃子。

其中每一個 slot 的大小是 32 位元組, slot0 的地址(即 storage 的起始地址)是 0x00 。Solidity對聲明時候沒有進行初始化的變數,都默認值為0。因此 p 作為一個指針,其中指針的值就是內存的地址(這點與C語言指針一樣),因此它會指向 slot0 。至於為什麼 a 的值變了,當然就是因為 a 存儲在了 slot0 。
下面整理一下 storage 內存布局的幾條規則:

items_arr 數組有三個元素,他們的內存佔用情況是,首先 struct items 的內存佔用是2位元組,然後按照一個 struct 佔用一個 slot 的話,那麼 items_arr 佔用了 3*32 的位元組,其中很多都浪費了。(這個其實我自己也不太肯定,因為使用Remix調試的時候,看不到 storage 內存詳情,也許要通過指令集來判斷,這里暫時存疑,以後驗證再補充。XXX)

arrays 有兩種類型,靜態長度 uint[3] 與動態長度 uint[] 。靜態長度的話,在編譯的時候,就可以確定他的內存佔用大小,因此可以提前分配。但是動態長度的 array ,他的元素大小是不確定的,因此需要使用別的方式來存儲動態長度的數組。舉個例子:

其中 a 的位置是 slot0 ,那叢握么 b 的位置是 slot1 , c 的位置是 slot2 , d 的位置是 slot3 - slot5 。沒蔽可以看到動長數組只佔用了一個 slot ,然後這個位置用來存放動長數組的長度,即 b.lenght 的值。動態數組的元素存儲在其他的位置,這個位置根據 keccak256() 方法計算出來,比如 b[1] 的位置就是 keccak256(1 . p) 。其中滲察慶 p 是 b 所在 slot1 的起始地址 0x32 (因為一個 slot 占 32 個位元組),另外 . 代表的是連接符。

Mappings 也會佔用一個 slot ,但是這個 slot 是空的,不記錄東西,用來做為尋找元素的 基址 ,定址方式則跟 Arrays 的一樣。

⑤ 密碼技術(七、二)之單向散列函數

單向散列函數
  ——獲取消息的「指紋」

 MD4是由Rivest 於1990年設計的單向散列函數,能夠產生128比特的散列值。不過,雖則Dobbertin提出尋找MD4散列碰撞方法,現在它已經不安全了。
 MD5是由Rivest於1991年設計的單向散列函數,能夠產生128比特的散列值。MD5的強抗碰撞性已經被攻破,也就是說,現在已經能夠產生具備相同散列值的兩條不同的消息,因此它也已經不安全了。
MD4和MD5的MD是消息摘要(Message Digest)的縮寫。

 SHA-1是由NIST(National Institue of Standards and Technology ,美國國家標准計算研究所)設計的一種能夠產生160比特的散列值的單向散列函數。1993年別作為美國聯邦信息處理標准規格發布的是SHA,1995年發布修訂版FIPS PUB 180-1稱為SHA-1。在《CRYPTREC密碼清單》中,SHA-1已經被列入「可謹慎運用的密碼清單」,即除了用於保持兼容性的目的以外,其他情況都不推薦使用。
 SHA-256、SHA-384和SHA512都是由NIST設計的單向散列函數,它們的散列值長度分別為256比特、384比特和512比特。這些單向散列函數合起來統稱為SHA-2,它們的消息長度也存在上限(中握SHA-256的上限近於2 64比特,SHA-384和SHA-512的上限接近於2 128比特 )。這些單詞散列函數式於2002年和SHA-1一起作為FIPS PUB 180-2發布的。
 SHA-1的臘哪強抗碰撞性已於2005年被攻破,也就是說,現在已經能夠產生具備相同散列值的兩條不同消息。不過SHA-2還尚未被攻破。
6種版本SHA-2

 RIPEMD 是與1996年由Hans Dobbertin、Antoon Bosselaers 和Bart Preneel 設計的一種能夠產生160比特的散列值單向散列函數。RIPEMD-160是歐盟RIPE項目所設計的RIPEMD單向散列函數的修訂版。這一系列的函數還包括RIPEMD-128、RIPEMD-256、RIPEMD-320等其他一些版本。在《CRYPTREC密碼清單》中,RIPEMD已經被列入「可謹慎運用的密碼清單」,即除了用於保持兼容性的目的以外,其他情況都不推薦使用。
 RIPEMD的強碰撞性已於2004年被攻破,但RIPEMD-160還尚未被攻破。比特幣中使用的就是RIPEMD-160。

 SHA-3(Secure Hash Algorithm-3)是一種作為新標准發布的單向散列函數演算法,用來替代在理論上已經被找出攻擊方法的SHA-1演算法。全世界的企業和密碼學家提交了SHA-3的候選方案很多,經過5年的選拔,最終在2013年正式確定了將Keccak演算法作為SHA-3的標准。
Keccak最終被選為SHA-3的理由如下:

 Keccak是一種被選定為SHA-3標準的單向散列函數演算法。
 Keccak可以生成任意長度的散列值,但是為了配合SHA-2的散列值長度,SHA-3標准中共規定了SHA3-224、SHA-3-256、SHA3-384、SHA3-512這4個版本。在輸入數據的長度上限方面,SHA-1為2 64-1比特,SHA-2為2 128-1比特,而SHA-3則沒有限制。
 此外FIPS202中還規定了兩個賣局慶可輸出任意長度散列值的函數(extendable-output function,XOF),分別為SHAKE128和SHAKE256。據說SHAKE這個名字取自Secure Hash Algorithm 與Keccak這幾個單詞。

 Keccak採用了海綿結構,輸入的數據在進行填充後,要經過 吸收階段 擠出階段 ,最終生成輸出的散列值。
並且作為海綿結構的變形, Keccak中還提出了一種雙共結構。
這里關於 Keccak的結構,不做過多解讀,想詳細了解,請參考原著;

暴力破解
任何文件中都或多或少存在具有一定的冗餘性。利用文件的冗餘性生產具有相同散列值的另一個文件,這就是一種針對單向散列函數的攻擊。
在對密碼進行暴力破解時,我們就是按照順序改變密鑰,如0、1、2、3.....然後分別用這些密鑰進行解密的,對單向散列函數進行暴力破解也是如此,即每次都稍微改變一下消息的值,然後對這些消息求散列值。
現在我們在尋找的是一條具備特定散列值的消息,具備相同散列值的另一條不同的消息。這相當於一種 試圖破解單向散列函數的「弱碰撞性」的攻擊 。在這種情況下,暴力破解需要嘗試的次數,可以根據散列值的長度計算出來,以SHA3-512為例,由於它的散列值長度為512比特,因此最多隻需要嘗試2^512次就能找到目標消息了,如此多的嘗試次數在現實中是不可能完成的。
由於嘗試次數純粹是由散列值的長度決定的,因此散列值的長度越長的單向散列函數,其抵禦暴力破解的能力也就越強。
找出具有指定散列值的消息的攻擊方式分為兩種,即「原像攻擊」和「第二原像攻擊」。 原像攻擊 (Pre-Image Attack)是指定一個散列值,找出具有該散列值的任意消息; 第二原像攻擊 (Second Pre-Image Attack)是指定一條消息1,找出另外一條消息2,消息2的散列值和消息1相同。

生日攻擊
要找到散列值相同的兩條消息,而散列值則可以是任意值。這樣的攻擊,一般稱為 生日攻擊 (birthday attack)或是 沖突攻擊 (collision attack),這是一種 試圖破解單向散列函數的「強碰撞性」 攻擊。
我們以512比特的散列值為例,對單向散列函數進行暴力破解所需要的嘗試次數2^512 次,而對同一單向散列函數進行生日攻擊所需要嘗試的次數2^256次,因此和暴力破解相比,生日攻擊所嘗試的次數要少的多。

單向散列函數能夠辨別出「篡改」,但無法辨別出「偽裝」。
當我們不僅需要確認文件的完整性,同時還需要確認這個文件是否真的屬於他的,我們還需要認證。

該系列的主要內容來自《圖解密碼技術第三版》
我只是知識的搬運工
文章中的插圖來源於原著