精華區beta java 關於我們 聯絡資訊
※ 引述《prodigywu (Soccer Fever)》之銘言: : 我希望server client彼此互相傳遞訊息前 : 都先將訊息加密傳出去 : 對方收到後再解密 : 但是有點疑惑需要解答 : 我想用JCE的DES來加密 : 那我勢必要把key送給對方 : 可是要怎麼樣才能把key安全的送給對方呢? : 第二個問題是說 : 產生key的過程會很耗時間嗎? : 我的server跟client會大量地互相交換訊息(字串的長度都不會很大) : 如果每傳一個訊息就產生一個新的key : overhead會不會很大呢? : 感謝回答~ 我比較熟SSHv2 你可以考慮他的作法, 也比較多RFC可以啃, 比較不會無聊 首先SSHv2一般來說required的基本加密演算法是用3DES //************************************************************ * * 有鑑於有人問我說3DES跟AES哪一個才是SSH的base encrypion alg. * * 我在這附上RFC4253的部分段落: * * The following ciphers are currently defined: * * 3des-cbc REQUIRED three-key 3DES in CBC mode * blowfish-cbc OPTIONAL Blowfish in CBC mode * twofish256-cbc OPTIONAL Twofish in CBC mode, * with a 256-bit key * twofish-cbc OPTIONAL alias for "twofish256-cbc" * (this is being retained * for historical reasons) * twofish192-cbc OPTIONAL Twofish with a 192-bit key * twofish128-cbc OPTIONAL Twofish with a 128-bit key * aes256-cbc OPTIONAL AES in CBC mode, * with a 256-bit key * aes192-cbc OPTIONAL AES with a 192-bit key * aes128-cbc RECOMMENDED AES with a 128-bit key * serpent256-cbc OPTIONAL Serpent in CBC mode, with * a 256-bit key * serpent192-cbc OPTIONAL Serpent with a 192-bit key * serpent128-cbc OPTIONAL Serpent with a 128-bit key * arcfour OPTIONAL the ARCFOUR stream cipher * with a 128-bit key * idea-cbc OPTIONAL IDEA in CBC mode * cast128-cbc OPTIONAL CAST-128 in CBC mode * none OPTIONAL no encryption; NOT RECOMMENDED ***********************************************************************// 3DES是什麼? 就是DES->DES->DES key拆成三段, 各分給三段的DES去用 (先記得一個原則, DES block size = 8 byte : 64 bits) 好 SSH因為是一種protocol, 設計上會嚴密一點, 流程上或許會有許多你覺得不必要的 你可以自行考慮增減 1. 互丟SSH版本識別字串 一個明碼封包, 其中包含protocol, 版本, 及其他, SSH所使用的識別字串如下: SSH-protoversion-softwareversion SP comments CR LF 這樣可能沒人看得懂, 我舉個例子給您: SSH-2.0-MC18openSSH-v18 just4test <CR><LF> SSH 協定編號 版本名稱及版號 空格 註記 換行(CR LF,可查ASCII表) 2. key exchange演算法溝通 雙方會開始溝通所擁有的演算法及預測對方會使用的演算法, 當然這個步驟在您的 case可以直接跳過, 就假設大家都用Diffie-Hellman key exchange 以及3DES-CBC, SHA-1, DSA 但為了第三個步驟的驗證, 我建議你可以雙方互傳一組隨機的變數array 例如Server傳出: FFAAFFAAFFAA Client傳出: 001100110011 (每次連線初始化都隨機產生) 3. key exchange 這部分有點雜, 但J2SE有API可以用, 如果你考慮到完整的安全性, 可考慮SSH 的RFC文件 (沒記錯是4253) 以下S是指Server, C為Client p為一個非常大的質數,心情好的話可以自己選,心情不好就用Second Oakley Group 那個數字很大, 所以麻煩自己去goo一下那個數字, 一大串的16進位用BigInter存 q別管他, 總之q別比p還大 g可以選2比較保險(如果你選用Second Oakley Group的話) [註]g全名為generator, 以目前的數學技術而言, 沒有一個很明確的方法可以 找出generator, 在一個GF(p)中 (anyway, 你可以無視這句話,總之g別亂選 1. C產生一個隨機數 x ( 1 < x < q)並計算出e=g^x mod p. 並將e發送給S 2. S產生一個隨機數y (0 < y < q)並計算出f = g^y mod p. 3. S收到e之後, 計算e^y mod p, 並產生一個Hash H, 以你的case而言H結構雙方是要相同的, 且一定要包含步驟2的隨機數,及步驟1個 識別字串,其他結構隨你心情增減, 這個H最主要用處在於驗證你步驟1到3是在跟同一台機器對話 4. S在這個H上簽上自己的private key, 並將剛剛記算出的f, public key, 及簽完的sign s一起送給C 5. 在你的case中你可以在C的local database記錄S的public key 在收到S傳來的資訊後, 首先驗證public key是否來自正確的S 6. C計算出共用金鑰K, K=f^x mod p, 並用Server的public key確定sign是否正確 這六個步驟要注意的是, H必須雙方自行紀錄, S在這六個步驟中不會傳H給C C必須自己記錄好整個傳輸過程中的關鍵資訊, 並定義好雙方的格式 (多一個byte都會讓sign差個十萬八千里) 如何用DSA驗證, 我這裡提供一點點演算法, 實際做法可以去goo看看 上述的第4 5步驟中收到的public key(簡寫為K_S)及s分別包括以下內容: s = {p|q|g|y}, 在SSH中屬於mpint, 你可以定義你自己的封包格式 K_S則為一個40byte的憑證資訊(假設演算法為SHA1), 前20個byte為r 後20為s 好了, 再來握好你的LP, 參考一下以下這堆很討人厭的演算法: 1. 計算w=(s)* mod q // *代表inverse 2. 計算u1=(H(m)w) mod q 3. 計算uw=(rw) mod q 4. 計算v=(((g^u1)(y^u2)) mod p ) mod q 5. 這時候你可以鬆開你的LP, 比對看看v是不是等於r, 成立則得證,反之則reject ok 這個步驟之後, 你就得到一個雙方都擁有的share key K, 就用這個K來加密即可 必要的話可以再對這組key做一點處理, 如果要用DES-CBC的話必須用這組key再生出 幾組init.用的KEY, 這部份我不是記得那麼清楚了, 所以就不亂唬爛了 以上如果你很有耐心的看完了, 那我相信你有了一點基本的認知, 那你可以開始去找 可以用的API來用, 也不用握著LP寫程式 我在手機上run的經驗來說, 因為我沒建public key認證機制, 所以每次連線都 要重新溝通, 但以實際上機測試效果來說, 頂多delay約3秒而已, 模擬器基本上 也不太會有太嚴重的delay, 你可以放心的使用, 只要在加解密的演算法上小心點 就好. 一點點經驗與您分享, 希望能給您一點點幫助, 雖然有點離題XD -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.175.27.54
mc18:對不起錯字有點多 懶得改了@@ 看不懂再問吧 @@ 03/12 00:57
※ 編輯: mc18 來自: 218.175.27.54 (03/12 01:11)