IMSample中乱码问题的解决方案

IMSample中乱码问题的解决方案
将文字在网络中进行传输的时候,如果存在非ASCII码字符,很容易出现乱码问题,要解决也不难,在传输的文字上用URLEncoder进行编码,将它变成全部是ASCII码的形式,这样在网络传输中就不会受到影响;在另一侧,将收到的文字用URLDecoder加码就能还原文字原本的摸样。

IMSample中涉及到文字的混合加密,情况稍复杂一点,但流程还是一样的。


相关涉及编码和解码的工具类:
package  com.heyang.common.code;

import  java.io.UnsupportedEncodingException;
import  java.net.URLDecoder;
import  java.net.URLEncoder;


/**
 * UTF8转码器
 * 
@author  heyang
 *
 
*/
public   class  UTF8Coder{
    
private   static   final  String UTF_8  =   " utf-8 " ; //  编码形式

    
/**
     * 对文字进行UTF8转码
     * 
@param  str
     * 
@return
     
*/
    
public   static  String encode(String str){
        
try  {
            
return  URLEncoder.encode(str, UTF_8);
        } 
catch  (UnsupportedEncodingException e) {
            
return   null ;
        }
    }
    
    
/**
     * 将转码后的文字还原
     * 
@param  str
     * 
@return
     
*/
    
public   static  String decode(String str){
        
try  {
            
return  URLDecoder.decode(str, UTF_8);
        } 
catch  (UnsupportedEncodingException e) {
            
return   null ;
        }
    }
}

变化后的加密器代码:
package  com.heyang.common.cipher;

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

import  com.heyang.common.code.AESSecurityCoder;
import  com.heyang.common.code.Base64SecurityUtil;
import  com.heyang.common.code.RSASecurityCoder;
import  com.heyang.common.code.UTF8Coder;

/**
 * 对消息进行加密的加密器
 * 说明:
 * 作者:何杨([email protected])
 * 创建时间:2010-12-27 下午07:00:29
 * 修改时间:2010-12-27 下午07:00:29
 
*/
public   class  IMMsgEncrypter{
    
//  经加密的消息
     private  String cipheredMsg;
    
    
/**
     * 构造函数
     * 
@param  plainMsg 未加密的消息
     * 
@param  otherSideRSAPublicKey 对方RSA公钥
     * 
@param  rsaCoder 己方RSA编码器
     * 
@param  aesCoder 己方AES编码器
     * 
@throws  IMMsgEncryptException
     
*/
    
public  IMMsgEncrypter(String plainMsg,String otherSideRSAPublicKey,RSASecurityCoder rsaCoder,AESSecurityCoder aesCoder)  throws  IMMsgEncryptException{
        
try {
            
//  防止乱码
            plainMsg = UTF8Coder.encode(plainMsg);
            
            
//  对明文进行AES加密
             byte [] aesArr = aesCoder.getEncryptByteArray(plainMsg);  //  对明文进行AES加密
            String cipherText = Base64.encodeBase64String(aesArr); //  得到AES加密后的密文
            
            
//  使用RSA对AES密钥进行加密
            String key = aesCoder.getAesKey(); //  取得AES的密钥
            String aesKey = "" ;
            
try {
                
byte [] clientRsaKeyArr = null ;
                clientRsaKeyArr
= Base64.decodeBase64(otherSideRSAPublicKey);
                
byte [] rsaArr = rsaCoder.getEncryptArray(key, clientRsaKeyArr);
                aesKey
= Base64.encodeBase64String(rsaArr);
            }
            
catch (Exception ex){
                
throw   new  IMMsgEncryptException( " 使用对方RSA公钥加密己方AES钥匙时发生异常. " );
            }
            
            
//  在发出的密文前附带经服务器RSA公钥加密的AES密钥
            StringBuilder sb = new  StringBuilder();
            sb.append(
" <aeskey> " + aesKey + " </aeskey> " );
            sb.append(
" <rsakey> " + rsaCoder.getPublicKeyString() + " </rsakey> " );
            sb.append(
" <text> " + cipherText + " </text> " );
            
            
//  最后对整体进行Base64加密
            cipheredMsg = Base64SecurityUtil.getEncryptString(sb.toString());
        }
        
catch (Exception ex){
            
throw   new  IMMsgEncryptException( " 加密消息时发生异常,异常信息为 " + ex.getMessage() + " . " );
        }
    }

    
public  String getCipheredMsg() {
        
return  cipheredMsg;
    }
}

