Java实现API sign签名校验的方法详解
简介
在互联网应用的开发过程中,API被广泛应用。而在API的开发过程中,为了确保API的安全性,一般都会使用签名验证的方式进行校验。而在Java中,实现API sign签名校验的方法也是比较简单的。
签名算法的原理
在进行签名校验之前,我们先来了解一下签名算法的原理。
签名算法是指通过一定的算法和密钥来对一个文本或二进制数据进行运算,产生一个固定长度的摘要信息。这个摘要信息在传输中起到了保密、完整性和鉴别身份等功能,也就是我们所说的签名。常用的签名算法有MD5、SHA-1、HMAC等。
在进行签名验证时,客户端和服务端需要约定好使用的签名算法和密钥,然后客户端将请求参数按照一定的规则和规则进行排序、拼接、加密等操作,最终生成一个签名值并将其添加到请求参数中,服务端在接收到请求参数后,也会按照相同的规则和规则对请求参数进行处理,然后生成一个自己的签名值,并将其与请求参数中的签名值进行比较,如果两者相等,则认为请求是合法的,否则就认为请求是不合法的。
签名验证的Java实现
在Java中,我们可以使用Java自带的安全框架javax.crypto来实现签名验证。具体的实现步骤如下:
- 约定使用的签名算法和密钥
在进行签名验证之前,客户端和服务端需要约定使用的签名算法和密钥。在实际应用中,我们可以将这些信息存储在配置文件或数据库中,并在应用启动时进行配置,以方便管理和修改。
private static final String ALGORITHM = "HmacSHA256";//使用的签名算法
private static final String SECRET_KEY = "xxxxxxxx";//使用的密钥
- 对请求参数进行处理
在进行签名验证之前,客户端需要对请求参数按照一定的规则进行处理,然后将处理后的结果生成签名值,并将其添加到请求参数中。服务端在接收到请求参数后,也需要对请求参数按照相同的规则进行处理,并生成一个自己的签名值。
/**
* 对请求参数进行处理,生成签名
* @param params 请求参数
* @return 签名值
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
*/
public static String generateSign(Map<String, Object> params) throws NoSuchAlgorithmException, InvalidKeyException {
StringBuilder sb = new StringBuilder();
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
for (String key : keys) {
Object value = params.get(key);
if (value != null && !value.toString().isEmpty() && !"sign".equals(key)) {
sb.append(key).append("=").append(value.toString()).append("&");
}
}
sb.append("key=").append(SECRET_KEY);
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(SECRET_KEY.getBytes(), ALGORITHM));
byte[] signBytes = mac.doFinal(sb.toString().getBytes(Charsets.UTF_8));
return Hex.encodeHexString(signBytes);
}
- 进行签名验证
在进行签名验证时,服务端需要按照相同的规则对请求参数进行处理,并生成一个自己的签名值,然后将其与请求参数中的签名值进行比较,如果两者相等,则认为请求是合法的,否则就认为请求是不合法的。
/**
* 验证签名
* @param params 请求参数
* @param sign 签名值
* @return 是否合法
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
*/
public static boolean verifySign(Map<String, Object> params, String sign) throws InvalidKeyException, NoSuchAlgorithmException {
String expectedSign = generateSign(params);
return expectedSign != null && expectedSign.equals(sign);
}
示例
为了更好地理解签名验证的Java实现过程,我们来看两个实际的示例案例。
示例1
在这个示例中,我们假设某个API的访问地址为:
http://www.example.com/api/user/details
请求参数中包含了以下内容:
Map<String, Object> params = new HashMap<>();
params.put("userId", "123456");
params.put("timestamp", "1614352796");
params.put("nonce", "291737");
params.put("sign", "f5a5ce839d217b46bffd230237985288");//这是请求参数中的签名值
我们约定使用的签名算法为HmacSHA256,密钥为"xxxxxxxx"。在进行签名处理时,按照约定的规则进行拼接和加密操作,生成一个签名值,最终与请求参数中的签名值进行比较,如果两者相等,则认为请求是合法的。
boolean isValid = verifySign(params, params.get("sign").toString());
示例2
在这个示例中,我们假设某个API的访问地址为:
http://www.example.com/api/order/create
请求参数中包含了以下内容:
Map<String, Object> params = new HashMap<>();
params.put("nonce", "699785");
params.put("timestamp", "1614262398");
params.put("appId", "123456789");
params.put("orderId", "20210303121212657");
params.put("productId", "12548");
params.put("price", "298.00");
params.put("count", "2");
params.put("sign", "d4ef976bdd7c3ccafbf6ab40c11d2910");
我们约定使用的签名算法为HmacSHA256,密钥为"xxxxxxxx"。在进行签名处理时,按照约定的规则进行拼接和加密操作,生成一个签名值,最终与请求参数中的签名值进行比较,如果两者相等,则认为请求是合法的。
boolean isValid = verifySign(params, params.get("sign").toString());
结论
Java实现API sign签名校验是比较容易的,只需要约定好使用的签名算法和密钥,对请求参数按照一定的规则进行处理,最后生成一个签名值,然后与请求参数中的签名值进行比较即可。只要签名算法和密钥得到保护,就可以确保API的安全性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现API sign签名校验的方法详解 - Python技术站