cn.com.antcloud.api.common.GwSigns Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of antcloud-api-sdk Show documentation
Show all versions of antcloud-api-sdk Show documentation
Ant Fin Tech API SDK For Java
Copyright (c) 2015-present Alipay.com, https://www.alipay.com
The newest version!
/*
* Copyright (c) 2015-present Alipay.com, https://www.alipay.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.com.antcloud.api.common;
import cn.com.antcloud.api.utils.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static cn.com.antcloud.api.common.SDKConstants.BASE64URL;
public class GwSigns {
private static final Logger logger = LoggerFactory.getLogger(GwSigns.class);
private static final Pattern ENCODED_CHARACTERS_PATTERN;
private static final String DEFAULT_ENCODING = "UTF-8";
static {
StringBuilder pattern = new StringBuilder();
pattern.append(Pattern.quote("+")).append("|").append(Pattern.quote("*")).append("|")
.append(Pattern.quote("%7E")).append("|").append(Pattern.quote("%2F"));
ENCODED_CHARACTERS_PATTERN = Pattern.compile(pattern.toString());
}
public static List signKeyFilter(Map params) {
List keys = new ArrayList();
// 对签名参数进行过滤,除去
for (Map.Entry item : params.entrySet()) {
if (item.getValue() == null || !item.getValue().startsWith(BASE64URL)) {
keys.add(item.getKey());
}
}
return keys;
}
/**
* 对参数进行签名
*
* @param params the params
* @param algorithm the algorithm
* @param secret the secret
* @param charset the charset
* @return the string
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws InvalidKeyException the invalid key exception
*/
public static String sign(Map params, String algorithm, String secret,
Charset charset) throws NoSuchAlgorithmException,
InvalidKeyException {
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(secret.getBytes(charset), algorithm));
List keys = signKeyFilter(params);
Collections.sort(keys);
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
if (i != 0) {
mac.update("&".getBytes(charset));
}
mac.update(urlEncode(key).getBytes(charset));
mac.update("=".getBytes(charset));
mac.update(urlEncode(params.get(key)).getBytes(charset));
}
byte[] signData = mac.doFinal();
return Base64.encodeToString(signData, false);
}
/**
* 对字符串进行签名
*
* @param text the text
* @param algorithm the algorithm
* @param secret the secret
* @param charset the charset
* @return the string
* @throws InvalidKeyException the invalid key exception
* @throws NoSuchAlgorithmException the no such algorithm exception
*/
public static String sign(String text, String algorithm, String secret,
Charset charset) throws InvalidKeyException,
NoSuchAlgorithmException {
Mac mac = Mac.getInstance(algorithm);
mac.init(new SecretKeySpec(secret.getBytes(charset), algorithm));
byte[] signData = mac.doFinal(text.getBytes(charset));
return Base64.encodeToString(signData, false);
}
/**
* 从产品返回的Response中抽取需要签名的字段。
* Response中的固定格式为:{"response": RESPONSE_JSON, "sign": SIGN_STRING}
* 其中RESPONSE_JSON为需要签名的字段,SIGN_STRING为产品返回的签名
*
* @param responseString the response string
* @return the string
*/
public static String extractStringToSign(String responseString) {
String responseNodeKey = "\"response\"";
String signNodeKey = "\"sign\"";
int indexOfResponseNode = responseString.indexOf(responseNodeKey);
int indexOfSignNode = responseString.lastIndexOf(signNodeKey);
if (indexOfResponseNode < 0) {
return null;
}
if (indexOfSignNode < 0 || indexOfSignNode < indexOfResponseNode) {
indexOfSignNode = responseString.lastIndexOf('}') - 1;
}
int startIndex = responseString.indexOf('{',
indexOfResponseNode + responseNodeKey.length());
int endIndex = responseString.lastIndexOf("}", indexOfSignNode);
// XXX: 这里可以用JSON解析一下这个子串,看他是不是合法的JSON
try {
return responseString.substring(startIndex, endIndex + 1);
} catch (IndexOutOfBoundsException e) {
logger.error(responseString);
logger.error("{}, {}", startIndex, endIndex);
throw e;
}
}
/**
* 在JsonString中添加签名字段
*
* @param responseString the response string
* @param sign the sign
* @return the string
*/
public static String attachSign(String responseString, String sign) {
String signNodeKey = "\"sign\"";
int indexOfSignNode = responseString.lastIndexOf(signNodeKey);
if (indexOfSignNode < 0) {
return null;
}
int indexOfOpenQuote = responseString.indexOf('"', indexOfSignNode + signNodeKey.length());
int indexOfCloseQuote = responseString.indexOf('"', indexOfOpenQuote + 1);
return responseString.substring(0, indexOfOpenQuote + 1) + sign
+ responseString.substring(indexOfCloseQuote);
}
/**
* url编码
*
* @param value the response string
* @return the string
*/
public static String urlEncode(final String value) {
if (value == null) {
return "";
}
try {
String encoded = URLEncoder.encode(value, DEFAULT_ENCODING);
Matcher matcher = ENCODED_CHARACTERS_PATTERN.matcher(encoded);
StringBuffer buffer = new StringBuffer(encoded.length());
while (matcher.find()) {
String replacement = matcher.group(0);
if ("+".equals(replacement)) {
replacement = "%20";
} else if ("*".equals(replacement)) {
replacement = "%2A";
} else if ("%7E".equals(replacement)) {
replacement = "~";
}
matcher.appendReplacement(buffer, replacement);
}
matcher.appendTail(buffer);
return buffer.toString();
} catch (UnsupportedEncodingException ex) {
throw new RuntimeException(ex);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy