在 Java 中,API 接口加密通常是为了解决以下问题之一:
下面从 常见方案 到 完整示例,给你一个系统性的说明。
✅ 第一步一定是 HTTPS
所有接口必须通过 HTTPS,否则任何加密都能被抓包破解。
HTTP + 自定义加密 ≈ 没加密
HTTPS + 简单防护 ≈ 安全
客户端和服务端 约定一套规则,对请求参数进行签名:
{
"userId": 1001,
"amount": 200,
"timestamp": 1700000000
}
import java.security.MessageDigest;
public class SignUtil {
private static final String SECRET = "mySecretKey";
public static String sign(String data) throws Exception {
String content = data + SECRET;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(content.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
}
X-Timestamp: 1700000000
X-Signature: a1b2c3d4...
String serverSign = SignUtil.sign(params + timestamp);
if (!serverSign.equals(clientSign)) {
throw new RuntimeException("签名错误");
}
long now = System.currentTimeMillis() / 1000;
if (Math.abs(now - timestamp) > 60) {
throw new RuntimeException("请求过期");
}
nonce = UUID
服务端缓存 5 分钟,已存在则拒绝。
适合:参数敏感,但不频繁调用
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(data.getBytes());
❗ AES 密钥管理是难点(建议结合 KMS 或非对称加密)
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
✅ 适合:
❌ 不适合大参数(性能差)
String token = JWT.create()
.withClaim("userId", 1001)
.sign(Algorithm.HMAC256(secret));
Authorization: Bearer xxxxxx
✅ 防篡改
⚠️ 不能防泄露(需 HTTPS)
HTTPS
+ Token(JWT)
+ 签名(SHA256)
+ Timestamp / Nonce
HTTPS
+ RSA 加密关键参数
+ AES 加密业务数据
+ JWT
public class SignInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
// 校验签名
return checkSign(request);
}
}
| 错误 | 说明 |
|---|---|
| 只用 AES/RSA | 没解决重放和篡改 |
| 密钥写死在前端 | 等于没加密 |
| 签名参数不全 | 可被篡改 |
| 忽略时间戳 | 可被重放 |
Java API 接口加密 = HTTPS + 签名 + 防重放 + 鉴权
如果你能提供:
我可以直接给你一套 可直接用的完整方案或代码模板。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。