Digital signature
To ensure the integrity of data transmitted throughout the API exchange, digital signature and encryption are adopted, where digital signature is mandatory and data encryption is required if sensitive information is enclosed in the message.
In order to fulfill our security standard, you should at least able to sign and verify the API with below steps:
- Generate a key pair
- Upload / exchange key with AlipayHK
- Sign the request
- Verify the response
1. Generate a key pair
We requires a 2048-bit RSA key pair for signature, below is an example to generate a key pair through OpenSSL.
# 1. Generate private key
openssl genrsa -out client_private_key_php_dotnet.pem
# 2. Convert into PKCS8 for Java application
openssl pkcs8 -topk8 -inform PEM -in client_private_key_php_dotnet.pem -outform PEM -nocrypt -out client_private_key_pkcs8.pem
# 3. Generate public key
openssl rsa -in client_private_key_php_dotnet.pem -pubout -out client_public_key_php_dotnet.pem
# 4. Generate private key for Java application
cat client_private_key_pkcs8.pem | grep -v "^\-" | tr -d "\n" | sed 's/%$//' > client_private_key_java.pem
# 5. Generate public key for Java application
cat client_public_key_php_dotnet.pem | grep -v "^\-" | tr -d "\n" | sed 's/%$//' > client_public_key_java.pem
Private key sample (Java)
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCozuwZZ1H0yKleXkTceCVmDIo4+kl9b9vvOAXvJcrzJM7p1KCRvBX9HffXhvO8Bhn8/YuhNlP4OEQPgGQoy7byBoJ/CUgLg0oKMvBotq2wcf0lIYzpJy0MoCurl370L/LLJZtP953C4WrQZkcL/MIKVqNNZNVgwT6NrINWcWqHO+UbHFmRojiyXUAR9YrRULONeHu+CkwOiiQh+tcibe1ieUsiN02vC6hp/PMf9Ebd0N/uxibk8HeHIIEm9RLx7VxF2tPEDC4Yog/gYOKuzq2UYMwrlui555uyDvoYq+dNAi+zaTObeR25wlDVIU1fTNTR9IoRkgtYeVcKaHt0Eq4HAgMBAAECggEALAe84WtnnxdvxeOExpS3/IQs0WvHG2a/0Qel1Jjg9MaXCbqiHyEWAy175cWXcWWOBcUEVIpdIJNcfUaZ2WI5V6uHAiejmQ0nlL1wo39ykmFJDBRSMsY7I93rRhh/zqVrCL3IYvVNOvWc7LqgsWm+GwA6HAe++DuvWziyESwIAzmZuIAHTMnppxV5hsjqlv+BuH6Fbw93qc0JmjQgHh5KwkhneJQQ+dpprZEQFdTg9XUP+Vt6NZ1c2uajPMSmwRoYJcuXMMzUpevV5HZA5wyrhsyJtJSYDt7WepudWX+C3YQLsjvYek906oHGym5tPbpoPVb9fXxqrKxdcBB+vR62oQKBgQDQbyty5JKpvUjASNULVHY5aY6xarR5Ubp0mmDUDK0y9Sc6LHfOFSz/U983Nk4dnbWuEQiRswxMjCJHesPXXsoLOolJVCAPP495BjWLejobSD4apjybEORVSWCFJSLcr3bdEAqROeNC8jOyJ63DCg/ZW6OFtLISN7mx4mbtfP1fjwKBgQDPVMjMXatzvvhGdB3PylZ/aW2j50E8PVMvG1Q/u/NVgpGwI+k6cWnqHNB2h8gGaUKPbhZtT/gy4kKiNs/dph1ltnflAZvTzo1djK5j6l2Z0sTYnxtlADg9bn2iuzZtpsF85XNhYgkfIW7KlYgITxLHxM1lOHRiEEJp/p0GBMeOCQKBgDcjgZH2R5ohmbJMUheaM2BCvV3PxYhmh3W7NSxDYjodwk/QXa0lyu6MiHs5oXaSNvKiTOsGO5WwaI0SO+aoi7hmttSwLX77KIAylU2deuums88m9Ndso4qwS5lNVqicvkwCp1j9wFIAco6Jkp0K92BfrqV7RLQvC6+0HdhrfTefAoGAHB/KJT7HlSngj94MdTVjSmFIyCUEimFfOVKhuQuL1Jujm5sjdhQQY/uIo6uDjKsWplIupKFmb7CVjV+WDuELt9JqrRvswWyRbJE6zr7p94XJwgDDPI4tEtg8Hqj6lyE5ufF+F0WvKxPj7YMfMtFXINYnboWb8/l0qOAq+LgJQdECgYADjs7gz32hdDy2YXyLuf0fqMuJ552M7FM1A2upWFmNSLv/h6FYxxUUMOoP4UEd8QNXtLBOxmovm772opUfoT91QUkZMKBe54XbfqEL+aUdi3Svhs+02cqEzqN1kfo9U5IkUqUDSB7bM1/nUHcxbw/2Va41ggyWO8VGd3Vq/1TXsg==
Public key sample (Java)
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqM7sGWdR9MipXl5E3HglZgyKOPpJfW/b7zgF7yXK8yTO6dSgkbwV/R3314bzvAYZ/P2LoTZT+DhED4BkKMu28gaCfwlIC4NKCjLwaLatsHH9JSGM6SctDKArq5d+9C/yyyWbT/edwuFq0GZHC/zCClajTWTVYME+jayDVnFqhzvlGxxZkaI4sl1AEfWK0VCzjXh7vgpMDookIfrXIm3tYnlLIjdNrwuoafzzH/RG3dDf7sYm5PB3hyCBJvUS8e1cRdrTxAwuGKIP4GDirs6tlGDMK5boueebsg76GKvnTQIvs2kzm3kducJQ1SFNX0zU0fSKEZILWHlXCmh7dBKuBwIDAQAB
2. Exchange key with AlipayHK
After generating the key pair on you side, you will need to exchange the public key with AlipayHK, please contact integration team for details.
3. Sign the request
You may use our official SDK to sign the request, or you may follow below steps to sign manually.
3.1 Prepare pre-sign string
Please check relevant API for preparing pre-sign string.
3.2 Create the signature
By default, we use SHA256withRSA to create and base64 to encode the signature.
Sample SDK code:
String signature = sign(reqContent, merchantPrivateKey);
Sample Java code:
public static String sign(String preSignString, String privateKey) {
System.out.println("To sign:\n" + preSignString);
try {
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] encodedKey = Base64.getDecoder().decode(privateKey.getBytes("UTF-8"));
PKCS8EncodedKeySpec PKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(encodedKey);
PrivateKey priKey = keyFactory.generatePrivate(PKCS8EncodedKeySpec);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(preSignString.getBytes("UTF-8"));
byte[] signed = signature.sign();
// return Base64.getUrlEncoder().encodeToString(signed); // v1
return URLEncoder.encode(new String(Base64.getEncoder().encode(signed), "UTF-8"), "UTF-8"); // v2
} catch (Exception e) {
throw new RuntimeException(e);
}
}
3.3 Use the signature
Please check relevant API for signature usage.
4. Verify the response
4.1 Obtain the signature
Please check relevant API for obtaining signature from response.
4.2 Verify the signature
By default, we use base64 to decode and SHA256withRSA to verify the signature.
Sample SDK code:
boolean isValid = SignatureTool.verify(rspContent, signature, alipayPublicKey);
Sample Java code:
public static boolean verify(String preSignString, String publicKey, String signatureToBeVerified) {
try {
java.security.Signature signature = java.security.Signature.getInstance("SHA256withRSA");
PublicKey pubKey = KeyFactory.getInstance("RSA").generatePublic(
new X509EncodedKeySpec(Base64.getDecoder().decode((publicKey.getBytes("UTF-8")))));
signature.initVerify(pubKey);
signature.update(preSignString.getBytes("UTF-8"));
return signature.verify(Base64.getDecoder().decode(URLDecoder.decode(signatureToBeVerified,"UTF-8").getBytes("UTF-8")));
} catch (Exception e) {
throw new RuntimeException(e);
}
}