<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    當(dāng)柳上原的風(fēng)吹向天際的時(shí)候...

    真正的快樂(lè)來(lái)源于創(chuàng)造

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
    按:前面(http://m.tkk7.com/heyang/archive/2010/12/25/341518.html)已經(jīng)提到過(guò)混合加密方式,今天這里再來(lái)贅述一下完成的代碼和流程,熟悉者就不用往下看了。完整的IM程序在(http://www.box.net/shared/jcrbps2hk3)可以下載。

    整個(gè)流程的UML Sequence圖(Amaterus UML用得還不熟練請(qǐng)見(jiàn)諒,會(huì)意就好)


    下面是以上八個(gè)步驟中使用到的代碼和信息。

    步驟一
    取得服務(wù)器端RSA公鑰的Socket通信代碼
        public static byte[] getPublicKey() throws Exception{
            Socket s
    =new Socket("127.0.0.1",8888);
            
            InputStream  inStram
    =s.getInputStream();
            OutputStream outStream
    =s.getOutputStream();
            
            
    // 輸出
            PrintWriter out=new PrintWriter(outStream,true);
            
            out.print(
    "getPublicKey");
            out.flush();

            s.shutdownOutput();
    // 輸出結(jié)束
            
            
    // 輸入
            Scanner in=new Scanner(inStram);
            StringBuilder sb
    =new StringBuilder();
            
    while(in.hasNextLine()){
                String line
    =in.nextLine();
                sb.append(line);
            }
            String response
    =sb.toString();
            
            
    byte[] arr=Base64.decodeBase64(response);
            
            s.close();
            
    return arr;
        }

    步驟二:
    客戶(hù)端加密過(guò)程代碼:

            // 待加密的明文
            StringBuilder sb1=new StringBuilder();
            sb1.append(
    "<request>");
            sb1.append(
    "<command>register</command>");
            sb1.append(
    "<username>趙云</username>");
            sb1.append(
    "<password>123456</password>");
            sb1.append(
    "</request>");
            String plainText
    =sb1.toString();
            
            
    // 對(duì)明文進(jìn)行AES加密
            byte[] aesArr=aesCoder.getEncryptByteArray(plainText); // 對(duì)明文進(jìn)行AES加密
            String cipherText=Base64.encodeBase64String(aesArr);// 得到AES加密后的密文
            
            
    // 使用RSA對(duì)AES密鑰進(jìn)行加密
            String key=aesCoder.getAesKey();// 取得AES的密鑰
            byte[] rsaArr=rsaCoder.getEncryptArray(key, serverPublicKey);
            String encryptedKey
    =Base64.encodeBase64String(rsaArr);

    步驟三:
    將密文,AES密鑰,本地RSA公鑰送到服務(wù)器端的代碼(粗體部分):

            Socket s=new Socket("127.0.0.1",8888);
           
           InputStream  inStram=s.getInputStream();
           OutputStream outStream=s.getOutputStream();

           
            // 輸出
            PrintWriter out=new PrintWriter(outStream,true);
           
            // 待加密的明文
            StringBuilder sb1=new StringBuilder();
            sb1.append("<request>");
            sb1.append("<command>register</command>");
            sb1.append("<username>趙云</username>");
            sb1.append("<password>123456</password>");
            sb1.append("</request>");
            String plainText=sb1.toString();
           
            // 對(duì)明文進(jìn)行AES加密
            byte[] aesArr=aesCoder.getEncryptByteArray(plainText); // 對(duì)明文進(jìn)行AES加密
            String cipherText=Base64.encodeBase64String(aesArr);// 得到AES加密后的密文
           
            // 使用RSA對(duì)AES密鑰進(jìn)行加密
            String key=aesCoder.getAesKey();// 取得AES的密鑰
            byte[] rsaArr=rsaCoder.getEncryptArray(key, serverPublicKey);
            String encryptedKey=Base64.encodeBase64String(rsaArr);
           
            // 在發(fā)出的密文前附帶經(jīng)服務(wù)器RSA公鑰加密的AES密鑰
            StringBuilder sb3=new StringBuilder();
            sb3.append("<aeskey>"+encryptedKey+"</aeskey>");
            sb3.append("<rsakey>"+rsaCoder.getPublicKeyString()+"</rsakey>");
            sb3.append("<text>"+cipherText+"</text>");
           
            // 請(qǐng)求送出前用Base64加密
            String request=Base64SecurityUtil.getEncryptString(sb3.toString());
         
            out.print(request);
           out.flush();
           s.shutdownOutput();
    // 輸出結(jié)束

    步驟四:
    服務(wù)器端解密過(guò)程代碼(變量request中就是客戶(hù)端送來(lái)的請(qǐng)求文):

           // 得到請(qǐng)求后先用Base64解密
            request=Base64SecurityUtil.getDecryptString(request);
            
            // 用正則表達(dá)式得到密鑰文,客戶(hù)端的RSA公鑰和密文
            String regex="<(\\w+)>((.|\\s)+)</\\1>";

            Pattern pattern=Pattern.compile(regex);
            Matcher matcher=pattern.matcher(request);
                
            String cipheredAesKey="";// 經(jīng)服務(wù)器RSA公鑰加密的客戶(hù)端AES鑰匙密文
            String clientRsaKey="";// 客戶(hù)端的RSA公鑰
            String cipherText="";// 經(jīng)客戶(hù)端AES加密的密文
            
            Map<String,String> map=new HashMap<String,String>();
            while(matcher.find()){
                map.put(matcher.group(1), matcher.group(2));
            }
            
            if(map.size()==3){
                cipheredAesKey=map.get("aeskey");
                clientRsaKey=map.get("rsakey");
                cipherText=map.get("text");
            }
            else{
                return "無(wú)法用正則表達(dá)式解析服務(wù)器端請(qǐng)求";
            }

            // 得到經(jīng)過(guò)服務(wù)器RSA私鑰解密后的AES密鑰
            String plainAesKey="";
            try {
                byte[] cipheredAesKeyArr=Base64.decodeBase64(cipheredAesKey);
                plainAesKey=model.getRsaCoder().getDecryptString(cipheredAesKeyArr);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
            
            // 使用AES密鑰解密出明文
            byte[] cipherTextArr=Base64.decodeBase64(cipherText);
            String plainText=model.getAesCoder().getDecryptString(cipherTextArr, plainAesKey);

    步驟五
    這里的主要操作是根據(jù)看用戶(hù)名是否在用戶(hù)列表中存在,是則創(chuàng)建用戶(hù),否則告知名稱(chēng)重復(fù)。這段代碼很簡(jiǎn)單常見(jiàn),故省略之。

    步驟六:
    服務(wù)器端加密過(guò)程代碼:

            // 對(duì)明文進(jìn)行AES加密
            byte[] aesArr=model.getAesCoder().getEncryptByteArray(retval); // 對(duì)明文進(jìn)行AES加密
            String cipherRetval=Base64.encodeBase64String(aesArr);// 得到AES加密后的密文
            
            
    // 使用RSA對(duì)AES密鑰進(jìn)行加密
            String key=model.getAesCoder().getAesKey();// 取得AES的密鑰
            String aesKey="";
            
    try{
                
    byte[] clientRsaKeyArr=null;
                clientRsaKeyArr
    =Base64.decodeBase64(clientRsaKey);
                
    byte[] rsaArr=model.getRsaCoder().getEncryptArray(key, clientRsaKeyArr);
                aesKey
    =Base64.encodeBase64String(rsaArr);
            }
            
    catch(Exception ex){
                ex.printStackTrace();
            }
            
            
    // 在發(fā)出的密文前附帶經(jīng)服務(wù)器RSA公鑰加密的AES密鑰
            StringBuilder sb3=new StringBuilder();
            sb3.append(
    "<aeskey>"+aesKey+"</aeskey>");
            sb3.append(cipherRetval);

    步驟七:
    將響應(yīng)發(fā)還給客戶(hù)端的代碼(粗體部分):

                InputStream  inStram=incoming.getInputStream();
                OutputStream outStream
    =incoming.getOutputStream();
                
                Scanner in
    =new Scanner(inStram);
                PrintWriter out
    =new PrintWriter(outStream,true);
                
                
    // 得到客戶(hù)端的請(qǐng)求
                StringBuilder sb=new StringBuilder();
                
    while(in.hasNextLine()){
                    String line
    =in.nextLine();
                    sb.append(line);
                }
                
                
                String request
    =sb.toString();
                String response
    ="";
                
    if("getPublicKey".equals(request)){
                    
    // 求服務(wù)器公鑰
                    response=model.getPublicKey();
                }
                
    else{
                    response
    =getResponse(request);
                }
                
                
    // 向客戶(hù)端送出反饋
                out.print(response);
                out.flush();
                out.close();

    步驟八:
    客戶(hù)端解密服務(wù)器端響應(yīng)的過(guò)程:

            String cipheredAesKey="";// 經(jīng)服務(wù)器RSA公鑰加密的客戶(hù)端AES鑰匙密文
            String cipheredResponse="";// 經(jīng)客戶(hù)端AES加密的密文
            
            
    // 用正則表達(dá)式得到密鑰文,客戶(hù)端的RSA公鑰和密文
            String regex="<aeskey>(.+)</aeskey>(.+)";
            Pattern pattern
    =Pattern.compile(regex);
            Matcher matcher
    =pattern.matcher(response);
                
            
    while(matcher.find()){
                cipheredAesKey
    =matcher.group(1);
                cipheredResponse
    =matcher.group(2);
                
    break;
            }
            
            
    // 得到經(jīng)過(guò)服務(wù)器RSA私鑰解密后的AES密鑰
            String plainAesKey="";
            
    try {
                
    byte[] cipheredAesKeyArr=Base64.decodeBase64(cipheredAesKey);
                plainAesKey
    =rsaCoder.getDecryptString(cipheredAesKeyArr);
            } 
    catch (Exception e) {
                e.printStackTrace();
            }
            
            
    // 使用AES密鑰解密出明文
            byte[] cipheredResponseArr=Base64.decodeBase64(cipheredResponse);
            String plainResponse
    =aesCoder.getDecryptString(cipheredResponseArr, plainAesKey);
            System.out.println(plainResponse);

    好了,整個(gè)過(guò)程的代碼都貼出來(lái)了,感謝您花費(fèi)寶貴時(shí)間看到這里。另外三個(gè)加密解密類(lèi)的代碼如下:
    AESSecurityCoder類(lèi):
    package com.heyang.common.code;

    import java.security.Key;
    import java.security.NoSuchAlgorithmException;

    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;

    import org.apache.commons.codec.binary.Hex;


    /**
     * AES加密解密類(lèi)
     * 說(shuō)明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-12-25 下午12:19:12
     * 修改時(shí)間:2010-12-25 下午12:19:12
     
    */
    public class AESSecurityCoder{
        
    // 加密方法
        private static final String Algorithm="AES";
        
        
    // 進(jìn)行加密解密的密鑰
        private String aesKey="";
        
        
    /**
         * 構(gòu)造函數(shù)
         * 
    @throws NoSuchAlgorithmException 
         
    */
        
    public AESSecurityCoder() throws NoSuchAlgorithmException{
            KeyGenerator kg
    =KeyGenerator.getInstance(Algorithm);
            kg.init(
    256);
            SecretKey sk
    =kg.generateKey();
            
    byte[] arr=sk.getEncoded();
            
            aesKey
    =new String(Hex.encodeHex(arr));
        }
        
        
    /**
         * 取得解密后的字符串
         * 
         * 說(shuō)明:
         * 
    @param encryptArr
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:33:31
         
    */
        
    public String getDecryptString(byte[] encryptArr){
            
    try{
                Cipher cp
    =Cipher.getInstance(Algorithm);
                cp.init(Cipher.DECRYPT_MODE, getKey());
                
    byte[] arr=cp.doFinal(encryptArr);
                
                
    return new String(arr);
            }
            
    catch(Exception ex){
                System.out.println(
    "無(wú)法進(jìn)行解密,原因是"+ex.getMessage());
                
    return null;
            }
        }
        
        
    /**
         * 傳入密鑰,得到解密后的字符串
         * 
         * 說(shuō)明:
         * 
    @param encryptArr
         * 
    @param aesKey
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-25 下午01:55:42
         
    */
        
    public String getDecryptString(byte[] encryptArr,String aesKeyIn){
            
    try{
                Cipher cp
    =Cipher.getInstance(Algorithm);
                
                
    byte[] arr1=Hex.decodeHex(aesKeyIn.toCharArray());
                cp.init(Cipher.DECRYPT_MODE, 
    new SecretKeySpec(arr1,Algorithm));
                
    byte[] arr=cp.doFinal(encryptArr);
                
                
    return new String(arr);
            }
            
    catch(Exception ex){
                System.out.println(
    "無(wú)法進(jìn)行解密,原因是"+ex.getMessage());
                
    return null;
            }
        }
        
        
    /**
         * 取得加密后的字節(jié)數(shù)組
         * 
         * 說(shuō)明:
         * 
    @param originalString
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:33:49
         
    */
        
    public byte[] getEncryptByteArray(String originalString){
            
    try{
                Cipher cp
    =Cipher.getInstance(Algorithm);
                cp.init(Cipher.ENCRYPT_MODE, getKey());
                
    return cp.doFinal(originalString.getBytes());
            }
            
    catch(Exception ex){
                System.out.println(
    "無(wú)法進(jìn)行加密,原因是"+ex.getMessage());
                
    return null;
            }
        }
        
        
    /**
         * 取得密鑰
         * 
         * 說(shuō)明:
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午03:33:17
         
    */
        
    private Key getKey() throws Exception{
            
    byte[] arr=Hex.decodeHex(aesKey.toCharArray());
            
            
    return new SecretKeySpec(arr,Algorithm);
        }

        
    /**
         * 取得AES加密鑰匙
         * 
         * 說(shuō)明:
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-25 下午12:27:16
         
    */
        
    public String getAesKey() {
            
    return aesKey;
        }
    }

    RSASecurityCoder類(lèi):
    package com.heyang.common.code;

    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;

    import javax.crypto.Cipher;

    import org.apache.commons.codec.binary.Base64;

    /**
     * RSA加密解密類(lèi)
     * 說(shuō)明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-12-1 下午06:14:38
     * 修改時(shí)間:2010-12-1 下午06:14:38
     
    */
    public class RSASecurityCoder{
        
    // 非對(duì)稱(chēng)加密密鑰算法
        private static final String Algorithm="RSA";
        
        
    // 密鑰長(zhǎng)度,用來(lái)初始化
        private static final int Key_Size=1024;
        
        
    // 公鑰
        private byte[] publicKey;
        
        
    // 私鑰
        private byte[] privateKey;
        
        
    /**
         * 構(gòu)造函數(shù),在其中生成公鑰和私鑰
         * 
    @throws Exception
         
    */
        
    public RSASecurityCoder() throws Exception{
            
    // 得到密鑰對(duì)生成器
            KeyPairGenerator kpg=KeyPairGenerator.getInstance(Algorithm);
            kpg.initialize(Key_Size);
            
            
    // 得到密鑰對(duì)
            KeyPair kp=kpg.generateKeyPair();
            
            
    // 得到公鑰
            RSAPublicKey keyPublic=(RSAPublicKey)kp.getPublic();
            publicKey
    =keyPublic.getEncoded();
            
            
    // 得到私鑰
            RSAPrivateKey keyPrivate=(RSAPrivateKey)kp.getPrivate();
            privateKey
    =keyPrivate.getEncoded();
        }
        
        
    /**
         * 用公鑰對(duì)字符串進(jìn)行加密
         * 
         * 說(shuō)明:
         * 
    @param originalString
         * 
    @param publicKeyArray
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午06:29:51
         
    */
        
    public byte[] getEncryptArray(String originalString,byte[] publicKeyArray) throws Exception{
            
    // 得到公鑰
            X509EncodedKeySpec keySpec=new X509EncodedKeySpec(publicKeyArray);
            KeyFactory kf
    =KeyFactory.getInstance(Algorithm);
            PublicKey keyPublic
    =kf.generatePublic(keySpec);
            
            
    // 加密數(shù)據(jù)
            Cipher cp=Cipher.getInstance(Algorithm);
            cp.init(Cipher.ENCRYPT_MODE, keyPublic);
            
    return cp.doFinal(originalString.getBytes());
        }
        
        
        
    /**
         * 使用私鑰進(jìn)行解密
         * 
         * 說(shuō)明:
         * 
    @param encryptedDataArray
         * 
    @return
         * 
    @throws Exception
         * 創(chuàng)建時(shí)間:2010-12-1 下午06:35:28
         
    */
        
    public String getDecryptString(byte[] encryptedDataArray) throws Exception{
            
    // 得到私鑰
            PKCS8EncodedKeySpec keySpec=new PKCS8EncodedKeySpec(privateKey);
            KeyFactory kf
    =KeyFactory.getInstance(Algorithm);
            PrivateKey keyPrivate
    =kf.generatePrivate(keySpec);
            
            
    // 解密數(shù)據(jù)
            Cipher cp=Cipher.getInstance(Algorithm);
            cp.init(Cipher.DECRYPT_MODE, keyPrivate);
            
    byte[] arr=cp.doFinal(encryptedDataArray);
            
            
    // 得到解密后的字符串
            return new String(arr);
        }

        
    /**
         * 取得數(shù)組形式的公鑰
         * 
         * 說(shuō)明:
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-25 上午07:50:04
         
    */
        
    public byte[] getPublicKey() {
            
    return publicKey;
        }
        
        
    /**
         * 取得字符串形式的公鑰
         * 
         * 說(shuō)明:
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-12-25 上午07:51:11
         
    */
        
    public String getPublicKeyString() {
            
    return  Base64.encodeBase64String(getPublicKey());
        }
        
        
    public static void main(String[] arr) throws Exception{
            String str
    ="你好,世界! Hello,world!";
            System.out.println(
    "準(zhǔn)備用公鑰加密的字符串為:"+str);
            
            
    // 用公鑰加密
            RSASecurityCoder rsaCoder=new RSASecurityCoder();
            
    byte[] publicKey=rsaCoder.getPublicKey();        
            
    byte[] encryptArray=rsaCoder.getEncryptArray(str, publicKey);
            
            System.out.print(
    "用公鑰加密后的結(jié)果為:");
            
    for(byte b:encryptArray){
                System.out.print(b);
            }
            System.out.println();
            
            
    // 用私鑰解密
            String str1=rsaCoder.getDecryptString(encryptArray);
            System.out.println(
    "用私鑰解密后的字符串為:"+str1);
        }
    }

    Base64SecurityUtil類(lèi):
    package com.heyang.common.code;

    import org.apache.commons.codec.binary.Base64;


    /**
     * 常規(guī)Base64加密解密實(shí)用工具類(lèi)
     * 說(shuō)明:
     * 作者:何楊(heyang78@gmail.com)
     * 創(chuàng)建時(shí)間:2010-11-29 上午07:52:01
     * 修改時(shí)間:2010-11-29 上午07:52:01
     
    */
    public class Base64SecurityUtil{
        
    /**
         * 得到Base64加密后的字符串
         * 
         * 說(shuō)明:
         * 
    @param originalString
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-11-29 上午07:53:30
         
    */
        
    public static String getEncryptString(String originalString){
            
    byte[] arr = Base64.encodeBase64(originalString.getBytes(), true);
            
    return new String(arr);
        }
        
        
    /**
         * 得到Base64解密后的字符串
         * 
         * 說(shuō)明:
         * 
    @param encryptString
         * 
    @return
         * 創(chuàng)建時(shí)間:2010-11-29 上午07:56:02
         
    */
        
    public static String getDecryptString(String encryptString){
            
    byte[] arr = Base64.decodeBase64(encryptString.getBytes());
            
    return new String(arr);
        }
        
        
    /**
         * 測(cè)試
         * 
         * 說(shuō)明:
         * 
    @param args
         * 創(chuàng)建時(shí)間:2010-11-29 上午07:56:39
         
    */
        
    public static void main(String[] args){
            String str
    ="Hello world!你好,世界。";
            
            String str1
    =Base64SecurityUtil.getEncryptString(str);
            System.out.println(
    "經(jīng)Base64加密后的密文為"+str1);
            
            String str2
    =Base64SecurityUtil.getDecryptString(str1);
            System.out.println(
    "經(jīng)Base64解密后的原文為"+str2);
            
        }
    }

    posted on 2010-12-26 11:41 何楊 閱讀(7352) 評(píng)論(4)  編輯  收藏

    Feedback

    # re: 一個(gè)完整的混合加密方式在Socket客戶(hù)機(jī)服務(wù)器通信應(yīng)用中的例子 2011-12-12 12:09 Horrison
    不懂啊  回復(fù)  更多評(píng)論
      

    # re: 一個(gè)完整的混合加密方式在Socket客戶(hù)機(jī)服務(wù)器通信應(yīng)用中的例子 2011-12-14 11:37 何楊
    @Horrison

    工作中涉及就會(huì)懂了,用不到那也沒(méi)啥。  回復(fù)  更多評(píng)論
      

    # re: 一個(gè)完整的混合加密方式在Socket客戶(hù)機(jī)服務(wù)器通信應(yīng)用中的例子 2015-10-30 11:28 junxuelian
    在不?  回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲成人免费网址| 亚洲AV无码专区在线播放中文| 日本成人免费在线| 91香蕉国产线观看免费全集| 国产特黄一级一片免费| 在线观看亚洲免费| 中文字幕乱码免费看电影| 一级毛片免费播放视频| 精品亚洲永久免费精品| 中文在线观看国语高清免费| 一区二区三区免费看| 免费一级毛片在线播放视频| 成年人网站免费视频| 国产成人免费全部网站| 狠狠久久永久免费观看| 岛国片在线免费观看| 亚洲人成网站18禁止一区| 亚洲欧洲国产精品你懂的| 亚洲国产欧美国产综合一区| jizz免费观看| 中国在线观看免费高清完整版| 亚洲国产精品成人久久蜜臀| 久久久久亚洲精品无码蜜桃 | 欧洲一级毛片免费| 女人张腿给男人桶视频免费版| 国产精品亚洲αv天堂无码| 亚洲av午夜精品一区二区三区| 久久精品国产亚洲AV果冻传媒| 亚洲 欧洲 视频 伦小说| 国产精品高清免费网站| 91在线品视觉盛宴免费| 中文字幕人成人乱码亚洲电影| 久久亚洲中文字幕精品一区四| 亚洲人成色77777| 亚洲中文字幕AV每天更新| 亚洲色欲色欱wwW在线| 成人免费区一区二区三区 | 亚洲精品综合一二三区在线 | 视频一区二区三区免费观看| 99re在线这里只有精品免费| 又爽又高潮的BB视频免费看 |