# Security

transfersmile incluye una firma en el encabezado transfersmile-Signature de cada evento. Esto le permite verificar que el evento fue enviado por transfersmile en lugar de un tercero. Puede verificar la firma en

# Firma

# Verificando firmas manualmente

El contenido aproximado del encabezado transfersmile-Signature es el siguiente (aquí con salto de línea para facilitar la visualización, el contenido real está todo en una línea):

transfersmile-Signature:

t=1577808000,

v2=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

El encabezado transfersmile-Signature contiene una marca de tiempo y una firma. La marca de tiempo está prefijada por t=, seguida de una marca de tiempo UNIX; la firma tiene el prefijo v2=, seguido del contenido de la firma.

La notificación enviada utiliza el siguiente formato:

{
  Content-Type: application/json,
  Method: POST,
  Header: transfersmile-Signature,
  Body: {
    "trade_no":"",
    "out_trade_no":"",
    "out_request_no":"",
    "app_id":"",
    "trade_status":"",
    "amount":"",
    "method":"",
    "currency":"",
    "timestamp":""
  }
}

# Step 1 : Extract the timestamp and signatures from the header

Divida el encabezado usando el carácter [,] como separador, para obtener una lista de elementos. Luego, divida cada elemento utilizando el carácter [=] como separador, para obtener un par de prefijos y valores.

El valor del prefijo [t] corresponde a la marca de tiempo y [v2] corresponde a la firma. Puede descartar todos los demás elementos.

# Paso 2 : Prepare el RequestBody string original

Obtén todo el contenido en RequestBody. Por favor, preste atención aquí. No utilice la estructura autoconstruida del programa para formatear y/o serializar el contenido de RequestBody. Si tiene requisitos similares, hágalo después de obtener los datos originales para su verificación para evitar la clasificación innecesaria de campos y la adición de caracteres que afectan la firma.

# Paso 3 : Determine la firma esperada

Calcule un HMAC con la función hash SHA256. Utilice secretKey get del merchant dashboard como clave (salt) y use el string RequestBody original como mensaje.

# Step 4 : Compare las firmas

Compare la firma en el encabezado con la firma esperada. Para un match de igualdad, calcule la diferencia entre la marca de tiempo actual y la marca de tiempo recibida y, a continuación, decida si la diferencia está dentro de su tolerancia.

# Ejemplo de códigos de verificación en Java

String content = JSON.toJSONString(notify); 
String sign = SignHelper.macSha256(content, privateKey());

import javax.crypto.Mac; 
import javax.crypto.spec.SecretKeySpec; 
import java.nio.charset.StandardCharsets; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.util.*;

/** 
 * 
 */ 
@Slf4j 
public final class SignHelper{

 /**
  * HMAC with SHA-256
  *
  * @param content 
  * @param salt
  * @return
  */
 public static String macSha256(String content, String salt) {
    StringBuilder result = new StringBuilder();
    try {

        Mac mac = Mac.getInstance("HmacSHA256");
        mac.init(new SecretKeySpec(salt.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] hash = mac.doFinal(content.getBytes(StandardCharsets.UTF_8));
        for (byte b : hash) {
            result.append(Integer.toString((b & 0xff) + 0x100, 16).substring(1));
        }

    } catch (NoSuchAlgorithmException | InvalidKeyException e) {
        e.printStackTrace();
    }
    return result.toString();
 }
}