GenerateAnInterfaceSignature
# UnifiedSignatureGenerationRules
onlyParameterValuesParticipateInTheSignature, Key(theNameOfTheParameter) Only the sorting is performed, and it does not participate in the signature calculation
- replaceAllNonNullParameters Key(theNameOfTheParameter) follow
ASCII
sort - According to the order of the key (parameter name), the parameter values are taken one by one and concatenated in parallel, and the signature string is calculated by using the 'RSA' algorithm to calculate the signature string
# IllustratedByExample
- ExampleParameters
parameters | type | required | describe | example |
---|---|---|---|---|
mchNo | string(32) | Y | The merchant ID can be obtained from the merchant platform - personal account - personal information | S820211021094748000001 |
method | string(16) | N | paymentMethods | BCA |
orderNum | string(64) | Y | merchantOrderNumber | T1642592278863 |
amount | int(10) | Y | theAmountOfThePayment | 10000 |
productDetail | string(100) | Y | paymentDescription | Test Pay |
customerName | string(64) | Y | theNameOfTheBusiness | JackMa |
expiryPeriod | int(5) | Y | orderExpirationTime | 1440 |
customeEmail | string(64) | Y | merchantEmailAddress | [email protected] |
customerPhone | string(32) | Y | merchantSMobilePhoneNumber | 082122965511 |
- ConcatenateStrings
- firstSortTheKeysParameterNamesByASCII
- Then, according to the key (parameter name), the values are sorted in order and concatenated into a string
StrA = 2022-01-01 10:55:[email protected] notify urlT1642593166888150.60082122965511Test Pay
- CalculateTheSignature
- Use the key pair you configured in the TopPay Merchant Portal
- Use your privateKey to perform cryptographic calculations, RSA (StrA) to obtain the final signature string
sign = IMLn23c4orM+7pZhHoRmbjrol4X33jeAqFxbZuQ+pnznBIGhb6Ail3qQPmKwcuhNCt536nmldpbWI72 k1lDxd0zZ95ZHElcNzwTFHFKtd8063uy6rFaxaW6DQ47t4U/95dpGfHAZe0GiIFAQ6xQquaoLINyQa4QqL+cpB JFEg1dyW6GYLFSdJnx7ycQvFYllmOpGZmdPLny62GvrCWvkiIARUsmc9fpkpTx5UQEDTgmhwdCKBkhHVsx2AiQ bYDxZ5WBuU1GZeiJjPuzSxvzWP6VoQBsfpwTI5kdJs6aQCekGO2/YScD+tGgrm2J89Pc/axPcb1xZzsi5SxpWh feabQ\u003d\u003d
# CodeSamples
import com.google.gson.JsonObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <p>
* TopPay RSA signatureUtilityClass
* </p>
*
* @author TopPay
*/
public class TopPayRequestUtil {
/**
* verifyTheSignature
* @param params
* @return
*/
public static boolean verifySign(JsonObject params, String publickey) throws InvalidKeySpecException, NoSuchAlgorithmException {
String platSign = params.remove("platSign").getAsString(); // signature
List<String> paramNameList = new ArrayList<>(params.keySet());
Collections.sort(paramNameList);
StringBuilder stringBuilder = new StringBuilder();
for (String name : paramNameList) {
stringBuilder.append(params.get(name).getAsString());
}
System.out.println("keys:" + stringBuilder);
String decryptSign = publicDecrypt(platSign, getPublicKey(publickey));
System.out.println("decryptSign:" + decryptSign);
return stringBuilder.toString().equals(decryptSign);
}
/**
* privateKeyEncryption
* @param data
* @param privateKey
* @return
*/
public static String privateEncrypt(String data, RSAPrivateKey privateKey){
try{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return Base64.encodeBase64String(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes("UTF-8"), privateKey.getModulus().bitLength()));
}catch(Exception e){
throw new RuntimeException("encryptStrings[" + data + "]anExceptionWasEncountered", e);
}
}
/**
* publicKeyDecryption
* @param data
* @param publicKey
* @return
*/
public static String publicDecrypt(String data, RSAPublicKey publicKey){
try{
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), "UTF-8");
}catch(Exception e){
throw new RuntimeException("decryptTheString[" + data + "]anExceptionWasEncountered", e);
}
}
/**
* getThePrivateKey
* @param privateKey keyString(base64Encoded)
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//The private key object is obtained through the PKCS#8 encoded Key instruction
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* getThePublicKey
* @param publicKey keyStringBase64Encoded
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//The public key object is obtained through the X509 encoded Key instruction
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
return key;
}
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
int maxBlock = 0;
if(opmode == Cipher.DECRYPT_MODE){
maxBlock = keySize / 8;
}else{
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try{
while(datas.length > offSet){
if(datas.length-offSet > maxBlock){
buff = cipher.doFinal(datas, offSet, maxBlock);
}else{
buff = cipher.doFinal(datas, offSet, datas.length-offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
}catch(Exception e){
throw new RuntimeException("theEncryptionAndDecryptionThresholdsAre["+maxBlock+"]anExceptionOccurredWhileTheDataWasInPlace", e);
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
public static String doPost(String url,String json) throws IOException {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
StringEntity s = new StringEntity(json);
s.setContentEncoding("UTF-8");
s.setContentType("application/json");//toSendJsonDataYouNeedToSetContentType
post.setEntity(s);
HttpResponse res = client.execute(post);
if(res.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
return EntityUtils.toString(res.getEntity());// returnInJsonFormat
}
return null;
}
}