Java调用REST接口遇AES密钥长度错误及POST请求配置疑问
解决Java OAuth1请求中AES密钥长度异常及POST请求JSON处理问题
首先来看你遇到的核心异常:
Exception in thread "main" java.lang.IllegalArgumentException: Key length not 128/192/256 bits.
at org.bouncycastle.crypto.engines.AESFastEngine.generateWorkingKey(Unknown Source)
这个问题的根源很明确:你在generateCmac方法里直接将字符串secret转成UTF-8字节数组作为AES密钥,但AES算法要求密钥长度必须严格是128位(16字节)、192位(24字节)或256位(32字节)。你的secret字符串"12345678-1234-1234-1234-12345678"转成UTF-8后是30字节,完全不符合AES的密钥长度规范,所以抛出了这个异常。
修复密钥长度问题
你有两种常见的解决方案,根据你的API文档要求选择:
方案1:对原始secret进行哈希处理(推荐)
通过SHA-256哈希原始secret,生成32字节(256位)的标准AES密钥,既符合算法要求,也提升了安全性。修改generateCmac方法如下:
import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; // ... private static String generateCmac(String key, String msg) throws UnsupportedEncodingException, NoSuchAlgorithmException { // 对原始secret做SHA-256哈希,得到32字节的AES密钥 MessageDigest digest = MessageDigest.getInstance("SHA-256"); byte[] keyBytes = digest.digest(key.getBytes("UTF-8")); byte[] data = msg.getBytes("UTF-8"); CMac macProvider = new CMac(new AESFastEngine()); macProvider.init(new KeyParameter(keyBytes)); macProvider.reset(); macProvider.update(data, 0, data.length); byte[] output = new byte[macProvider.getMacSize()]; macProvider.doFinal(output, 0); String cmac = Base64.encodeBase64String(output).replaceAll("\r\n", ""); return cmac; }
方案2:如果API提供的是Base64编码的密钥
如果你的API文档说明secret是Base64编码的AES密钥,那么你应该用Base64解码而不是直接转UTF-8:
byte[] keyBytes = Base64.decodeBase64(key);
POST请求JSON处理问题
是的,你完全可以直接在body中发送JSON数据,但需要注意几个关键细节:
- 设置正确的请求头:必须添加
Content-Type: application/json,告诉服务器你发送的是JSON格式数据,否则服务器可能无法正确解析。 - 保证JSON格式合法:手动拼接JSON时要注意转义双引号(比如
"{\"var\":\"val\"}"),更推荐用Jackson、Gson等JSON库生成字符串,避免手动拼接出错。 - 签名时的body处理:你的代码已经在
normalizeParams方法中处理了POST/PUT的body,但要确认你的API是否要求将body纳入OAuth签名的base string计算——大部分OAuth1.0的API对此有要求,你的当前逻辑是正确的,但要和API文档对齐。
修改POST请求部分的代码,添加Content-Type头:
if ("POST".equals(httpMethod) || "PUT".equals(httpMethod)) { request.setRequestProperty("Content-Length", "" + requestBody.length); request.setRequestProperty("Content-Type", "application/json"); // 新增这行 request.setDoOutput(true); OutputStream postStream = request.getOutputStream(); postStream.write(requestBody, 0, requestBody.length); postStream.close(); }
内容的提问来源于stack exchange,提问作者Chandhan Sai
相关产品推荐
相关产品推荐

