Updated on 2023-09-22 GMT+08:00

Java Code Example

package com.huawei.cbc.cbcmarketplacecommentservice.ability.jsonutils;

import java.io.UnsupportedEncodingException;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.SecureRandom;

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Set;

import java.util.TreeMap;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.KeyGenerator;

import javax.crypto.Mac;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.SecretKey;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

import org.apache.commons.lang.StringUtils;

public class EncryptTest {

// Encoding format

private static final String CHARSET = "UTF-8";

// If encryptType is set to AES256_CBC_PKCS5Padding, 1 is transferred. If encryptType is set to AES128_CBC_PKCS5Padding, 2 is transferred.

private static final String ENCRYPT_TYPE_256 = "1";

// Key displayed on the Seller Information page (Replace xxxxxxx with the actual key.)

private static final String ACCESS_KEY = "xxxxxxx";

public static void main(String args[]) throws Exception {

// ------------Request verification---------------

// Convert the request into a map and simulate the operation of obtaining parameters from the request (request.getParameterMap())

Map<String, String[]> paramsMap = getTestUrlMap();

// Encryption type. The value can be AES256_CBC_PKCS5Padding (256-bit encryption) or AES128_CBC_PKCS5Padding (128-bit encryption).

System.out.println("Request verification:" + verificateRequestParams(paramsMap, ACCESS_KEY, 256));

// Mobile number and password to be encrypted

String needEncryptStr = "15905222222";

String encryptStr = generateSaaSUsernameOrPwd(needEncryptStr, ACCESS_KEY, ENCRYPT_TYPE_256);

System.out.println("Mobile number and password to be encrypted:"+ encryptStr);

// Decryption

String decryptStr = decryptMobilePhoneOrEMail(ACCESS_KEY, encryptStr, ENCRYPT_TYPE_256);

System.out.println("Mobile number and password to be decrypted:"+ decryptStr);

// Body signature

String needEncryptBody =

"{\"resultCode\":\"00000\",\"resultMsg\":\"Purchase succeeded\",\"encryptType\":\"1\",\"instanceId\":\"000bd4e1-5726-4ce9-8fe4-fd081a179304\",\"appInfo\"{\"userName\":\"3LQvu8363e5O4zqwYnXyJGWz8y+GAcu0rpM0wQ==\",\"password\":\"RY31aEnR5GMCFmt3iG1hW7UF1HK09MuAL2sgxA==\"}}";

String encryptBody = generateResponseBodySignature(ACCESS_KEY, needEncryptStr);

System.out.println("Body signature:"+ encryptBody);

}

private static Map<String, String[]> getTestUrlMap() {

// Original request: http://bzapic.natappfree.cc?activity=newInstance&businessId=61e834ba-7b97-4418-b8f7-e5345137278c&customerId=68cbc86abc2018ab880d92f36422fa0e&expireTime=20200727153156&orderId=CS1906666666ABCDE&productId=00301-666666-0--0&testFlag=1&timeStamp=20200727073711903&authToken=Gzbfjf9LHRBcI3bFVi++sLinCNOBF6qa7is1fvjEgYQ=

Map<String, String[]> paramsMap = new HashMap<String, String[]>();

paramsMap.put("activity", new String[] {"newInstance"});

paramsMap.put("businessId", new String[] {"61e834ba-7b97-4418-b8f7-e5345137278c"});

paramsMap.put("customerId", new String[] {"68cbc86abc2018ab880d92f36422fa0e"});

paramsMap.put("expireTime", new String[] {"20200727153156"});

paramsMap.put("orderId", new String[] {"CS1906666666ABCDE"});

paramsMap.put("productId", new String[] {"00301-666666-0--0"});

paramsMap.put("testFlag", new String[] {"1"});

paramsMap.put("timeStamp", new String[] {"20200727073711903"});

paramsMap.put("authToken", new String[] {"Gzbfjf9LHRBcI3bFVi++sLinCNOBF6qa7is1fvjEgYQ="});

return paramsMap;

}

/**

* Verify the validity of the request.

*

* @param accessKey Access key

* @param encryptLength Length of the encrypted content

* @return Verification result

*/

public static boolean verificateRequestParams(Map<String, String[]> paramsMap, String accessKey,

int encryptLength) {

String timeStamp = null;

String authToken = null;

String[] timeStampArray = paramsMap.get("timeStamp");

if (null != timeStampArray && timeStampArray.length > 0) {

timeStamp = timeStampArray[0];

}

String[] authTokenArray = paramsMap.get("authToken");

if (null != authTokenArray && authTokenArray.length > 0) {

authToken = authTokenArray[0];

}

// Sort the remaining parameters and combine them to form the encrypted content.

Map<String, String[]> sortedMap = new TreeMap<String, String[]>();

sortedMap.putAll(paramsMap);

sortedMap.remove("authToken");

StringBuffer strBuffer = new StringBuffer();

Set<String> keySet = sortedMap.keySet();

Iterator<String> iter = keySet.iterator();

while (iter.hasNext()) {

String key = iter.next();

String value = sortedMap.get(key)[0];

strBuffer.append("&").append(key).append("=").append(value);

}

// Rectify the message body by removing the ampersand (&) before the first parameter.

String reqParams = strBuffer.toString().substring(1);

String key = accessKey + timeStamp;

String signature = null;

try {

signature = generateResponseBodySignature(key, reqParams);

} catch (InvalidKeyException | NoSuchAlgorithmException | IllegalStateException

| UnsupportedEncodingException e) {

// TODO Auto-generated catch block

}

return authToken.equals(signature);

}

public static String generateResponseBodySignature(String key, String body)

throws InvalidKeyException, NoSuchAlgorithmException, IllegalStateException, UnsupportedEncodingException {

return base_64(hmacSHA256(key, body));

}

public static byte[] hmacSHA256(String macKey, String macData) {

try {

try {

SecretKeySpec secret = new SecretKeySpec(macKey.getBytes(CHARSET), "HmacSHA256");

Mac mac = Mac.getInstance("HmacSHA256");

mac.init(secret);

return mac.doFinal(macData.getBytes(CHARSET));

} catch (UnsupportedEncodingException e) {

} catch (InvalidKeyException e) {

}

} catch (NoSuchAlgorithmException e) {

}

return new byte[0];

}

// Body signature

public static String generateSaaSUsernameOrPwd(String isvBody, String decryptAccessKey, String sEncryptType) {

String iv = getRandomChars(16);

int iEncryptType = 0;

try {

iEncryptType = Integer.parseInt(sEncryptType);

} catch (NumberFormatException exception) {

iEncryptType = 1;

}

int encryptType;

if (1 == iEncryptType) {

encryptType = 256;

} else {

encryptType = 128;

}

String isvEncryptBody = encryptAESCBCEncode(isvBody, decryptAccessKey, iv, encryptType);

return iv + isvEncryptBody;

}

/**

* AES CBC 256-bit encryption

*

* @param content Content to be encrypted

* @param key Encryption key

* @param iv Encrypted salt value

* @return Encryption result

*/

public static String encryptAESCBCEncode(String content, String key, String iv, int encryptType) {

if (StringUtils.isEmpty(content) || StringUtils.isEmpty(key) || StringUtils.isEmpty(iv)) {

return null;

}

try {

byte[] encrypContent =

encryptAESCBC(content.getBytes(CHARSET), key.getBytes(CHARSET), iv.getBytes(CHARSET), encryptType);

if (null != encrypContent) {

return base_64(encrypContent);

} else {

return null;

}

} catch (UnsupportedEncodingException e) {

return null;

}

}

public static byte[] encryptAESCBC(byte[] content, byte[] keyBytes, byte[] iv, int encryptType) {

try {

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

secureRandom.setSeed(keyBytes);

keyGenerator.init(encryptType, secureRandom);

SecretKey key = keyGenerator.generateKey();

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));

return cipher.doFinal(content);

} catch (Exception e) {

}