修改后的解码器代码:
package  com.heyang.common.cipher;

import  java.util.HashMap;
import  java.util.Map;
import  java.util.regex.Matcher;
import  java.util.regex.Pattern;

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

import  com.heyang.common.code.AESSecurityCoder;
import  com.heyang.common.code.Base64SecurityUtil;
import  com.heyang.common.code.RSASecurityCoder;
import  com.heyang.common.code.UTF8Coder;


/**
 * 消息解密器
 * 说明:
 * 作者:何杨([email protected])
 * 创建时间:2010-12-27 下午07:41:44
 * 修改时间:2010-12-27 下午07:41:44
 
*/
public   class  IMMsgDecrypter{
    
//  固定的三个节点名
     private   static   final  String TEXT  =   " text " ;

    
private   static   final  String RSAKEY  =   " rsakey " ;

    
private   static   final  String AESKEY  =   " aeskey " ;

    
//  对方的RSA公钥
     private  String otherSideRSAPublicKey;
    
    
//  解密后的明文
     private  String plainMsg;
    
    
/**
     * 构造函数
     * 
@param  cipherMsg 要解密的消息
     * 
@param  rsaCoder 己方RSA编码器
     * 
@param  aesCoder 己方AES编码器
     * 
@throws  IMMsgDecryptException
     
*/
    
public  IMMsgDecrypter(String cipherMsg,RSASecurityCoder rsaCoder,AESSecurityCoder aesCoder)  throws  IMMsgDecryptException{
        
try {
            
//  先用Base64解密密文
            cipherMsg = Base64SecurityUtil.getDecryptString(cipherMsg);
            
            
//  用正则表达式得到密钥文,客户端的RSA公钥和密文
            String regex = " <(\\w+)>((.|\\s)+)</\\1> " ;

            Pattern pattern
= Pattern.compile(regex);
            Matcher matcher
= pattern.matcher(cipherMsg);
                
            String cipheredAesKey
= "" ; //  经服务器RSA公钥加密的客户端AES钥匙密文
            String cipherText = "" ; //  经客户端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);
                otherSideRSAPublicKey
= map.get(RSAKEY);
                cipherText
= map.get(TEXT);
            }
            
else {
                
throw   new  IMMsgDecryptException( " 解密消息时发生异常,原因是消息格式不正确.消息为: " + cipherMsg);
            }

            
//  得到经过服务器RSA私钥解密后的AES密钥
            String plainAesKey = "" ;
            
try  {
                
byte [] cipheredAesKeyArr = Base64.decodeBase64(cipheredAesKey);
                plainAesKey
= rsaCoder.getDecryptString(cipheredAesKeyArr);
            } 
catch  (Exception e) {
                
throw   new  IMMsgDecryptException( " 无法解密对方AES密钥,异常信息为 " + e.getMessage() + " ,客户端请求为: " + cipherMsg);
            }
            
            
//  使用AES密钥解密出明文
             byte [] cipherTextArr = Base64.decodeBase64(cipherText);
            plainMsg
= aesCoder.getDecryptString(cipherTextArr, plainAesKey);
            
            
//   UTF08还原
            plainMsg = UTF8Coder.decode(plainMsg);
        }
        
catch (Exception ex){
            
throw   new  IMMsgDecryptException( " 解密消息发生异常,异常信息为 " + ex.getMessage() + " . " );
        }
    }

    
public  String getOtherSideRSAPublicKey() {
        
return  otherSideRSAPublicKey;
    }

    
public  String getPlainMsg() {
        
return  plainMsg;
    }
}

以上只是涉及乱码问题的一个处理方法,各位还要具体情况具体分析。

你可能感兴趣的:(IMSample中乱码问题的解决方案)