猿问

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

我取一个数据字符串 = "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;

}


人到中年有点甜
浏览 110回答 2
2回答

胡说叔叔

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

largeQ

你的错误在这里: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输入长度 -> 48AkhilRanjanBiharabcdefghijklmnopMovedtoChennai18奖励警告 1:加密使用硬编码,"AES/CBC/NoPadding"但解密是动态的(当然也应该使用"AES/CBC/NoPadding")。奖励警告2:机会是低,但它是完全可能的,"::"里面出现encrBytes,搞砸了你的str.split("::");。一种解决方案是搜索最后一次出现的"::"并且仅在其上进行拆分。
随时随地看视频慕课网APP

相关分类

Java
我要回答