Verifique as assinaturas do webhook

Visão geral #

Verifique os eventos que o Wooshpay envia para seus endpoints de webhook.

Cabeçalho da assinatura do Wooshpay #

O Wooshpay - Assinatura O cabeçalho incluído em cada evento assinado contém um registro de data e hora e uma assinatura.

O registro de data e hora é prefixado por t=e cada assinatura é prefixada por v1.

Por exemplo:

Wooshpay-Signature:t=1492774577,v1=6fdfb9c357542b8ee07277f5fca2c6f728bae2dce9be2f91412f4de922c1bae4

Chave secreta do webhook #

O Wooshpay gera um chave secreta para cada webhook. whsec_

Antes de verificar as assinaturas, você precisa recuperar o segredo do webhook em webhook.secret no objeto webhook.

webhook-secret-key

Verificação de assinaturas #

Ao comparar o assinatura no cabeçalho para o assinatura esperadaVocê pode verificar se o mesmo foi enviado pela Wooshpay e não por terceiros.

Para verificar a assinatura passo a passo, você pode seguir o guia abaixo:

Etapa 1: Extrair o registro de data e hora e as assinaturas do cabeçalho #

Dividir o cabeçalho, usando o , como separador, para obter uma lista de elementos. Em seguida, divida cada elemento, usando o = como separador, para obter um par de prefixo e valor.

O valor do prefixo t corresponde ao registro de data e hora, e v1 corresponde à assinatura. Você pode descartar todos os outros elementos.

Por exemplo:

t=1687845304,v1=6fdfb9c357542b8ee07277f5fca2c6f728bae2dce9be2f91412f4de922c1bae4

Etapa 2: Prepare o signed_payload string #

O signed_payload é criada pela concatenação:

  • O registro de data e hora (como uma cadeia de caracteres)
  • O personagem .
  • A carga útil real do JSON (o corpo da solicitação)

Por exemplo:

1687845304+.+Carga útil JSON

1687845304.{
  "id": "evt_1NNUrjL6kclEVx6Mb1x5dKJ3",
  "object": "event" (evento),
  "api_version": "2022-11-15",
  "created" (criado): 1687845303,
  "data": {
    "object": {
      "id": "prod_O9oUVgsSaordCT",
      "object": "product" (produto),
      "active": true,
      "livemode": true,
      "name": "test",
      "type" (tipo): "service" (serviço),
  "livemode": true,
  "pending_webhooks": 1,
  "type": "product.created"
}

Etapa 3: Determinar a assinatura esperada #

Calcule um HMAC com a função hash SHA256.

  • Use o segredo do webhook do ponto de extremidade como o chaveque você pode obter em webhook.secret no objeto webhook
  • Use o signed_payload como a string mensagem que você já preparou na etapa 2.

Por meio do chave + mensagemvocê pode calcular uma string HMAC, que é assinatura esperada

Por exemplo:

 public static void main(String[] args) {
        String webhookSecret = "whsec_261V2mfsXt1BsOjJbHaQOxnTzhWZKrUE";
        String timestamp = "1687845304";
        String requestBody = "{\"id\":\"evt_1NNUrjL6kclEVx6Mb1x5dKJ3\",\"object\":\"event\",\"api_version\":\"2022-11-15\",\"created\":1687845303,\"data\":{\"object\":{\"id\":\"prod_O9oUVgsSaordCT\",\"object\":\"product\",\"active\":true,\"livemode\":true,\"name\":\"test\",\"type\":\"service\",\"livemode\":true,\"pending_webhooks\":1,\"type\":\"product.created\"}";
        String signedPayload = timestamp+". "+requestBody;
        String signature = hmacSha256(webhookSecret,signedPayload);
        String WooshpaySignature = "t="+timestamp+",v1="+signature;
    }

    /**
     * HMAC-SHA256
     */
    public static String hmacSha256(String secret, String message) {
        String res;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            mac.init(secretKey);
            byte[] hash = mac.doFinal(message.getBytes());
            res = Hex.encodeHexString(hash);
        } catch (Exception e) {
            return null;
        }
        return res;
    }

Etapa 4: Comparar as assinaturas #

Compare o assinatura no cabeçalho para o assinatura esperada.

Para uma correspondência de igualdade, calcule a diferença entre os valores carimbo de data/hora atual e o carimbo de data/hora recebidoe, em seguida, decida se a diferença está dentro de sua tolerância.

Para se proteger contra ataques de tempo, você pode usar uma comparação de cadeia de caracteres em tempo constante para comparar a assinatura esperada com cada uma das assinaturas recebidas.

Quais são seus sentimentos?
Atualizado em 5 de agosto de 2023