金蝶银行卡实名认证接口

----->   金蝶实名认证接口文档下载地址    <-----

(请先留意金蝶实名认证接口文档(涉及加解密、偏移量、签名秘钥))

3DES加解密Util

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class Cipher3DES {
	//private final static Logger log = LoggerFactory.getLogger(Cipher3DES.class);
	
	public static String encrypt(String toEncode, String key, String vector){
		try {
			Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
			DESedeKeySpec dks = new DESedeKeySpec(key.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory
					.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);
			IvParameterSpec iv = new IvParameterSpec(vector.getBytes(), 0,
					cipher.getBlockSize());
			cipher.init(1, securekey, iv);
			byte[] encoded = cipher.doFinal(toEncode.getBytes("UTF-8"));
			return CipherBase64.encryptBASE64(encoded);
		} catch (NoSuchAlgorithmException | NoSuchPaddingException
				| InvalidKeyException | InvalidKeySpecException
				| InvalidAlgorithmParameterException
				| IllegalBlockSizeException | BadPaddingException
				| UnsupportedEncodingException e) {
			//log.error(e.getMessage());
		}
		return null;
	}

	public static String decrypt(String toDecode, String key, String vector) {
		try {
			Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
			DESedeKeySpec dks = new DESedeKeySpec(key.getBytes());
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			SecretKey securekey = keyFactory.generateSecret(dks);
			IvParameterSpec iv = new IvParameterSpec(vector.getBytes(), 0,
					cipher.getBlockSize());
			cipher.init(2, securekey, iv);
			byte[] todecodeBytes = CipherBase64.decryptBASE64(toDecode);
			String decoded = new String(cipher.doFinal(todecodeBytes), "utf-8");
			return decoded;
		} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidKeySpecException | InvalidAlgorithmParameterException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e) {
			//log.error(e.getMessage());
		}
		return null;
	}
}

Base64加解密

public class CipherBase64 {
	private static final byte[] base64Alphabet = new byte[''];
	private static final char[] lookUpBase64Alphabet = new char[64];

	public static byte[] decryptBASE64(String encoded) {
		if (encoded == null) {
			return null;
		}

		char[] base64Data = encoded.toCharArray();

		int len = removeWhiteSpace(base64Data);

		if (len % 4 != 0) {
			return null;
		}

		int numberQuadruple = len / 4;

		if (numberQuadruple == 0) {
			return new byte[0];
		}

		byte[] decodedData = null;
		byte b1 = 0;
		byte b2 = 0;
		byte b3 = 0;
		byte b4 = 0;
		char d1 = '\000';
		char d2 = '\000';
		char d3 = '\000';
		char d4 = '\000';

		int i = 0;
		int encodedIndex = 0;
		int dataIndex = 0;
		decodedData = new byte[numberQuadruple * 3];

		for (; i < numberQuadruple - 1; i++) {
			if ((!isData(d1 = base64Data[(dataIndex++)]))
					|| (!isData(d2 = base64Data[(dataIndex++)]))
					|| (!isData(d3 = base64Data[(dataIndex++)]))
					|| (!isData(d4 = base64Data[(dataIndex++)]))) {
				return null;
			}

			b1 = base64Alphabet[d1];
			b2 = base64Alphabet[d2];
			b3 = base64Alphabet[d3];
			b4 = base64Alphabet[d4];

			decodedData[(encodedIndex++)] = ((byte) (b1 << 2 | b2 >> 4));
			decodedData[(encodedIndex++)] = ((byte) ((b2 & 0xF) << 4 | b3 >> 2 & 0xF));
			decodedData[(encodedIndex++)] = ((byte) (b3 << 6 | b4));
		}

		if ((!isData(d1 = base64Data[(dataIndex++)]))
				|| (!isData(d2 = base64Data[(dataIndex++)]))) {
			return null;
		}

		b1 = base64Alphabet[d1];
		b2 = base64Alphabet[d2];

		d3 = base64Data[(dataIndex++)];
		d4 = base64Data[(dataIndex++)];
		if ((!isData(d3)) || (!isData(d4))) {
			if ((isPad(d3)) && (isPad(d4))) {
				if ((b2 & 0xF) != 0) {
					return null;
				}
				byte[] tmp = new byte[i * 3 + 1];
				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
				tmp[encodedIndex] = ((byte) (b1 << 2 | b2 >> 4));
				return tmp;
			}
			if ((!isPad(d3)) && (isPad(d4))) {
				b3 = base64Alphabet[d3];
				if ((b3 & 0x3) != 0) {
					return null;
				}
				byte[] tmp = new byte[i * 3 + 2];
				System.arraycopy(decodedData, 0, tmp, 0, i * 3);
				tmp[(encodedIndex++)] = ((byte) (b1 << 2 | b2 >> 4));
				tmp[encodedIndex] = ((byte) ((b2 & 0xF) << 4 | b3 >> 2 & 0xF));
				return tmp;
			}
			return null;
		}

		b3 = base64Alphabet[d3];
		b4 = base64Alphabet[d4];
		decodedData[(encodedIndex++)] = ((byte) (b1 << 2 | b2 >> 4));
		decodedData[(encodedIndex++)] = ((byte) ((b2 & 0xF) << 4 | b3 >> 2 & 0xF));
		decodedData[(encodedIndex++)] = ((byte) (b3 << 6 | b4));

		return decodedData;
	}

