IMSample中乱码问题的解决方案
将文字在网络中进行传输的时候,如果存在非ASCII码字符,很容易出现乱码问题,要解决也不难,在传输的文字上用URLEncoder进行编码,将它变成全部是ASCII码的形式,这样在网络传输中就不会受到影响;在另一侧,将收到的文字用URLDecoder加码就能还原文字原本的摸样。
IMSample中涉及到文字的混合加密,情况稍复杂一点,但流程还是一样的。
相关涉及编码和解码的工具类:
变化后的加密器代码:
修改后的解码器代码:
以上只是涉及乱码问题的一个处理方法,各位还要具体情况具体分析。
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 ;
}
}
}
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;
}
}
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;
}
}
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;
}
}
以上只是涉及乱码问题的一个处理方法,各位还要具体情况具体分析。