AES 加密解密HTTP传输乱码问题

简介: AES 加密解密HTTP传输乱码问题

在做项目使用 AES加密串作为TOKEN时遇到一个问题 ==,而且是在服务器上才会出现。加密好好的解密后数据乱码的问题。 因为加解密这些东西都是直接拿网上写的算法,具体里面的方法没有研究透彻,更别说去改了==。首先没想到是乱码的问题,只是解密返回过来的JSON串(因为加密数据就是JSON)在回转的时候一直回转失败。用的是阿里的fastJson ,难道是这个包有问题?然后排查发现,在断点进入后发现加密过后的数据回传过来后乱码了。。。。。所以初步判定是 乱码导致 JSON 回转失败。。。

然后将加密解密方法中的所有String.getBytes()方法全部指定 UTF-8 而且new String(bytes[],"UTF-8"),全部指定为UTF-8,测试。不行,还是乱码,上网查找资料,发现好多人都会出现,因为AES的加密是有要求的, 由于AES加密算法要求密文是16位的倍数所以会有信息的填充,猜测是在填充的数据中,解密时出现了问题。而且所有的的加密解密在经过转换后最后的状态都是 bytes[]数组,展现出来的字符状态都是经过处理的(大部分时base64的加密转换),而base64字符在网络传输中有可能特殊字符会经过转义,目前发现的就有加号被转换成了空格==。猜测也有可能是这个原因导致失败。(但是不应该时解密失败嘛,为啥会转换成特殊字符)。使用加密解密时,别人都是汉字转换会成为特殊字符,我这里是 数字和字母==。根据大神给出的信息,重新定义AES的加密解密类,并且将加密返回的字符串改成16进制,这样就只会存在字母和数字,就是将加密返回的bytes[]转成16进制而不是base64,这样,会解决掉解密后出现字符乱码的问题。(同样的在网络传输中因为特殊字符被转换的问题也会被解决掉)代码:

packagecom.tl.handlpower.util;
importorg.apache.commons.codec.binary.Base64;
importorg.apache.commons.lang3.StringUtils;
importsun.misc.BASE64Decoder;
importjavax.crypto.*;
importjavax.crypto.spec.SecretKeySpec;
importjava.io.UnsupportedEncodingException;
importjava.security.InvalidKeyException;
importjava.security.NoSuchAlgorithmException;
importjava.security.SecureRandom;
/*** AESUtils** @author mjx* @date 2020/4/15*/publicclassAESUtils {
/*** 密钥*///    public static final String KEY = "1234567887654321";// AES加密要求key必须要128个比特位(这里需要长度为16,否则会报错)/*** 加密** @param content*            需要加密的内容* @param password*            加密密码* @return*/publicstaticbyte[] encrypt(Stringcontent, Stringpassword) {
try {
KeyGeneratorkgen=KeyGenerator.getInstance("AES");
kgen.init(128, newSecureRandom(password.getBytes()));
SecretKeysecretKey=kgen.generateKey();
byte[] enCodeFormat=secretKey.getEncoded();
SecretKeySpeckey=newSecretKeySpec(enCodeFormat, "AES");
Ciphercipher=Cipher.getInstance("AES");// 创建密码器byte[] byteContent=content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化byte[] result=cipher.doFinal(byteContent);
returnresult; // 加密        } catch (NoSuchAlgorithmExceptione) {
e.printStackTrace();
        } catch (NoSuchPaddingExceptione) {
e.printStackTrace();
        } catch (InvalidKeyExceptione) {
e.printStackTrace();
        } catch (UnsupportedEncodingExceptione) {
e.printStackTrace();
        } catch (IllegalBlockSizeExceptione) {
e.printStackTrace();
        } catch (BadPaddingExceptione) {
e.printStackTrace();
        }
returnnull;
    }
/*** 解密** @param content*            待解密内容* @param password*            解密密钥* @return*/publicstaticbyte[] decrypt(byte[] content, Stringpassword) {
try {
KeyGeneratorkgen=KeyGenerator.getInstance("AES");
kgen.init(128, newSecureRandom(password.getBytes()));
SecretKeysecretKey=kgen.generateKey();
byte[] enCodeFormat=secretKey.getEncoded();
SecretKeySpeckey=newSecretKeySpec(enCodeFormat, "AES");
Ciphercipher=Cipher.getInstance("AES");// 创建密码器cipher.init(Cipher.DECRYPT_MODE, key);// 初始化byte[] result=cipher.doFinal(content);
returnresult; // 加密        } catch (NoSuchAlgorithmExceptione) {
e.printStackTrace();
        } catch (NoSuchPaddingExceptione) {
e.printStackTrace();
        } catch (InvalidKeyExceptione) {
e.printStackTrace();
        } catch (IllegalBlockSizeExceptione) {
e.printStackTrace();
        } catch (BadPaddingExceptione) {
e.printStackTrace();
        }
returnnull;
    }
