Skip to content

Commit 97b8412

Browse files
Easonwang01Easonwang01
Easonwang01
authored and
Easonwang01
committed
Add description
1 parent ed5301e commit 97b8412

10 files changed

+1039
-1
lines changed

1.1 密碼雜湊.md renamed to 1.1 Bcrypt、PBKDF2、Scrypt、Argon2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ hash的過程會加入一個隨機的salt,然後salt跟password一起hash。
1212

1313
以下為在2GHz core上的耗費時間表:
1414

15-
![](https://easonwang01.gitbooks.io/blockchain-and-cryptography/content/assets/螢幕快照 2018-01-28 下午12.06.21.png)
15+
![](https://easonwang01.gitbooks.io/blockchain-and-cryptography/content/assets/%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202018-01-28%20%E4%B8%8B%E5%8D%8812.06.21.png)
1616

1717
再來你可能會想既然每次產生的Hash不同,那要怎麼進行訊息驗證呢?
1818

File renamed without changes.
File renamed without changes.

3. 非對稱式加密.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# 非對稱式加密 \( Asymmetric Encryption \)
2+
3+
相較於對稱式加密的加解密使用同一把金鑰,非對稱式加密採用公鑰與私鑰機制,公鑰是可公開的,而私鑰是不公開的,只有擁有私鑰的人才可解開密文或是進行訊息驗證。所以非對稱式加密也稱為**公開金鑰加密**
4+
5+
任何人都可以使用公鑰加密明文,但只有對應的私鑰持有者才可以解密得到明文。
6+
7+
應用:
8+
9+
1.公鑰加密 私鑰解密
10+
11+
```
12+
可想像為把公鑰在網路上傳播讓大家可以用公鑰對一份訊息加密,之後把加密訊息發送給你,你在用對應那把公鑰的私鑰解開訊息。
13+
```
14+
15+
2.私鑰加密 公鑰解密
16+
17+
```
18+
用在簽名驗證方面,假設A擁有私鑰並對一個文件加密產生了一個簽名字串,這時其他任何擁有公鑰的人都可以去解密,
19+
並且由於只有擁有私鑰的A才能加密出可以被公鑰解密的字串,所以就可以確認訊息是由A發出的。
20+
```
21+
22+
> 上面第二點的問題在於假設在B身上之A的公鑰被壞人給替換了,並且壞人用他的公鑰假裝是A的公鑰然後傳給B,之後壞人用他的私鑰傳送訊息給B,這時B用壞人的公鑰一樣可以解開訊息,這時將會以為訊息還是由A所發出的。
23+
24+
要解決此問題就需要一個驗證公鑰的機構,驗證B身上的公鑰確實是屬於A的公鑰。
25+
26+
這時可以找**憑證中心** \( certificate authority \),也稱為 CA,來幫公鑰做認證。**憑證中心**用自己的私鑰,對 A 的公鑰和一些相關資訊一起加密,生成**數位憑證**(Digital Certificate),之後 A 在傳遞訊息時需要同時附上此**數位憑證**
27+
28+
B 收到 A 傳來的訊息後訊息後用 CA 的公鑰解開**數位憑證**,就可以拿到 A 真正的公鑰。就不怕再被壞人替換公鑰了。
29+
30+
當 B 想私密傳送訊息給 A 時,可以用 A 的公鑰將訊息加密,A 收到加密訊息後用自己的私鑰再將訊息解密。以上也是目前瀏覽器之HTTPS 運作之簡單原理。
31+
32+
常見的非對稱式金鑰演算法包含:RSA、DSA、ECDSA、Diffie–Hellman \( DH \) 、ECDH等等。
33+
34+
RSA、DSA、DH 等加密演算法目前建議使用2048bits以上之金鑰長度,ECDSA 與 ECDH 之金鑰長度則至少為 224 bits。
35+

3.1 RSA.md

Whitespace-only changes.

3.2 DSA.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# DSA \( Digital Signature Algorithm \)
2+
3+
在1991年DSA 演算法被採納作為**Digital Signature Standard **\( **DSS **\)** **數位簽名標準之演算法。
4+
5+
DSA 的安全性是基於整數有限域離散對數之難題。
6+
7+
```
8+
假設在Fp域上,已知a,t,可快速計算 (a ** t) mod p
9+
但是假設已知a,b,欲求t ,則 a ** t = b mod p 則較難求解。
10+
```
11+
12+
#### 參數選擇
13+
14+
```
15+
1. 選擇一個Hash function 當作H (e.g.SHA系列)
16+
17+
2. 選擇 L 和 N 的長度 FIPS 186-3 選定了 L 和 N 長度對為 (1024, 160), (2048, 224), (2048, 256), (3072, 256)。
18+
N 必須小於等於 Hash function H 產生出來的長度.
19+
20+
3. 選擇一個 N-bit 的質數 q ( N 即為剛才選的數字)
21+
22+
4. 選擇 L-bit 的質數 p ( L 即為剛才選的數字),並且 p − 1 是 q 的倍數
23+
```
24+
25+
最後選擇一個 g ,滿足 $$g^q $$ = 1 mod p
26+
27+
之後這三個參數\(p, g, q\)可以公開分享。
28+
29+
#### 公鑰與私鑰
30+
31+
```
32+
在0 < x < q 條件下任選一個適合長度的私鑰 x
33+
```
34+
35+
之後公鑰即為$$y = g^x$$ mod p
36+
37+
#### 簽名
38+
39+
```
40+
1. 在1 < k < q 條件下隨機產生一個k
41+
2. 計算r, r = ((g ** k) mod p) mod q,假設r算出來為0則換一個k再算一次
42+
3. 計算s, s = ((k ** -1) * (H(m) + xr)) mod q,假設s算出來為0則換一個k再算一次
43+
```
44+
45+
得到簽名為\(r, s\)
46+
47+
#### 驗證
48+
49+
```
50+
1. 如果0 < r < q或是0 < s < q則拒絕
51+
2. 計算w, w = (s ** -1) mod q
52+
3. 計算u1,u1 = H(m) * w mod q
53+
4. 計算u2,u2 = (r * w) mod q
54+
```
55+
56+
最後計算 v
57+
58+
![](https://easonwang01.gitbooks.io/blockchain-and-cryptography/content/assets/%E8%9E%A2%E5%B9%95%E5%BF%AB%E7%85%A7%202018-01-07%20%E4%B8%8A%E5%8D%8811.50.11.png)
59+
60+
如果算出之 v = r 則驗證成功。
61+
62+
# 實際應用
63+
64+
# 使用OpenSSL
65+
66+
> 查看相關指令
67+
68+
```
69+
openssl gendsa
70+
```
71+
72+
![](https://easonwang01.gitbooks.io/blockchain-and-cryptography/content/assets/94.png)
73+
74+
1.產生一個1024bits的參數檔案
75+
76+
```
77+
openssl dsaparam -out dsa_param.pem 1024
78+
```
79+
80+
2.從剛才的參數檔案產生一個private key 並且用AES-128之加密也可用AES-192或AES-256
81+
82+
> 密碼長度至少四位數
83+
84+
```
85+
openssl gendsa -out dsa_privatekey.pem -aes128 dsa_param.pem
86+
```
87+
88+
> 如出現 unable to write ''random state" 之訊息,可參考此
89+
>
90+
> [https://stackoverflow.com/questions/94445/using-openssl-what-does-unable-to-write-random-state-mean](https://stackoverflow.com/questions/94445/using-openssl-what-does-unable-to-write-random-state-mean)
91+
92+
3.接著再從私鑰產生一把公鑰
93+
94+
```
95+
openssl dsa -in dsa_privatekey.pem -pubout -out dsa_publickey.pem
96+
```
97+
98+
4.之後我們新增一個我們要用來簽章的文件 ,並且在裡面寫一點字
99+
100+
```
101+
echo test > document.txt
102+
```
103+
104+
然後用私鑰對文件簽章產生一個sig檔案
105+
106+
```
107+
openssl dgst -dss1 -sign dsa_privatekey.pem -out document.sig document.txt
108+
```
109+
110+
5.最後用公鑰驗證
111+
112+
```
113+
openssl dgst -dss1 -verify dsa_publickey.pem -signature document.sig document.txt
114+
```
115+
116+
![](https://easonwang01.gitbooks.io/blockchain-and-cryptography/content/assets/89a.png)
117+
118+
## 使用Node.js
119+
120+
> 完成以上步驟產生pem格式之公私鑰後可執行以下程式。
121+
122+
```js
123+
const fs = require('fs');
124+
const crypto = require('crypto');
125+
126+
const privateKey = {key: fs.readFileSync('./dsa_privatekey.pem'), passphrase: "填入剛才輸入的密碼"};
127+
const publicKey = fs.readFileSync('./dsa_publickey.pem');
128+
129+
let sign = crypto.createSign('dsaWithSHA1');
130+
sign.update('apple');
131+
132+
// 注意 這裡是用私鑰簽名,如果用公鑰會出現錯誤
133+
let res = sign.sign(privateKey, 'hex');
134+
135+
let verify = crypto.createVerify('dsaWithSHA1');
136+
verify.update('apple');
137+
138+
let result = verify.verify(publicKey, res, "hex");
139+
140+
console.log(result); // Prints success. means the key pair works.
141+
```
142+
143+
144+

0 commit comments

Comments
 (0)