BlogJava 聯系 聚合 管理  

          Blog Stats

          隨筆檔案


          bitmap

          bitmap

          接下來我們分析DH加密算法,一種適基于密鑰一致協議的加密算法。
          DH
          Diffie-Hellman算法(D-H算法),密鑰一致協議。是由公開密鑰密碼體制的奠基人Diffie和Hellman所提出的一種思想。簡單的說就是允許兩名用戶在公開媒體上交換信息以生成"一致"的、可以共享的密鑰。換句話說,就是由甲方產出一對密鑰(公鑰、私鑰),乙方依照甲方公鑰產生乙方密鑰對(公鑰、私鑰)。以此為基線,作為數據傳輸保密基礎,同時雙方使用同一種對稱加密算法構建本地密鑰(SecretKey)對數據加密。這樣,在互通了本地密鑰(SecretKey)算法后,甲乙雙方公開自己的公鑰,使用對方的公鑰和剛才產生的私鑰加密數據,同時可以使用對方的公鑰和自己的私鑰對數據解密。不單單是甲乙雙方兩方,可以擴展為多方共享數據通訊,這樣就完成了網絡交互數據的安全通訊!該算法源于中國的同余定理——中國馀數定理。 

          流程分析:

          1.甲方構建密鑰對兒,將公鑰公布給乙方,將私鑰保留;雙方約定數據加密算法;乙方通過甲方公鑰構建密鑰對兒,將公鑰公布給甲方,將私鑰保留。
          2.甲方使用私鑰、乙方公鑰、約定數據加密算法構建本地密鑰,然后通過本地密鑰加密數據,發送給乙方加密后的數據;乙方使用私鑰、甲方公鑰、約定數據加密算法構建本地密鑰,然后通過本地密鑰對數據解密。
          3.乙方使用私鑰、甲方公鑰、約定數據加密算法構建本地密鑰,然后通過本地密鑰加密數據,發送給甲方加密后的數據;甲方使用私鑰、乙方公鑰、約定數據加密算法構建本地密鑰,然后通過本地密鑰對數據解密。


          通過java代碼實現如下:
          import java.security.Key;   
          import java.security.KeyFactory;   
          import java.security.KeyPair;   
          import java.security.KeyPairGenerator;   
          import java.security.PublicKey;   
          import java.security.spec.PKCS8EncodedKeySpec;   
          import java.security.spec.X509EncodedKeySpec;   
          import java.util.HashMap;   
          import java.util.Map;   
            
          import javax.crypto.Cipher;   
          import javax.crypto.KeyAgreement;   
          import javax.crypto.SecretKey;   
          import javax.crypto.interfaces.DHPrivateKey;   
          import javax.crypto.interfaces.DHPublicKey;   
          import javax.crypto.spec.DHParameterSpec;   
            
          /**  
           * DH安全編碼組件  
           *   
           * 
          @author 梁棟  http://www.bt285.cn http://www.5a520.cn
           * 
          @version 1.0  
           * 
          @since 1.0  
           
          */
            
          public abstract class DHCoder extends Coder {   
              
          public static final String ALGORITHM = "DH";   
            
              
          /**  
               * 默認密鑰字節數  
               *   
               * <pre>  
               * DH  
               * Default Keysize 1024    
               * Keysize must be a multiple of 64, ranging from 512 to 1024 (inclusive).  
               * </pre>  
               
          */
            
              
          private static final int KEY_SIZE = 1024;   
            
              
          /**  
               * DH加密下需要一種對稱加密算法對數據加密,這里我們使用DES,也可以使用其他對稱加密算法。  
               
          */
            
              
          public static final String SECRET_ALGORITHM = "DES";   
              
          private static final String PUBLIC_KEY = "DHPublicKey";   
              
          private static final String PRIVATE_KEY = "DHPrivateKey";   
            
              
          /**  
               * 初始化甲方密鑰  
               *   
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static Map<String, Object> initKey() throws Exception {   
                  KeyPairGenerator keyPairGenerator 
          = KeyPairGenerator   
                          .getInstance(ALGORITHM);   
                  keyPairGenerator.initialize(KEY_SIZE);   
            
                  KeyPair keyPair 
          = keyPairGenerator.generateKeyPair();   
            
                  
          // 甲方公鑰   
                  DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();   
            
                  
          // 甲方私鑰   
                  DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();   
            
                  Map
          <String, Object> keyMap = new HashMap<String, Object>(2);   
            
                  keyMap.put(PUBLIC_KEY, publicKey);   
                  keyMap.put(PRIVATE_KEY, privateKey);   
                  
          return keyMap;   
              }
             
            
              
          /**  
               * 初始化乙方密鑰  
               *   
               * 
          @param key  
               *            甲方公鑰  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static Map<String, Object> initKey(String key) throws Exception {   
                  
          // 解析甲方公鑰   
                  byte[] keyBytes = decryptBASE64(key);   
                  X509EncodedKeySpec x509KeySpec 
          = new X509EncodedKeySpec(keyBytes);   
                  KeyFactory keyFactory 
          = KeyFactory.getInstance(ALGORITHM);   
                  PublicKey pubKey 
          = keyFactory.generatePublic(x509KeySpec);   
            
                  
          // 由甲方公鑰構建乙方密鑰   
                  DHParameterSpec dhParamSpec = ((DHPublicKey) pubKey).getParams();   
            
                  KeyPairGenerator keyPairGenerator 
          = KeyPairGenerator   
                          .getInstance(keyFactory.getAlgorithm());   
                  keyPairGenerator.initialize(dhParamSpec);   
            
                  KeyPair keyPair 
          = keyPairGenerator.generateKeyPair();   
            
                  
          // 乙方公鑰   
                  DHPublicKey publicKey = (DHPublicKey) keyPair.getPublic();   
            
                  
          // 乙方私鑰   
                  DHPrivateKey privateKey = (DHPrivateKey) keyPair.getPrivate();   
            
                  Map
          <String, Object> keyMap = new HashMap<String, Object>(2);   
            
                  keyMap.put(PUBLIC_KEY, publicKey);   
                  keyMap.put(PRIVATE_KEY, privateKey);   
            
                  
          return keyMap;   
              }
             
            
              
          /**  
               * 加密<br>  
               *   
               * 
          @param data  
               *            待加密數據  
               * 
          @param publicKey  
               *            甲方公鑰  
               * 
          @param privateKey  
               *            乙方私鑰  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static byte[] encrypt(byte[] data, String publicKey,   
                      String privateKey) 
          throws Exception {   
            
                  
          // 生成本地密鑰   
                  SecretKey secretKey = getSecretKey(publicKey, privateKey);   
            
                  
          // 數據加密   
                  Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());   
                  cipher.init(Cipher.ENCRYPT_MODE, secretKey);   
            
                  
          return cipher.doFinal(data);   
              }
             
            
              
          /**  
               * 解密<br>  
               *   
               * 
          @param data  
               *            待解密數據  
               * 
          @param publicKey  
               *            乙方公鑰  
               * 
          @param privateKey  
               *            乙方私鑰  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static byte[] decrypt(byte[] data, String publicKey,   
                      String privateKey) 
          throws Exception {   
            
                  
          // 生成本地密鑰   
                  SecretKey secretKey = getSecretKey(publicKey, privateKey);   
                  
          // 數據解密   
                  Cipher cipher = Cipher.getInstance(secretKey.getAlgorithm());   
                  cipher.init(Cipher.DECRYPT_MODE, secretKey);   
            
                  
          return cipher.doFinal(data);   
              }
             
            
              
          /**  
               * 構建密鑰  
               *   
               * 
          @param publicKey  
               *            公鑰  
               * 
          @param privateKey  
               *            私鑰  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          private static SecretKey getSecretKey(String publicKey, String privateKey)   
                      
          throws Exception {   
                  
          // 初始化公鑰   
                  byte[] pubKeyBytes = decryptBASE64(publicKey);   
            
                  KeyFactory keyFactory 
          = KeyFactory.getInstance(ALGORITHM);   
                  X509EncodedKeySpec x509KeySpec 
          = new X509EncodedKeySpec(pubKeyBytes);   
                  PublicKey pubKey 
          = keyFactory.generatePublic(x509KeySpec);   
            
                  
          // 初始化私鑰   
                  byte[] priKeyBytes = decryptBASE64(privateKey);   
            
                  PKCS8EncodedKeySpec pkcs8KeySpec 
          = new PKCS8EncodedKeySpec(priKeyBytes);   
                  Key priKey 
          = keyFactory.generatePrivate(pkcs8KeySpec);   
            
                  KeyAgreement keyAgree 
          = KeyAgreement.getInstance(keyFactory   
                          .getAlgorithm());   
                  keyAgree.init(priKey);   
                  keyAgree.doPhase(pubKey, 
          true);   
            
                  
          // 生成本地密鑰   
                  SecretKey secretKey = keyAgree.generateSecret(SECRET_ALGORITHM);   
            
                  
          return secretKey;   
              }
             
            
              
          /**  
               * 取得私鑰  
               *   
               * 
          @param keyMap  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static String getPrivateKey(Map<String, Object> keyMap)   
                      
          throws Exception {   
                  Key key 
          = (Key) keyMap.get(PRIVATE_KEY);   
            
                  
          return encryptBASE64(key.getEncoded());   
              }
             
            
              
          /**  
               * 取得公鑰  
               *   
               * 
          @param keyMap  
               * 
          @return  
               * 
          @throws Exception  
               
          */
            
              
          public static String getPublicKey(Map<String, Object> keyMap)   
                      
          throws Exception {   
                  Key key 
          = (Key) keyMap.get(PUBLIC_KEY);   
            
                  
          return encryptBASE64(key.getEncoded());   
              }
             
          }
            
          再給出一個測試類:
          import static org.junit.Assert.*;   
            
          import java.util.Map;   
            
          import org.junit.Test;   
            
          /**  
           *   
           * 
          @author 梁棟  http://www.bt285.cn http://www.feng123.com
           * 
          @version 1.0  
           * 
          @since 1.0  
           
          */
            
          public class DHCoderTest {   
            
              @Test  
              
          public void test() throws Exception {   
                  
          // 生成甲方密鑰對兒   
                  Map<String, Object> aKeyMap = DHCoder.initKey();   
                  String aPublicKey 
          = DHCoder.getPublicKey(aKeyMap);   
                  String aPrivateKey 
          = DHCoder.getPrivateKey(aKeyMap);   
            
                  System.err.println(
          "甲方公鑰:\r" + aPublicKey);   
                  System.err.println(
          "甲方私鑰:\r" + aPrivateKey);   
                     
                  
          // 由甲方公鑰產生本地密鑰對兒   
                  Map<String, Object> bKeyMap = DHCoder.initKey(aPublicKey);   
                  String bPublicKey 
          = DHCoder.getPublicKey(bKeyMap);   
                  String bPrivateKey 
          = DHCoder.getPrivateKey(bKeyMap);   
                     
                  System.err.println(
          "乙方公鑰:\r" + bPublicKey);   
                  System.err.println(
          "乙方私鑰:\r" + bPrivateKey);   
                     
                  String aInput 
          = "abc ";   
                  System.err.println(
          "原文: " + aInput);   
            
                  
          // 由甲方公鑰,乙方私鑰構建密文   
                  byte[] aCode = DHCoder.encrypt(aInput.getBytes(), aPublicKey,   
                          bPrivateKey);   
            
                  
          // 由乙方公鑰,甲方私鑰解密   
                  byte[] aDecode = DHCoder.decrypt(aCode, bPublicKey, aPrivateKey);   
                  String aOutput 
          = (new String(aDecode));   
            
                  System.err.println(
          "解密: " + aOutput);   
            
                  assertEquals(aInput, aOutput);   
            
                  System.err.println(
          " ===============反過來加密解密================== ");   
                  String bInput 
          = "def ";   
                  System.err.println(
          "原文: " + bInput);   
            
                  
          // 由乙方公鑰,甲方私鑰構建密文   
                  byte[] bCode = DHCoder.encrypt(bInput.getBytes(), bPublicKey,   
                          aPrivateKey);   
            
                  
          // 由甲方公鑰,乙方私鑰解密   
                  byte[] bDecode = DHCoder.decrypt(bCode, aPublicKey, bPrivateKey);   
                  String bOutput 
          = (new String(bDecode));   
            
                  System.err.println(
          "解密: " + bOutput);   
            
                  assertEquals(bInput, bOutput);   
              }
             
            
          }
            
          控制臺輸出:
          1. 甲方公鑰:   
          2. MIHfMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHz   
          3. W5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSG   
          4. kx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANDAAJAdAWBVmIzqcko   
          5. Ej6qFjLDL2+Y3FPq1iRbnOyOpDj71yKaK1K+FhTv04B0zy4DKcvAASV7/Gv0W+bgqdmffRkqrQ==   
          6.   
          7. 甲方私鑰:   
          8. MIHRAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYX   
          9. rgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpD   
          10. TWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQyAjACJRfy1LyR   
          11. eHyD+4Hfb+xR0uoIGR1oL9i9Nk6g2AAuaDPgEVWHn+QXID13yL/uDos=   
          12.   
          13. 乙方公鑰:   
          14. MIHfMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYXrgHz   
          15. W5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpDTWSG   
          16. kx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgANDAAJAVEYSfBA+I9nr   
          17. dWw3OBv475C+eBrWBBYqt0m6/eu4ptuDQHwV4MmUtKAC2wc2nNrdb1wmBhY1X8RnWkJ1XmdDbQ==   
          18.   
          19. 乙方私鑰:   
          20. MIHSAgEAMIGXBgkqhkiG9w0BAwEwgYkCQQD8poLOjhLKuibvzPcRDlJtsHiwXt7LzR60ogjzrhYX   
          21. rgHzW5Gkfm32NBPF4S7QiZvNEyrNUNmRUb3EPuc3WS4XAkBnhHGyepz0TukaScUUfbGpqvJE8FpD   
          22. TWSGkx0tFCcbnjUDC3H9c9oXkGmzLik1Yw4cIGI1TQ2iCmxBblC+eUykAgIBgAQzAjEAqaZiCdXp   
          23. 2iNpdBlHRaO9ir70wo2n32xNlIzIX19VLSPCDdeUWkgRv4CEj/8k+/yd   
          24.   
          25. 原文: abc    
          26. 解密: abc    
          27.  ===============反過來加密解密==================    
          28. 原文: def    
          29. 解密: def   
          posted on 2009-07-11 20:01 bitmap 閱讀(1244) 評論(0)  編輯  收藏
          主站蜘蛛池模板: 报价| 龙岩市| 高邮市| 温州市| 南华县| 邮箱| 东明县| 临沂市| 正安县| 潼关县| 兴城市| 浠水县| 商南县| 米易县| 满城县| 凉城县| 临猗县| 肃北| 司法| 平远县| 罗江县| 南城县| 贵州省| 郴州市| 崇仁县| 布尔津县| 麦盖提县| 乐山市| 来安县| 和田县| 邹城市| 洞头县| 宝鸡市| 化德县| 莱阳市| 郑州市| 辉县市| 岳池县| 林周县| 合水县| 平湖市|