Saltar al contenido principal

2- 2. Cómo firmar

Firma (se aplica la verificación de firma)

Los pasos generales para la generación de firmas son los siguientes:

El cifrado MD5 requiere codificación utf-8

**El primer paso es configurar todos los datos enviados o recibidos como un conjunto M, ordenar los valores de parámetros no nulos en el conjunto M de pequeño a grande de acuerdo con el código ASCII del nombre del parámetro (orden lexicográfico) y usar el formato de par clave-valor de URL (es decir, clave1=valor1&clave2=valor2...) para unirlos en una cadena cadenaA. **

** El segundo paso es aplicar un secreto en el empalme final de stringA para obtener la cadena stringSignTemp y realizar la operación MD5 en stringSignTemp para obtener el valor de signo signValue. **

Ejemplo de cadena de firma: key=08SaKUwNafSOc8w7&localOrderId=2023102400684344447&localUserId=302199873005&notifyUrl=http://127.0.0.1:8080/call-back/demo/notify&secret=uRdLM5BeMobQ4SePrwqZd35lNXyXJUHh

Paso 3, cifrado MD5: MD5 (cadena a firmar)

Obtener signo de firma: 6416c9f6eb37c8a901904026c769bec0 (minúscula)

----java签名代码工具

private static String getListString(List<Map<String, Object>> list) {
List<String> l = new ArrayList<>();
list.forEach(item -> {
l.add(getString(item));
});
String arrStr = String.join(",", l);
return "[" + arrStr + "]";
}

private static String getListConstable(List<?> list) {
List<String> l = new ArrayList<>();
list.forEach(item -> {
l.add( String.valueOf(item) );
});
String arrStr = String.join(",", l);
return "[" + arrStr + "]";
}

public static String getString(Map<String, Object> p) {
List<String> query = new ArrayList<>();
p.entrySet().stream().sorted(Map.Entry.comparingByKey()).forEach((v) -> {
String s;
Object value = v.getValue();
if( value == null ) return ;
if (value instanceof List<?>) {
List<?> list = (List<?>) value;
if (list.isEmpty()) return;
if(list instanceof Map<?,?>){
s = getListString((List<Map<String, Object>>) list);
}else{ s = getListConstable(list);}
}else if (value instanceof Map){
s = "{" + getString( (Map<String, Object>) value ) + "}";
}else if (value instanceof Double) {
Double doubleValue = (Double) value;
s = new BigDecimal(String.valueOf(doubleValue)).stripTrailingZeros().toPlainString();
} else if (value instanceof Float) {
Float floatValue = (Float) value;
s = new BigDecimal(String.valueOf(floatValue)).stripTrailingZeros().toPlainString();
} else if (value instanceof BigDecimal) {
BigDecimal bigDecimalValue = (BigDecimal) value;
s = bigDecimalValue.stripTrailingZeros().toPlainString();
} else {
s = value.toString();
}

query.add(v.getKey() + "=" + s);
});
return String.join("&", query);
}

public static String getSignStr(Map<String, Object> p, String secret){
return getString(p) + "&secret=" + secret;
}

public static String getSign(Map<String, Object> p, String secret) {
if (p.isEmpty()) return "";
String originalSign = getSignStr(p, secret);
log.info("待签名字符串 {}", originalSign);
return DigestUtils.md5DigestAsHex(originalSign.getBytes());
}