面向接口编程
package com.mycom;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
/*
加密参考
【微信支付】微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
第一步:对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密钥:
stringSignTemp=stringA+"&key=192006250b4c09247ec02edce69f6a2d" //注:key为商户平台设置的密钥key
sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7" //注:MD5签名方式
sign=hash_hmac("sha256",stringSignTemp,key).toUpperCase()="6A9AE1657590FD6257D693A078E1C3E4BB6BA4DC30B23E0EE2496E54170DACD6" //注:HMAC-SHA256签名方式
originUrl=http://api02.test.com:8080/user/alipay_phone?uid=123&amount=21.3
originUrl=http://test.com:8080/user/alipay_phone?uid=123&amount=21.3
第0步:
前后端约定32位密钥KEY
第一步:引入8位随机字符串,对参数按照key=value的格式,并按照参数名ASCII字典序排序如下:
stringSignTemp="amount=21.32&nonce_str=abc32&uid=123"
第二步:拼接密钥,签名:
sign=MD5(stringSignTemp+"&key=KEY").toUpperCase()
第三步:拼接、base64编码,生成加密后的url(str为utf-8编码):
result=Base64Encode(stringSignTemp@sign)
resultUrl=http://test.com:8080/user/alipay_phone/result
前端发起resultUrl请求,服务端收到后做逆向处理,校验sign后,做badRequest处理或执行originUrl逻辑
TODO
待解决url过长,引起用户疑惑;但不能通过缩短随机字符串、密钥等牺牲安全性来换取短的url
前后端32位密钥
DEMO:
KEY='sdf324dsfASdsadadADdsaff3aefrsaf'
originUrl=http://api02.test.com:8080/user/alipay_phone?amount=21.32&uid=145tfdsfdfgsgsgfsdg23
resultUrl=http://api02.test.com:8080/user/alipay_phone/YW1vdW50PTIxLjMyJm5vbmNlX3N0cj1kc2ZmczQ1dHJmZ2ZmZHN2MzQ1MjQzZmRzZnNkZnhjdngmdWlkPTE0NXRmZHNmZGZnc2dzZ2ZzZGcyM0A0RUM3NjhDMEJGMEE0MDlERTdBQURDRkNDMjRBMjBCQQ==
Base64Utf8Str = 'YW1vdW50PTIxLjMyJm5vbmNlX3N0cj1kc2ZmczQ1dHJmZ2ZmZHN2MzQ1MjQzZmRzZnNkZnhjdngmdWlkPTE0NXRmZHNmZGZnc2dzZ2ZzZGcyM0A0RUM3NjhDMEJGMEE0MDlERTdBQURDRkNDMjRBMjBCQQ=='
Base64Decode(Base64Utf8Str) // stringSignTemp@sign
stringSignTemp // 'amount=21.32&nonce_str=dsffs45trfgffdsv345243fdsfsdfxcvx&uid=145tfdsfdfgsgsgfsdg23'
sign // sign
if (MD5(stringSignTemp+"&key=KEY") === sign ){
go originUrl
}esle{
Bad Request
}
* */
interface AliPayCustomerUrl {
void getAliPayUrlEncryptKey();
void getEncodedUrl();
void getPlainUrl();
void checkRequest();
void handingBusiness();
}
class DecodeCustomerData {
public static String decodeBase64Utf8Str(String Utf8Base64String) {
byte[] b = Base64.decodeBase64(Utf8Base64String);
return new String(b);
}
public static String MD5Utf8Str(String plainText) {
return DigestUtils.md5Hex(plainText).toUpperCase();
}
}
public class AliPayCustomerUrlImplement implements AliPayCustomerUrl {
String AliPayUrlEncryptKey;
String encodedUrl;
String plainUrl;
Boolean badRequest;
DecodeCustomerData decodeCustomerData = new DecodeCustomerData();
public void getAliPayUrlEncryptKey() {
// 密钥管理服务 KMS - 腾讯云 https://cloud.tencent.com/product/kms
this.AliPayUrlEncryptKey = "sdf324dsfASdsadadADdsaff3aefrsaf";
}
public void getEncodedUrl() {
String requestUrlBase64 = "YW1vdW50PTIxLjMyJm5vbmNlX3N0cj1kc2ZmczQ1dHJmZ2ZmZHN2MzQ1MjQzZmRzZnNkZnhjdngmdWlkPTE0NXRmZHNmZGZnc2dzZ2ZzZGcyM0A0RUM3NjhDMEJGMEE0MDlERTdBQURDRkNDMjRBMjBCQQ==";
this.encodedUrl = requestUrlBase64;
}
public void getPlainUrl() {
String utf8Str = decodeCustomerData.decodeBase64Utf8Str(this.encodedUrl);
this.plainUrl = utf8Str;
}
public void checkRequest() {
String[] requestInfo = this.plainUrl.split("@");
String requestStringSignTemp = requestInfo[0];
// TODO 密钥正确、加密结果正确,但是请求参数非法的处理
String requestSign = requestInfo[1];
String checkPlainStr = requestStringSignTemp + "&key=" + this.AliPayUrlEncryptKey;
String sign = decodeCustomerData.MD5Utf8Str(checkPlainStr);
if (sign == requestSign) {
this.badRequest = false;
return;
}
this.badRequest = false;
}
public void handingBusiness() {
System.out.println(this.AliPayUrlEncryptKey);
System.out.println(this.encodedUrl);
System.out.println(this.plainUrl);
System.out.println(this.badRequest);
if (!this.badRequest) {
System.out.println("加密结果正确,但是请求不合业务逻辑的处理");
System.out.println("OK-----》Let's go!");
} else {
System.out.println("Bad Request! Who!");
}
}
public static void main(String[] args) {
AliPayCustomerUrlImplement m = new AliPayCustomerUrlImplement();
m.getAliPayUrlEncryptKey();
m.getEncodedUrl();
m.getPlainUrl();
m.checkRequest();
m.handingBusiness();
}
}
java base64 加密 解密 md5 加密
1、正常;2、加密错误,恶意请求;3、加密正确,但参数不合业务逻辑,可疑请求;