那把key的參數是
p=FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 FFFFFFFF FFFFFFFF" g=2
先把它轉成der格式
package require asn package require math::bignum set p " FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 FFFFFFFF FFFFFFFF" set p [::math::bignum::fromstr 0x[string tolower [join [split $p " \n"] ""]]] set key "" append key [::asn::asnBigInteger $p] append key [asn::asnInteger 2] set key [::asn::asnSequence $key] set fd [open dh_der w] fconfigure $fd -translation binary puts -nonewline $fd $key
再丟給openssl去跑一下,檢查順便轉檔
the g value is not a generator !!
於是爬了一下source code
在openssl\crypto\dh\dh_check.c裡
int DH_check(const DH *dh, int *ret)
當g=2時,檢查 p mod 24 == 11
在openssl\crypto\dh\dh_gen.c的註解裡有更詳細的挑選方法說明
敗了一下google大神
整理以下心得
1.generator
意思是 g^n mod p 可以產生出 1~(p-1)的結果,而snmpv3用的這一組數字在g^((p-1)/2) mod p 就是 1 了,只能生成一半的數字
雖然DH演算法不一定要g是個generator,不過openssl實作時會挑generator
2.safe prime
若 \(p\) 是質數,\(p=2q+1\),\(q\) 也是質數,\(p\) 就是 safe prime
3. generator 驗證方法
當 \(p\) 選擇為 save prime 時可以用以下方法驗證 \(g\) 是否為 generator (*1)
\(g^2 \mod p \neq 1\)
\(g^{(p-1)/2} \mod p \neq 1\)
若符合兩式 \(q\) 就是 generator
當\(g=2\)時,可以用以下方法驗證 (*2)
\(p \mod 24 == 11,q\) 是 generator
\(p \mod 24 == 23,q\) 不是 generator
4.是否為 generator 的比較
generator : 可以生成所有的值,但可以輕易知道private key的 1 個 bit(LSB),openssl 用這種方式 (*3)
非generator : 只能生成一半的值,無法輕易知道private key的任何bit,snmpv3 選的是這一種
(*1)
\(p=2q+1\),\(p,q\)為質數
\(g^{(p-1)} \equiv 1 \pmod p\)
\(g^{2q} \equiv 1 \pmod p\)
\(g^2 g^q \equiv 1 \pmod p\)
這時只要檢查
\(g^2 \mod p \neq 1\)
\(g^q \mod p \neq 1\)
即可
證明:
假設存在 \(x ,1 < x < 2q\)
\(g^x \equiv g^{2q} \equiv 1 \pmod p\)
則 \(2q\) 可以寫成 \(k_1 x + r_1\),(這邊及以下的值符合正整數除法規則)
\(g^x \equiv g^{k_1x+r_1} \equiv g^{r_1} \equiv 1 \pmod p\)
則 \(x\) 可以寫成 \(k_2 r_1 + r_2\)
\(g^{k_2 r_1 + r_2} \equiv g^{r_2} \equiv g^{r_1} \equiv 1 \pmod p\)
重複這個步驟(輾轉相除法),最後會得到\(\gcd (x,2q)\)
\(g^{\gcd (x,2q)} \equiv 1 \pmod p\)
因為\(2,q\)都是質數
若\(x \neq 2, x \neq q \Rightarrow \gcd (x,2q)=1\)
\(g \equiv 1 \pmod p\)
\(g=1\),我們不會選1來當key
所以\(x=2\) 或 \(x=q\) \(\gcd (x,2q) = 2 \text{或} q \)
所以只要檢查\(g^2 , g^q\)即可
(*2) RFC4419 section-6.1有提到這個檢查方法
(*3)
Diffie-Hellman Parameter Check (when g = 2, must p mod 24 == 11?)
當 \(g\) 是 generator 可求出 private key (x) 的 LSB
public key (C) 就是
\(C=g^x \mod p\)
透過以下計算
\(C^{(p-1)/2} \mod p\)
\(\Rightarrow g^{x (p-1)/2} \mod p\)
就能分辨出\(x\) 為奇數或偶數,相當於得知LSB
令\(x=2n+r\)
\(g^{x(p-1)/2}\)
\(= g^{(2n+r)(p-1)/2}\)
\(= g^{(2n+r)(p-1)/2}\)
\(= g^{n(p-1)}g^{r(p-1)/2}\)
則源式可寫成
\(g^{n(p-1)}g^{r(p-1)/2} \mod p\)
因為 \(p\) 是質數
\(= g^{(p-1)} \equiv 1\pmod p\)
所以可以化簡成
\(g^{r(p-1)/2} \mod p\)
\(r=0\)時,結果為\(1\)
\(r=1,\)時,
\(g^{(p-1)/2} \mod p \neq 1\)
因為 \(g\) 是 generator
透過這個運算,就能輕易得知 private key 的 1 個 bit
沒有留言:
張貼留言