接入签名
1.1 SHA256withRSA
签名步骤
- 获取私钥(privateKey)
- 算法选择SHA256withRSA
- 将待签名数据转换为UTF-8格式
- 进行签名
- Base64转码
签名数据说明
剔除所有值为空的参数,剩下的参数根据参数名称的ASCII码排序,然后以key=value&key1=value1...的方式连接key和value(最后一个参数不需要&)。
示例
1. 私钥
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHaM7clWWlJNS6
ZR5ZkxSFeMMFt74YGRmYPr67UHrfc4CzFtN9sctIUqZJVv05sfOgnb0rk1G7wx97
/LqxPEGs5chc+Nq9HkNf5VopMifOQ85j1Sv1U031oEGk+Oi4MTAR4ZWlLKBQPyKV
b5pCP8aIv15GTIiIwJKS17zY5mQUrXzASTDk54DCG9eN4Lgka9xzwRvaYZvmxLg7
32GxjI5TE797kA5gxY7GxZ0wxdkWkhcee6xX6WWhAcmdHPUUS0EPcnL5wcc3wP07
vO+R/jO1XoaXczb6JRh6ApR3Y5VjSFQApqwe7AIgASGf8aSkBU4K95RfZ3QsBjof
2SX/3fkf2. 数据
json
{
"key": "value",
"key2": "value2",
"key1": "value2",
"sign": "RcqXuiVp1JpwJedRGzTpL8M5mUsfeHL29gV9ycaJwmDoNV21AiaQ41au2qiJ8h+jKn/KBMcrJAzHGBTO3CZ0ffGxmqNz9fKhZX+X1MTntH+MhtKTyKR4ZF8kbAtezdVgPfqT69NPQGbWo57R3KP0m4W4n2ZjgkxkcG3yYtBdAgsyxDNoT8W0wH7nK7Y0zp88O8wIMe7kfBnK59J4y0Xz2EwiFX+bNkfRhf3U5WiHIU2TdRbaYsnzndmOkYkVdFAiUH7zoXnEn8ZVqiDZkK4eFG9H1LxU55dStug1hLtwxOKlu5OYFUi4iGAiq0Vlir01eDR1++KAudOdb1gcUyH2rA=="
}3. 需要签名的数据
key=value&key1=value2&key2=value24. 签名结果
RcqXuiVp1JpwJedRGzTpL8M5mUsfeHL29gV9ycaJwmDoNV21AiaQ41au2qiJ8h+jKn/KBMcrJAzHGBTO3CZ0ffGxmqNz9fKhZX+X1MTntH+MhtKTyKR4ZF8kbAtezdVgPfqT69NPQGbWo57R3KP0m4W4n2ZjgkxkcG3yYtBdAgsyxDNoT8W0wH7nK7Y0zp88O8wIMe7kfBnK59J4y0Xz2EwiFX+bNkfRhf3U5WiHIU2TdRbaYsnzndmOkYkVdFAiUH7zoXnEn8ZVqiDZkK4eFG9H1LxU55dStug1hLtwxOKlu5OYFUi4iGAiq0Vlir01eDR1++KAudOdb1gcUyH2rA==参考代码
Maven 依赖
xml
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>Java 实现
java
package xxx;
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RSASecureDemo {
/**
* 签名
*
* @param privateKey 私钥
* @param toBeSignedData 需要签名的数据
* @return sign 签名结果
*/
public static String signRSA(String privateKey, String toBeSignedData) {
try {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(toBeSignedData.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(signature.sign());
} catch (Exception e) {
throw new RuntimeException("rsa sign failed");
}
}
public static void main(String[] args) {
String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHaM7clWWlJNS6" +
"ZR5ZkxSFeMMFt74YGRmYPr67UHrfc4CzFtN9sctIUqZJVv05sfOgnb0rk1G7wx97" +
"/LqxPEGs5chc+Nq9HkNf5VopMifOQ85j1Sv1U031oEGk+Oi4MTAR4ZWlLKBQPyKV" +
// ... 其他私钥内容 ...
"483/Axmrwea50UKLqRVH3IXzTOEJth0betqTmbefYFLETn5RXB6MOJQOdzpvvcP3" +
"05FmtT/grqqcnaeLbosT4A==";
String toBeSignedData = "key=value&key1=value2&key2=value2";
String sign = signRSA(privateKey, toBeSignedData);
System.out.println(sign);
}
}1.2 SHA256
签名步骤
- 获取密钥
- 将待签名数据和密钥以字符串的形式串联起来
- 将上述字符串转换为UTF-8格式
- 进行sha-256摘要
- 将字节转换为十六进制
签名数据说明
剔除所有"签名"列为"No"以及值为空的参数,剩下的参数根据参数名称的ASCII码排序,然后以vaule1vaule2vaule3...的方式将值拼接起来。
示例
1. 密钥
3b5e10b65bff4172a5b9ca2d2ec00a6e2. 数据
json
{
"merchantNo": "800135",
"test": "dsaaass1dsag",
"bizContent": "yesdas1dsa",
"as": "12334567",
"bc": "098754"
}3. 需要签名的数据
12334567098754yesdas1dsa800135dsaaass1dsag4. 签名结果
0ce84cc90742e79b3af76da6b6909dc158a2e933057562639fe6a5a8e73f5350参考代码
Maven 依赖
xml
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>Java 实现
java
package xxx;
import org.apache.commons.lang3.StringUtils;
import java.security.MessageDigest;
import java.util.TreeMap;
public class SHA256SecureDemo {
public static void main(String[] args) throws Exception {
TreeMap data = new TreeMap();
data.put("merchantNo","800135");
data.put("test","yesdas1dsa");
data.put("bizContent","dsaaass1dsag");
data.put("as","12334567");
data.put("bc","098754");
String toBeSignedData = strcatValueSign(data);
String key = "3b5e10b65bff4172a5b9ca2d2ec00a6e";
String sign = signSha256(key, toBeSignedData);
System.out.println(sign);
}
private static String strcatValueSign(TreeMap treeMap) {
StringBuffer buffer = new StringBuffer();
treeMap.forEach((k, v) -> {
if (StringUtils.isNotBlank(v)) {
buffer.append(v);
}
});
return buffer.toString();
}
public static String signSha256(String key, String toBeSignedData) {
String str = toBeSignedData + key;
MessageDigest messageDigest;
String encodestr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes("UTF-8"));
encodestr = byte2Hex(messageDigest.digest());
} catch (Exception e) {
e.printStackTrace();
}
return encodestr;
}
/**
* 将字节转换为十六进制
*/
private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1) {
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
}