	public static String encryptBASE64(byte[] binaryData) {
		if (binaryData == null) {
			return null;
		}

		int lengthDataBits = binaryData.length * 8;
		if (lengthDataBits == 0) {
			return "";
		}

		int fewerThan24bits = lengthDataBits % 24;
		int numberTriplets = lengthDataBits / 24;
		int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1
				: numberTriplets;
		char[] encodedData = null;

		encodedData = new char[numberQuartet * 4];

		byte k = 0;
		byte l = 0;
		byte b1 = 0;
		byte b2 = 0;
		byte b3 = 0;

		int encodedIndex = 0;
		int dataIndex = 0;

		for (int i = 0; i < numberTriplets; i++) {
			b1 = binaryData[(dataIndex++)];
			b2 = binaryData[(dataIndex++)];
			b3 = binaryData[(dataIndex++)];

			l = (byte) (b2 & 0xF);
			k = (byte) (b1 & 0x3);

			byte val1 = (b1 & 0xFFFFFF80) == 0 ? (byte) (b1 >> 2)
					: (byte) (b1 >> 2 ^ 0xC0);
			byte val2 = (b2 & 0xFFFFFF80) == 0 ? (byte) (b2 >> 4)
					: (byte) (b2 >> 4 ^ 0xF0);
			byte val3 = (b3 & 0xFFFFFF80) == 0 ? (byte) (b3 >> 6)
					: (byte) (b3 >> 6 ^ 0xFC);

			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[val1];
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[(val2 | k << 4)];
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[(l << 2 | val3)];
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[(b3 & 0x3F)];
		}

		if (fewerThan24bits == 8) {
			b1 = binaryData[dataIndex];
			k = (byte) (b1 & 0x3);

			byte val1 = (b1 & 0xFFFFFF80) == 0 ? (byte) (b1 >> 2)
					: (byte) (b1 >> 2 ^ 0xC0);
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[val1];
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[(k << 4)];
			encodedData[(encodedIndex++)] = '=';
			encodedData[(encodedIndex++)] = '=';
		} else if (fewerThan24bits == 16) {
			b1 = binaryData[dataIndex];
			b2 = binaryData[(dataIndex + 1)];
			l = (byte) (b2 & 0xF);
			k = (byte) (b1 & 0x3);

			byte val1 = (b1 & 0xFFFFFF80) == 0 ? (byte) (b1 >> 2)
					: (byte) (b1 >> 2 ^ 0xC0);
			byte val2 = (b2 & 0xFFFFFF80) == 0 ? (byte) (b2 >> 4)
					: (byte) (b2 >> 4 ^ 0xF0);

			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[val1];
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[(val2 | k << 4)];
			encodedData[(encodedIndex++)] = lookUpBase64Alphabet[(l << 2)];
			encodedData[(encodedIndex++)] = '=';
		}

		return new String(encodedData);
	}

	private static int removeWhiteSpace(char[] data) {
		if (data == null) {
			return 0;
		}

		int newSize = 0;
		int len = data.length;
		for (int i = 0; i < len; i++) {
			if (!isWhiteSpace(data[i])) {
				data[(newSize++)] = data[i];
			}
		}
		return newSize;
	}

	private static boolean isWhiteSpace(char octect) {
		return (octect == ' ') || (octect == '\r') || (octect == '\n')
				|| (octect == '\t');
	}

	private static boolean isPad(char octect) {
		return octect == '=';
	}

	private static boolean isData(char octect) {
		return (octect < '') && (base64Alphabet[octect] != -1);
	}

	static {
		for (int i = 0; i < 128; i++) {
			base64Alphabet[i] = -1;
		}
		for (int i = 90; i >= 65; i--) {
			base64Alphabet[i] = ((byte) (i - 65));
		}
		for (int i = 122; i >= 97; i--) {
			base64Alphabet[i] = ((byte) (i - 97 + 26));
		}

		for (int i = 57; i >= 48; i--) {
			base64Alphabet[i] = ((byte) (i - 48 + 52));
		}

		base64Alphabet[43] = 62;
		base64Alphabet[47] = 63;

		for (int i = 0; i <= 25; i++) {
			lookUpBase64Alphabet[i] = ((char) (65 + i));
		}

		int i = 26;
		for (int j = 0; i <= 51; j++) {
			lookUpBase64Alphabet[i] = ((char) (97 + j));

			i++;
		}

		i = 52;
		for (int j = 0; i <= 61; j++) {
			lookUpBase64Alphabet[i] = ((char) (48 + j));

			i++;
		}

		lookUpBase64Alphabet[62] = '+';
		lookUpBase64Alphabet[63] = '/';
	}
}

签名方式

根据用户自己的签名私钥对加密报文进行签名

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
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.HashMap;
import java.util.Map;

public class RsaSignCoder {
	//private static final Logger log = LoggerFactory.getLogger(Cipher3DES.class);

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static Map<String, Object> initKey() {
		try {
			KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
			keyPairGenerator.initialize(512);

			KeyPair keyPair = keyPairGenerator.generateKeyPair();

			RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

			RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

			Map keyMap = new HashMap();
			keyMap.put("RSAPublicKey", publicKey);
			keyMap.put("RSAPrivateKey", privateKey);
			return keyMap;
		} catch (NoSuchAlgorithmException e) {
			//log.error(e.getMessage());
		}
		return null;

	}

	public static String sign(String datas, String privates) {
		byte[] data = datas.getBytes();
		byte[] privateKey = CipherBase64.decryptBASE64(privates);

		PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
			Signature signature = Signature.getInstance("MD5withRSA");
			signature.initSign(priKey);
			signature.update(data);
			return CipherBase64.encryptBASE64(signature.sign());
		} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException | InvalidKeySpecException e) {
			//log.error(e.getMessage());
		}
		return null;

	}

	public static boolean verify(String datas, String publicKeys, String signs) {
		byte[] data = datas.getBytes();
		byte[] publicKey = CipherBase64.decryptBASE64(publicKeys);
		byte[] sign = CipherBase64.decryptBASE64(signs);

		try {
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKey);
			PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
			Signature signature = Signature.getInstance("MD5withRSA");
			signature.initVerify(pubKey);
			signature.update(data);
			return signature.verify(sign);
		} catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | SignatureException e) {
			//log.error(e.getMessage());
		}
		return false;
	}

	public static String getPrivateKey(Map<String, Object> keyMap) {
		Key key = (Key) keyMap.get("RSAPrivateKey");
		return CipherBase64.encryptBASE64(key.getEncoded());
	}

	public static String getPublicKey(Map<String, Object> keyMap) {
		Key key = (Key) keyMap.get("RSAPublicKey");
		return CipherBase64.encryptBASE64(key.getEncoded());
	}

}

四要素

