当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
将文字在网络中进行传输的时候,如果存在非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;

/**
 * 对消息进行加密的加密器
 * 说明:
 * 作者:何杨(heyang78@gmail.com)
 * 创建时间: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;


/**
 * 消息解密器
 * 说明:
 * 作者:何杨(heyang78@gmail.com)
 * 创建时间: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;
    }
}

以上只是涉及乱码问题的一个处理方法,各位还要具体情况具体分析。
posted on 2011-01-21 22:41 何杨 阅读(250) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: