为了账号安全,请及时绑定邮箱和手机立即绑定

AES 算法在我的数据字符串中间返回垃圾字符

AES 算法在我的数据字符串中间返回垃圾字符

人到中年有点甜 2022-01-06 17:45:59
我取一个数据字符串 = "AkhilRanjanBiharabcdefghijklmnopMovedtoChennai18",先加密然后解密。我解密后得到的字符串是“AkhilRanjanBiharÙ†+™¸„À–ýæó@Movedtoñhennai18”,这对于前 16 个和最后 16 个字符几乎没问题,但中间的 16 个字符绝对是垃圾。什么可能会出错?我的加密代码:-public String encrypt(String value) {    log.info("This method is not going to be used");    String key = "theabcd@heymaths";    initVector = "{{{{{{{{{{{{{{{{";    String encryptedStr="";    byte[] encrBytes =null;    try {        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes());        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(), "AES");        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);        encrBytes = cipher.doFinal(value.getBytes());        encryptedStr = new String(encrBytes);    } catch (Exception ex) {        ex.printStackTrace();    }    String strToBeEncoded = encryptedStr +"::"+initVector;    encrBytes = strToBeEncoded.getBytes();    //String encoded = Base64.encodeBase64String(encrBytes);    String encoded = Base64.getEncoder().encodeToString(encrBytes);    String urlEncoded = null;    try {        urlEncoded = java.net.URLEncoder.encode(encoded, CHARSET);    } catch (UnsupportedEncodingException e) {        // TODO Auto-generated catch block        e.printStackTrace();    }    return urlEncoded;}解密代码:-public String decrypt(String encrypted) {    String decryptedStr = null;    byte[] base64Bytes = null;    String urlDecoded = null;    String key = HmCommonProperty.getProperty("abcd_crypt_key");    if(key == null || key.isEmpty()) {        key = securityKey;    }    String encryptionMech = HmCommonProperty.getProperty("abcd_crypt_algo");    if(encryptionMech == null || encryptionMech.isEmpty()) {        encryptionMech = CRYPT_MECHANISM;    }    return decryptedStr;}
查看完整描述

2 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

您的加密数据是一个字节序列。如果需要将其编码为字符串,则应使用 base64 或用于编码任意字节数组的类似编码。假装您的任意字节数组是有效的字符串编码会给您带来麻烦,即使您使用ISO_8859_1.



查看完整回答
反对 回复 2022-01-06
?
largeQ

TA贡献2039条经验 获得超7个赞

你的错误在这里:


encryptedStr = new String(encrBytes);

strToBeEncoded.getBytes();

这些方法使用平台默认字符集,并且当您从byte[]toString和 back转换时,在一般情况下byte[]是有损的。如果平台默认字符集是"ISO_8859_1".


我将所有 11 个这样的调用更改为:


encryptedStr = new String(encrBytes, StandardCharsets.ISO_8859_1);

strToBeEncoded.getBytes(StandardCharsets.ISO_8859_1);

(我没有改变CHARSET)。我现在得到的输出是:


initVector 长度 -> 16

输入长度 -> 48

AkhilRanjanBiharabcdefghijklmnopMovedtoChennai18


奖励警告 1:加密使用硬编码,"AES/CBC/NoPadding"但解密是动态的(当然也应该使用"AES/CBC/NoPadding")。


奖励警告2:机会是低,但它是完全可能的,"::"里面出现encrBytes,搞砸了你的str.split("::");。一种解决方案是搜索最后一次出现的"::"并且仅在其上进行拆分。


查看完整回答
反对 回复 2022-01-06
  • 2 回答
  • 0 关注
  • 109 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号