其中涉及到的client_id(云平台id),client_secret ( 云平台秘钥 ),publicKey(公钥),PrivateKey(私钥)需要联系金蝶提供。

import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

import javax.inject.Singleton;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ningze.entity.ReqDate;

@Singleton
@Path("")
public class FourElements {
	private static final Logger LOGGER = LogManager.getLogger(FourElements.class.getName());

	private final static String client_id = "******";
	private final static String client_secret = "1a0b365*********************";

	private final static String PRIVATE_KEY = "*******************************";

	private final static String PUBLIC_KEY = "********************************";

	@Autowired
	private ReqDate req = new ReqDate();

	@POST
	@Path("/realName")
	@Produces(MediaType.APPLICATION_JSON)
	public Response identification2(/*@Context UriInfo uri, @Context HttpHeaders headers,*/ String requestJson) {
		JSONObject request = JSONObject.parseObject(requestJson);
		String realName = request.getString("realName");
		String bankCard = request.getString("bankCard");

		// 偏移量
		String vector = UUID.randomUUID().toString().substring(0, 8);

		JSONObject responseJSON = new JSONObject();
		responseJSON.put("realName", realName);
		responseJSON.put("bankCard", bankCard);
		responseJSON.put("client_id", client_id);
		responseJSON.put("client_secret", client_secret);

		StringBuffer strBuff = new StringBuffer();

                // 利用fastjson将jsonobject对象转为map类型   
                TreeMap<String, String> jsonMap = JSONObject.parseObject(responseJSON.toJSONString(),
				new TypeReference<TreeMap<String, String>>() {});

                // 所有需签名字段按key的字典序连接,组成key1=value1&key2=value2的方式
                for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
			strBuff.append(entry.getKey() + "=" + entry.getValue() + "&");
		}

		// 签名
		String signature = RsaSignCoder.sign(strBuff.substring(0, strBuff.length() - 1), PRIVATE_KEY);
		responseJSON.put("sign", signature);

		// 加密
		String encrData = Cipher3DES.encrypt(responseJSON.toJSONString(), PUBLIC_KEY, vector);

		// 加密后输入
		req.setAppid(client_id);
		req.setData(encrData);
		req.setVector(vector);

                String url = "https://www.bigdataxy.com/api/v2/verify/bankcard/check2";
		// 模拟客户端请求
		Response resp = ClientBuilder.newClient().target(url).request()
				.post(Entity.entity(JSONObject.toJSONString(req), MediaType.APPLICATION_JSON));

		JSONObject responseJson = JSONObject.parseObject(resp.readEntity(String.class));
		// JSONObject jData=responseJson.getJSONObject("data");
		
		return Response.status(200).entity(responseJson.toString()).type(new MediaType("application", "json", "UTF-8"))
				.build();
	}
	
	
	public static void main(String[] args) {
		FourElements four = new FourElements();
		String requestJson = "{\"realName\":\"***\",\"bankCard\":\"*******\"}";
		Response res = four.identification2(requestJson);
		//res.getEntity().
		System.out.println(res.getEntity());
	}
}


返回结果:
{
    "msg": "操作成功",
    "data": {
        "result": "HgZ/NySGpVe4k/CWSetm71DlEpjOibEBffW7iIUEL86VxEv4F9cv2Rzw+lDPHEmIVrAVH+ZrK/9+yzNIuwMyTc2BvHN6XdnXrvNefSflm5T81FqUHf8UAtCHeQQPaLa4Zbl/igcHQyvADNvsqjvDb4rrIRosVNMnld1CnjcAiShzvyeejltQomjITHJD+OlqYOIU+TumOb4=",
        "sign": "COZ5+y4ArU7de4xi5RYdtHExU5UAobcg0VVMUnNxTLpkT91bfg6pbtwPv5bz6wa7daTelABPBA0UDitndMHbB0gxjSxvu/TcYaY90WJ/4dMjC38XIvkyuVVYPSpSchDQnaZ3RkjlAMtEuZTqWmXZ946woxVKYjtojX9otnUqNho=",
        "vector": "8a53a4cd"
    },
    "status": 200
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值