Todos os produtos
Search
Central de documentação

Direct Mail:Assinaturas de solicitação

Última atualização: Jun 27, 2026

O Direct Mail autentica cada solicitação de API com uma assinatura HMAC-SHA1 derivada do seu par de AccessKey.

Nota:

  • Ignore este tópico se você utiliza um SDK do Alibaba Cloud (disponível para Java, PHP e C#).

  • A API aceita solicitações GET e POST, mas o StringToSign difere entre elas.

Toda solicitação deve incluir uma assinatura, seja por HTTP ou HTTPS. O Direct Mail usa um AccessKey ID e um AccessKey secret para verificar o remetente. Gerencie seus pares de AccessKey no console User Information Management. O AccessKey ID identifica o solicitante; o AccessKey secret assina a solicitação e permite a verificação no servidor. Mantenha seu AccessKey secret em sigilo.

Etapas da assinatura

Para assinar uma solicitação:

  1. Crie uma string de consulta canônica a partir dos parâmetros da solicitação.

    a. Ordene os parâmetros.

    Organize todos os parâmetros da solicitação (comuns e específicos da API) em ordem alfabética pelo nome. Exclua o parâmetro Signature.

    Nota: Em solicitações GET, esses parâmetros correspondem à parte da URL da solicitação após o caractere ? e separados por &.

    b. Codifique cada nome e valor de parâmetro.

    Codifique nomes e valores em URL usando UTF-8. Regras:

    • Não codifique A-Z, a-z, 0-9, -, _, . ou ~.

    • Codifique outros caracteres como %XY, onde XY é o valor ASCII hexadecimal. Exemplo: "%22.

    • Codifique caracteres UTF-8 multibyte como %XY%ZA….

    • Codifique espaços como %20, não como +.

    Importante: Bibliotecas padrão de codificação URL (como java.net.URLEncoder) seguem as regras de application/x-www-form-urlencoded. Após a codificação, substitua + por %20, * por %2A e %7E por ~.

    c. Una cada nome e valor codificados com =.

    d. Concatene todos os pares nome-valor com & seguindo a ordem definida na etapa a. Isso gera a string de consulta canônica.

  2. Crie a string a ser assinada no seguinte formato:

     StringToSign=
     HTTPMethod + "&" +
     percentEncode("/") + "&" +
     percentEncode(CanonicalizedQueryString)        

    HTTPMethod é o método HTTP (GET ou POST).

    percentEncode("/") codifica / conforme as regras da etapa 1.b, resultando em %2F.

    percentEncode(CanonicalizedQueryString) codifica a string de consulta canônica da etapa 1 segundo as regras da etapa 1.b. Nota: Isso produz um resultado com codificação dupla.

  3. Calcule o valor HMAC.

    Calcule o HMAC-SHA1 do StringToSign conforme definido na RFC2104.

    Nota: A chave de assinatura é o seu AccessKeySecret seguido por & (ASCII 38). O algoritmo de hash é SHA1.

  4. Calcule o valor da assinatura.

    Codifique o valor HMAC da etapa 3 em Base64. O resultado é a assinatura.

  5. Adicione a assinatura à solicitação como o parâmetro Signature.

    Nota: O valor de Signature deve ter codificação URL assim como os demais parâmetros, conforme a RFC3986.

Exemplo de assinatura

Este exemplo assina uma solicitação POST SingleSendMail.

URL da solicitação: http://dm.aliyuncs.com/

Parâmetros da solicitação:

AccessKeyId=testid&AccountName=<a%b'>&Action=SingleSendMail&AddressType=1&Format=XML&HtmlBody=4&RegionId=cn-hangzhou&ReplyToAddress=true&SignatureMethod=HMAC-SHA1&SignatureNonce=c1b2c332-4cfb-4a0f-b8cc-ebe622aa0a5c&SignatureVersion=1.0&Subject=3&TagName=2&Timestamp=2016-10-20T06:27:56Z&ToAddress=1@test.com&Version=2015-11-23

StringToSign:

POST&%2F&AccessKeyId%3Dtestid%26AccountName%3D%253Ca%2525b%2527%253E%26Action%3DSingleSendMail%26AddressType%3D1%26Format%3DXML%26HtmlBody%3D4%26RegionId%3Dcn-hangzhou%26ReplyToAddress%3Dtrue%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3Dc1b2c332-4cfb-4a0f-b8cc-ebe622aa0a5c%26SignatureVersion%3D1.0%26Subject%3D3%26TagName%3D2%26Timestamp%3D2016-10-20T06%253A27%253A56Z%26ToAddress%3D1%2540test.com%26Version%3D2015-11-23

Com AccessKeyId testid e AccessKeySecret testsecret, a chave de assinatura é testsecret&. A assinatura resultante:

llJfXJjBW3OacrVgxxsITgYaYm0=

Corpo POST assinado (com Signature adicionado e Content-Type definido como application/x-www-form-urlencoded):

Signature=llJfXJjBW3OacrVgxxsITgYaYm0=&AccessKeyId=testid&AccountName=<a%b'>&Action=SingleSendMail&AddressType=1&Format=XML&HtmlBody=4&RegionId=cn-hangzhou&ReplyToAddress=true&SignatureMethod=HMAC-SHA1&SignatureNonce=c1b2c332-4cfb-4a0f-b8cc-ebe622aa0a5c&SignatureVersion=1.0&Subject=3&TagName=2&Timestamp=2016-10-20T06:27:56Z&ToAddress=1@test.com&Version=2015-11-23

Codifique esses parâmetros em URL antes do envio..

Exemplos de código

Java

private static final String MAC_NAME ="HmacSHA1";
private static final String ENCODING ="UTF-8";

/**
 * Signs encryptText using the HMAC-SHA1 method.
 *
 *@param encryptText The string to be signed.
 *@param encryptKey  The key.
 *@return
 *@throws Exception
 */
public static byte[] HmacSHA1Encrypt(StringencryptText, String encryptKey) throwsException {
byte[] data = encryptKey.getBytes(ENCODING);
// Creates a key from the given byte array. The second parameter specifies the name of the key algorithm.
SecretKey secretKey = new SecretKeySpec(data,MAC_NAME);
// Generates a Mac object for the specified Mac algorithm.
Mac mac = Mac.getInstance(MAC_NAME);
// Initializes the Mac object with the given key.
mac.init(secretKey);
byte[] text = encryptText.getBytes(ENCODING);
// Completes the Mac operation.
return mac.doFinal(text);
}
@Test
public void test() throws Exception {
/*StringToSign=
                HTTPMethod + “&” +
                percentEncode(“/”) + ”&” +
percentEncode(CanonicalizedQueryString)*/
String str ="AccessKeyId=testid&AccountName=<a%b'>&Action=SingleSendMail&AddressType=1&Format=XML&HtmlBody=4&RegionId=cn-hangzhou&ReplyToAddress=true&SignatureMethod=HMAC"+
"-SHA1&SignatureNonce=c1b2c332-4cfb-4a0f-b8cc-ebe622aa0a5c&SignatureVersion=1.0&Subject=3&TagName=2&Timestamp=2016-10-20T06:27:56Z&ToAddress=1@test.com&Version=2015-11-23";
String percentStr = "";
String[] strs = str.split("&");
for (int i = 0; i < strs.length;i++) {
String[] str1 =strs[i].split("=");
if (str1.length == 1){
                percentStr = percentStr + getUtf8Encoder(str1[0])+ "=" + getUtf8Encoder("")+ "&";
}else {
                percentStr = percentStr + getUtf8Encoder(str1[0])+ "=" + getUtf8Encoder(str1[1]) + "&";
            }
}
percentStr =percentStr.substring(0,percentStr.lastIndexOf("&"));
String percent = URLEncoder.encode("/","UTF-8");
percentStr = getUtf8Encoder(percentStr);
String toSign = HttpMethod.POST + "&"+ percent +"&" + percentStr;
System.out.println("--------------"+ toSign);
/*POST&%2F&AccessKeyId%3Dtestid%26AccountName%3D%253Ca%2525b%2527%253E%26Action%3DSingleSendMail%26AddressType%3D1%26Format%3DXML%26HtmlBody%3D4%26RegionId%3Dcn-hangzhou%26ReplyToAddress%3Dtrue%26SignatureMethod%3DHMAC-SHA1%26SignatureNonce%3Dc1b2c332-4cfb-4a0f-b8cc-ebe622aa0a5c%26SignatureVersion%3D1.0%26Subject%3D3%26TagName%3D2%26Timestamp%3D2016-10-20T06%253A27%253A56Z%26ToAddress%3D1%2540test.com%26Version%3D2015-11-23*/
byte[] bytes = HmacSHA1Encrypt(toSign,"testsecret&");
String base64Str = Base64.encode(bytes);
System.out.println(base64Str);//llJfXJjBW3OacrVgxxsITgYaYm0=
}
private String getUtf8Encoder(String param) throwsUnsupportedEncodingException {
return URLEncoder.encode(param, "UTF-8")
                .replaceAll("\\+","%20")
                .replaceAll("\\*","%2A")
                .replaceAll("%7E","~");
 };

Python

import hmac
import base64
# Replace StringToSign with the actual content.
message = b'StringToSign'
key = b'testsecret&'
h = hmac.new(key, message, digestmod='sha1')
# print(h.digest())
print(base64.b64encode(h.digest()))

PHP

<?php
function encryptTokey($data){
     $apikey = 'testsecret&';
     $sign = base64_encode(hash_hmac("sha1", $data, $apikey, true));
     //printf($sign);
     return $sign;
}
// Replace StringToSign with the actual content.
echo encryptTokey(StringToSign);
?>

Perguntas frequentes

  • Erros intermitentes de SignatureDoesNotMatch geralmente indicam que caracteres especiais não foram substituídos após a codificação. Consulte a nota Importante acima.

  • Se houver problemas de incompatibilidade de assinatura não resolvidos, use o Exemplo de solicitação e substitua pelos seus próprios parâmetros.