JAVA AES 256解密32字节

时间:2018-11-15 12:15:26

标签: java

我正在尝试使用AES解密一些数据。,有人告诉我加密是一种32字节的方法,我得到的错误消息是输入长度不是16字节的倍数,所以我将继续尝试

添加

我正在阅读示例API文件,我想我用这个hextoByte方法应该是错的

hashKey :Xgmz5mMUm7JdpPI7mRXIITSNjPEUtV7f
hashIv :nxKLik2dMNPUqIJy

这是加密值:

   MerchantID=MS15295340&RespondType=JSON&TimeStamp=1485232229&Version=1.4&MerchantOrderNo=S_1485232288&Amt=40&ItemDesc=UnitTest

加密答案为:

fb7a19d840c9877d26d961f6a906602439260588e0e9db45cdc0d4d69a3b97fe22e00fda051ee90c7e987e62a717d409a45e4c04893caa90b31f86dc32929debb391145325f07068854efb5977e9aed0b684e7b0a1cb45a764bad9f4d9ab32cb1f634c66e315054b2d3589a1d9fc0ad3dfdb8dad102df281c306c25972047d4e

主要方法

public static void main(String[] args) {
        String hashKey = "Xgmz5mMUm7JdpPI7mRXIITSNjPEUtV7f";
        String hashIv = "nxKLik2dMNPUqIJy";
        String value = "MerchantID=MS15295340&RespondType=JSON&TimeStamp=1485232229&Version=1.4&MerchantOrderNo=S_12345667822&Amt=40&ItemDesc=UnitTest";
        Map<String, Object> map = encryptSpgateway(hashKey, hashIv, value);
        System.out.println(map);

        String decrypt = decryptSpgateway(hashKey, hashIv,
                "fb7a19d840c9877d26d961f6a906602439260588e0e9db45cdc0d4d69a3b97fe22e00fda051ee90c7e987e62a717d409a45e4c04893caa90b31f86dc32929debb391145325f07068854efb5977e9aed065bafa1c91f243f0fc1efac2f0d8db2a16276764914eaf38b9e61ae1e12731e9461d493860ace4b89a3d49203c1745dd");
        System.out.println(decrypt);
    }

此加密代码

public static Map<String, Object> encrypt(String hashKey, String hashIv, String value) {
        Map<String, Object> encryMap = new HashMap<String, Object>();
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(hashKey.getBytes("UTF-8"), "AES");
            IvParameterSpec iv = new IvParameterSpec(hashIv.getBytes("UTF-8"));
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(addPKCS7Padding(value.getBytes("UTF-8"), 32));
            String encryResult = bytesToHex(encrypted).toLowerCase();
            encryMap.put("encry", encryResult);
            return encryMap;
        } catch (Exception e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
        }
        return null;
    }

    private static byte[] addPKCS7Padding(byte[] data, int iBlockSize) {
        int iLength = data.length;
        byte cPadding = (byte) (iBlockSize - (iLength % iBlockSize));
        byte[] output = new byte[iLength + cPadding];
        System.arraycopy(data, 0, output, 0, iLength);
        for (int i = iLength; i < output.length; i++)
            output[i] = (byte) cPadding;
        return output;
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            sb.append(hex);
        }
        return sb.toString();
    }

这是我的解密代码

public static String decrypt(String hashKey, String hashIv, String value) {
        try {
            SecretKeySpec skeySpec = new SecretKeySpec(hashKey.getBytes("UTF-8"), "AES");
            IvParameterSpec iv = new IvParameterSpec(hashIv.getBytes("UTF-8"));
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] decrypted = cipher.doFinal(Base64.decodeBase64(HexToBytes(value)));
        byte[] unpadded = RemovePKCS7Padding(decrypted);
        return new String(unpadded, "UTF-8");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return null;
    }

    private static byte[] RemovePKCS7Padding(byte[] data) {
        int ilength = data[data.length - 1];
        byte[] output = new byte[data.length - ilength];
        System.arraycopy(data, 0, output, 0, output.length);
        return output;
    }

    public static byte[] HexToBytes(String value) {
    value = value.toUpperCase();
    int length = value.length() / 2;
    char[] hexChars = value.toCharArray();
    byte[] b = new byte[length];
    for (int i = 0; i < length; i++) {
        int pos = i * 2;
        b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
    }
    return b;
}

public static byte charToByte(char c) {
    return (byte) "0123456789ABCDEF".indexOf(c);
}

1 个答案:

答案 0 :(得分:0)

几件事:

  1. 当您尝试解密时,您的密码处于ENCRYPT_MODE
  2. 您不应从加密的字符串中删除填充,可以根据需要从解密的字符串中删除填充。

将您的解密方法更改为此:

public static String decrypt(String hashKey, String hashIv, String value) {
    try {
        SecretKeySpec skeySpec = new SecretKeySpec(hashKey.getBytes("UTF-8"), "AES");
        IvParameterSpec iv = new IvParameterSpec(hashIv.getBytes("UTF-8"));
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] decrypted = cipher.doFinal(HexToBytes(value));
        byte[] unpadded = removePKCS7Padding(decrypted);
        return new String(unpadded, "UTF-8");
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    return null;
}