仅持有密钥时,如何解密AES加密的SOAP API响应?
问题分析与解决
核心错误点
你的代码存在两个致命逻辑错误,直接触发了IllegalBlockSizeException:
- 解码对象完全搞反:你对密钥(
secretKey)执行了Base64解码,但实际需要解码的是API返回的加密响应(encryptedResponse)——加密内容是Base64编码后的字符串,必须先解码为字节数组才能解密;而密钥一般是明文或Base64编码的原始密钥,不需要对它做解密前的Base64解码。 - AES密钥长度不合法:AES要求密钥长度必须是128位(16字节)、192位(24字节)或256位(32字节)。你提供的密钥
ijsdfgDJJff42h3412是18个字符,按UTF-8编码后为18字节,不符合AES的密钥规范,这会直接导致解密逻辑异常。
修正后的代码示例
先修正解码逻辑,再处理密钥长度问题(注:以下代码为基础修复方案,实际需结合API提供商的加密参数调整):
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class AESDecryptor { public static void main(String[] args) throws Exception { final String encryptedResponse = "F9nwhTquiEcRY3wfwCGVH1yvZ1fl28VnBXQ3vo6fyCzdV0MnOmeeHg8ea/7c/9ZT0AeEywnR06r5eUoeq4Swf/bFIixc9JJEYB7/fJ0h6I7blQbiOuks7QOUBoSMNaAum1NYTgTm0MHbM3GYLHDPlb8PkBFTL0XxZalKqcqRuhr3BQxPfITeSXjqSvPvy5Wt1Jq"; final String secretKey = "ijsdfgDJJff42h3412"; // 1. 修正:解码加密响应,而非密钥 byte[] encryptedBytes = Base64.getDecoder().decode(encryptedResponse); // 2. 处理密钥:确保长度符合AES要求 // 优先建议向API提供商确认密钥的真实格式(是否为Base64编码) // 临时方案:若密钥是明文,截取前16字节凑够128位(仅用于测试,实际需按API要求) byte[] keyBytes = secretKey.getBytes(); if (keyBytes.length != 16 && keyBytes.length !=24 && keyBytes.length !=32) { byte[] adjustedKey = new byte[16]; System.arraycopy(keyBytes, 0, adjustedKey, 0, Math.min(keyBytes.length, 16)); keyBytes = adjustedKey; } // 3. 指定完整的AES算法参数(避免依赖JDK默认值,必须和API提供商一致) // 若API用CBC/GCM等模式,还需获取初始化向量(IV),并在SecretKeySpec后添加IvParameterSpec Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); // 4. 执行解密 byte[] decryptedBytes = cipher.doFinal(encryptedBytes); String decryptedResponse = new String(decryptedBytes); System.out.println(decryptedResponse); } }
关键注意事项
- 必须确认API加密参数:向提供商索要以下信息,否则无法确保解密成功:
- AES的加密模式(ECB/CBC/GCM等)
- 填充方式(PKCS5Padding/PKCS7Padding等)
- 若为CBC/GCM模式,需获取初始化向量(IV)(通常随加密内容返回或双方预先约定)
- 密钥的编码格式(明文还是Base64编码)
- 密钥长度必须合规:严格按照API提供的密钥长度处理,禁止自行截取或补全,否则解密会失败
- 替换过时API:你使用的
BASE64Decoder是sun私有包下的过时类,建议改用JDK自带的java.util.Base64
内容的提问来源于stack exchange,提问作者xetra11
相关产品推荐
相关产品推荐