/*** 将二进制转换成16进制** @param buf* @return*/publicstaticStringparseByte2HexStr(bytebuf[]) {
StringBuffersb=newStringBuffer();
for (inti=0; i<buf.length; i++) {
Stringhex=Integer.toHexString(buf[i] &0xFF);
if (hex.length() ==1) {
hex='0'+hex;
            }
sb.append(hex.toUpperCase());
        }
returnsb.toString();
    }
/*** 将16进制转换为二进制** @param hexStr* @return*/publicstaticbyte[] parseHexStr2Byte(StringhexStr) {
if (hexStr.length() <1) {
returnnull;
        }
byte[] result=newbyte[hexStr.length() /2];
for (inti=0; i<hexStr.length() /2; i++) {
inthigh=Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
intlow=Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
result[i] = (byte) (high*16+low);
        }
returnresult;
    }
/*** 加密** @param content*            需要加密的内容* @param password*            加密密码* @return*/publicstaticbyte[] encrypt2(Stringcontent, Stringpassword) {
try {
SecretKeySpeckey=newSecretKeySpec(password.getBytes(), "AES");
Ciphercipher=Cipher.getInstance("AES/ECB/NoPadding");
byte[] byteContent=content.getBytes("utf-8");
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化byte[] result=cipher.doFinal(byteContent);
returnresult; // 加密        } catch (NoSuchAlgorithmExceptione) {
e.printStackTrace();
        } catch (NoSuchPaddingExceptione) {
e.printStackTrace();
        } catch (InvalidKeyExceptione) {
e.printStackTrace();
        } catch (UnsupportedEncodingExceptione) {
e.printStackTrace();
        } catch (IllegalBlockSizeExceptione) {
e.printStackTrace();
        } catch (BadPaddingExceptione) {
e.printStackTrace();
        }
returnnull;
    }
publicstaticvoidmain(String[] args) throwsUnsupportedEncodingException {
Stringcontent="我是shoneworn";
Stringpassword="12345678";
// 加密System.out.println("加密前:"+content);
byte[] encode=encrypt(content, password);
//传输过程,不转成16进制的字符串,就等着程序崩溃掉吧Stringcode=parseByte2HexStr(encode);
System.out.println("密文字符串:"+code);
byte[] decode=parseHexStr2Byte(code);
// 解密byte[] decryptResult=decrypt(decode, password);
System.out.println("解密后:"+newString(decryptResult, "UTF-8")); //不转码会乱码    }
/**** 解密* @Author: mjx* @DateTime: 2020/4/28 10:42* @Params: []* @Return java.lang.String*/publicstaticStringaesDecrypt(Stringdata, Stringkey) {
try {
returnnewString(decrypt(parseHexStr2Byte(data), key),"UTF-8");
        } catch (UnsupportedEncodingExceptione) {
e.printStackTrace();
        }
returnnull;
    }
/**** 加密* @Author: mjx* @DateTime: 2020/4/28 10:43* @Params: []* @Return java.lang.String*/publicstaticStringaesEncrypt(Stringdata,Stringkey) {
returnparseByte2HexStr(encrypt(data, key));
    }
}
目录
相关文章
|
25天前
|
Linux 数据安全/隐私保护 Windows
aes加密在linux下会生成随机key的解决办法
aes加密在linux下会生成随机key的解决办法
14 2
|
1月前
|
PHP 数据安全/隐私保护
在PHP中使用AES进行加密和解密
在PHP中使用AES进行加密和解密
|
1月前
|
Linux 网络安全 数据安全/隐私保护
Linux vsFTPd服务详解——文件加密传输配置
Linux vsFTPd服务详解——文件加密传输配置
144 2
|
2月前
|
存储 算法 安全
【加密算法】AES对称加密算法简介
【加密算法】AES对称加密算法简介
|
2月前
|
安全 小程序 数据安全/隐私保护
aes加密算法python版本
aes加密算法python版本
39 0
|
2月前
|
安全 前端开发 网络协议
|
4月前
|
JavaScript 前端开发 测试技术
Postman 加密接口测试 | 使用Rsa、Aes对参数加密
Postman 加密接口测试 | 使用Rsa、Aes对参数加密
162 0
|
3月前
|
算法 安全 物联网
全面了解AES加密:入门指南(二)
全面了解AES加密:入门指南
|
1月前
|
存储 缓存 安全
https跳过SSL认证时是不是就是不加密的,相当于http?
https跳过SSL认证时是不是就是不加密的,相当于http?
123 0
|
2月前
|
网络协议 安全 数据安全/隐私保护
HTTP/2与HTTP/3:互联网传输协议的新旧交替
HTTP/2与HTTP/3:互联网传输协议的新旧交替
23 2