return null;

}

public static String base_64(byte[] bytes) {

try {

return new String(Base64.encodeBase64(bytes), CHARSET);

} catch (UnsupportedEncodingException e) {

return null;

}

}

static String decryptMobilePhoneOrEMail(String accessKey, String encryptStr, String sEncryptType) {

String iv = encryptStr.substring(0, 16);

int iEncryptType = 1;

try {

iEncryptType = Integer.parseInt(sEncryptType);

} catch (NumberFormatException exception) {

exception.printStackTrace();

}

int encryptType;

if (1 == iEncryptType) {

encryptType = 256;

} else {

encryptType = 128;

}

String decryptBody = null;

try {

decryptBody = decryptAESCBCEncode(encryptStr.substring(16), accessKey, iv, encryptType);

} catch (Exception e) {

e.printStackTrace();

return decryptBody;

}

return decryptBody;

}

public static String decryptAESCBCEncode(String content, String key, String iv, int encryptType)

throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,

InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

if (StringUtils.isEmpty(content) || StringUtils.isEmpty(key) || StringUtils.isEmpty(iv)) {

return null;

}

return new String(decryptAESCBC(org.apache.commons.codec.binary.Base64.decodeBase64(content.getBytes()),

key.getBytes(), iv.getBytes(), encryptType));

}

public static byte[] decryptAESCBC(byte[] content, byte[] keyBytes, byte[] iv, int encryptType)

throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,

InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {

KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");

secureRandom.setSeed(keyBytes);

keyGenerator.init(encryptType, secureRandom);

SecretKey key = keyGenerator.generateKey();

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));

byte[] result = cipher.doFinal(content);

return result;

}

/**

* Obtain a random character string.

*

* @param length Character string length

* @return

* @author d00420944

*/

public static String getRandomChars(int length) {

StringBuffer randomCharsBuf = new StringBuffer(1024);

SecureRandom random = new SecureRandom();

for (int i = 0; i < length; i++) {

// Randomly choose letters and digits.

if (random.nextInt(2) % 2 == 0) {

// Specify whether uppercase or lowercase letters are output.

int letterIndex = random.nextInt(2) % 2 == 0 ? 65 : 97;

randomCharsBuf.append((char) (random.nextInt(26) + letterIndex));

} else {

randomCharsBuf.append(String.valueOf(random.nextInt(10)));

}

}

String randomChars = randomCharsBuf.toString();

return randomChars;

}

}