使用公钥完成签名验证
2023-03-15 23:26:33 时间
在对接微信支付接口时,需要对微信支付返回的信息进行签名验证,防止中间人攻击,替换微信支付返回的结果
整体过程
- 微信支付生成签名:私钥 + 内容
->
signature - 调用方验证签名:公钥 + 内容
验证
signature
示例
- 生成签名
/**
* 生成签名.
*
* @param originalData 原始数据
* @param privateKey 私钥
* @return 签名串
*/
public static String sign(String originalData, PrivateKey privateKey) {
String base64Sign = "";
try {
//返回指定签名的Signature对象
Signature sign = Signature.getInstance("SHA1withRSA");
//初始化这个用于签名的对象
sign.initSign(privateKey);
byte[] bysData = originalData.getBytes(StandardCharsets.UTF_8);
//使用指定的byte数组更新要签名的数据
sign.update(bysData);
//返回所有已经更新数据的签名字节
byte[] signByte = sign.sign();
//对其进行Base64编码
BASE64Encoder encoder = new BASE64Encoder();
base64Sign = encoder.encode(signByte);
} catch (Exception e) {
throw new RuntimeException(e);
}
return base64Sign;
}
- 验证签名
/**
* 验证签名.
*
* @param signStr 签名串
* @param originalData 原始数据
* @param publicKey 公钥
* @return 是否验证通过
*/
public static boolean verify(String signStr, String originalData, PublicKey publicKey) {
System.out.println("开始进行验签,原始数据为:" + originalData);
try {
//将签名数据
BASE64Decoder decoder = new BASE64Decoder();
byte[] signed = decoder.decodeBuffer(signStr);
//通过Signature的getInstance方法,获取指定签名算法的Signature对象
Signature signature = Signature.getInstance("SHA1withRSA");
//初始化用于验证的对象
signature.initVerify(publicKey);
//使用指定的byte[]更新要验证的数据
signature.update(originalData.getBytes(StandardCharsets.UTF_8));
//验证传入的签名
return signature.verify(signed);
} catch (Exception e) {
return false;
}
}
- 测试
public static void main(String[] args) throws Exception {
String p12 = "KLFJDLJFL";
byte[] decode = Base64.getDecoder().decode(p12);
String keypasswd = "passwd";
String keyalias = "tenpay certificate";
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new ByteArrayInputStream(decode), keypasswd.toCharArray());
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
System.out.println(aliases.nextElement());
}
PrivateKey prikey = (PrivateKey) ks.getKey(keyalias, keypasswd.toCharArray());
Certificate cert = ks.getCertificate(keyalias);
PublicKey pubkey = cert.getPublicKey();
String originData = "hello world";
String sign = sign(originData, prikey);
boolean verify = verify(sign, originData, pubkey);
System.out.println(verify);
}
疑问
使用了HTTPS,为什么微信支付还要用公私钥签名呢?
相关文章
- 友盟季报:小长假拍照美化应用受青睐 北京用户深夜爱购物
- 移动互联网应用数据分析基础体系
- 听云廖雄杰:大数据时代精益应用性能管理
- findmnt 命令的八个应用实例
- 电商社交数据在大数据风控的应用实践
- 如何快速在阿里云上构建自己的机器学习应用
- 创建你的第一个Spring Boot应用
- 第一个AngularJS Web应用 todoList
- 一个二维码扫码下载两种平台app
- 【便签】签到app安卓客户端(开源)
- Android学习之补间动画
- Android学习之逐帧动画
- Android学习之图像的处理
- Android弹球游戏
- Android简易画板
- Android学习之path类
- Android学习之绘图入门
- Android学习之Bitmap
- Android记事本开发
- Android记事本开发之SQLite数据库实现