全部
全部
更新时间:2023-08-22 13:52:36
功能接口调用

1)接入方生成RSA2048公私钥对(公私钥对生成方法见下文),签名公钥录入至开放平台“个人中心-API认证账号-RSA验签公钥  (RSA-VerifyPublicKey) ”(需要用户先注册开放平台的登录账号,并进行登录),签名私钥SignPrivateKey用来计算签名调  用接口时,请提前将服务器IP地址添加到用户IP白名单中,否则将无法调用,返回应答码为9901(详见:全局返回码说明)。


(2)使用请求头部信息和、RSA签名私钥SignPrivateKey计算得出签名信息sign。       

            签名规则:

            a. 将请求头部信息的version、appid、bizMethod、reqId和请求报文body以&作为连接符拼接成待签名串, 型如:

                "version=[version]&appId=[appId]&bizMethod= [bizMethod]&reqId=[reqId]&body=[body]";

           b. 对待签名串使用SHA256做摘要(SHA256摘要算法见下文);

            c. 用SignPrivateKey对摘要做RSA2048签名(RSA2048签名算法见下文),得到签名信息sign。

                  SignPrivateKey: RSA签名私钥;

                  body: 请求JSON报文;


(3)使用API认证账号AppId、签名信息sign、请求头部信息header、请求报文body,发出API调用请求。

    HTTP 请求方式:

        POST



    HTTP URL:

        https://openapi.unionpay.com/upapi/cardbin/cardinfo


    HTTP 报文头(header):

        Content-Type: application/json


    其余参数请参考下表:

中文名称

英文名称

域类型

域长度

默认值

请求要求

备注

版本号

version

string

8


M-必填

格式xx.yy.zz

取值举例1.0.0

发送方索引类型

appType

string

2


M-必填

取值:

00:银联索引

01:机构索引

02:商户索引

发送方索引标识码 

appId

string

32


M-必填

由银联分配,请求或应答的发送方填写,标识签名验签对应的发送方

接口类型

bizMethod

string

64


M-必填

取值:宜全英文,不应出现中文

取值举例:cardbin.cardinfo

签名

sign

string

344


M-必填

根据报文签名方法生成对报文摘要的签名

签名或摘要方式

signMethod

string

20


M-必填

取值:

1RSA2

2SM2

发送方流水号

reqId

string

64


M-必填

请求方自行生成,保证每笔交易不重复,但非交易主键


    HTTP 报文体(body):

             JSON格式接口请求报文,如{"cardNo":""}



(4)API接口的请求参数、应答参数依据业务需求会配置校验规则或加解密规则,相关内容请参考《参数规则说明


接入方公私钥对生成方法


方法一:


在Linux环境下,依次执行以下命令,使用OpenSSL生成RSA2048公私钥对。

a.生成RSA2048私钥-》upapi_private_key.pem

    >openssl genrsa -out upapi_private_key.pem 2048

b.根据私钥生成公钥-》upapi_public_key.pem

    >openssl rsa -in upapi_private_key.pem -out upapi_public_key.pem -pubout

将upapi_private_key.pem和upapi_public_key.pem中密钥取出整理为字符串即可。



方法二:


/** 加密算法RSA */

public static final String RSA_ALGORITHM = "RSA";

/** 获取公钥的key */

public static final String PUBLIC_KEY = "RSAPublicKey";

/** 获取私钥的key */

public static final String PRIVATE_KEY = "RSAPrivateKey";

/** 签名长度 */

private static final int KEY_SIZE = 2048;


static {

      if (Security.getProvider("BC") == null) {

        Security.addProvider(new BouncyCastleProvider());

     } else {

        Security.removeProvider("BC");

        Security.addProvider(new BouncyCastleProvider());

      }

}

/**

 * 生成密钥对(公钥和私钥)

 * @return

 * @throws Exception

 */

public static Map<String, Object> genKeyPair() throws Exception {

    KeyPairGenerator keyPairGen =KeyPairGenerator.getInstance(RSA_ALGORITHM);

    keyPairGen.initialize(KEY_SIZE);

    KeyPair keyPair = keyPairGen.generateKeyPair();

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

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

    Map<String, Object> keyMap = new HashMap<String, Object>(2);

    keyMap.put(PUBLIC_KEY, publicKey);

    keyMap.put(PRIVATE_KEY, privateKey);

    return keyMap;

}

/**

 * 获取公钥

 * @param keyMap 密钥对

 * @return

 * @throws Exception

 */

public static String getPublicKey(Map<String, Object> keyMap) {

    Key key = (Key) keyMap.get(PUBLIC_KEY);

    return encode64(key.getEncoded());

}

/**

 * 获取私钥

 * @param keyMap  密钥对

 * @return

 * @throws Exception

 */

public static String getPrivateKey(Map<String, Object> keyMap) {

   Key key = (Key) keyMap.get(PRIVATE_KEY);

   return encode64(key.getEncoded());

}

/**

 * Discription:编码

 * @return String

 */

public static String encode64(byte[] b) {

  return Base64.encodeBase64String(b);

}


报文签名样例代码


RSA非对称认证方式报文签名规则-Java语言


/**

 * RSA非对称认证方式签名算法

 *

 * @param body 请求报文体

 * @param SignPrivateKey  RSA签名私钥

 * @param ts 时间戳

 */
public static String getRSASign(String body,String  SignPrivateKey,String version,String appId,String bizMethod,String reqId){

   // 拼接待签名字符串,计算SHA256摘要
    String signForVerify =  signForRsaSignMethod(version,appId,bizMethod,reqId,body);
    String realSign = null;
    try {

      // 对摘要做RSA2048签名
       realSign  = RSASignUtil.sign(signForVerify.getBytes(),SignPrivateKey);
    } catch (Exception e) {
       e.printStackTrace();
    }
    return realSign;
}

/**

 * RSA非对称认证方式-SHA256摘要算法

 *

 * @param body 报文体

 * @param ts 时间戳

 * @return

 */

public static String signForRsaSignMethod(String version,String appId,String bizMethod,String reqId,String body) {

    String result =  "version="+version+"&appId="+appId+"&bizMethod="+bizMethod+"&reqId="+reqId+"&body="+body;;
    String sign = EncodeUtils.encodeBySHA256(result);
    return sign;
}


SHA256摘要算法实现样例-Java语言


private static final char[] HEX_DIGITS={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};

/**
   * encode By SHA-256
   *
   * @param str
   * @return
   */
public static String encodeBySHA256(String str) {
     if (str == null) {
       return null;
      }
    try {
       MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
       messageDigest.reset();
       messageDigest.update(str.getBytes("UTF-8"));
       return getFormattedText(messageDigest.digest());
     } catch (Exception e) {
       throw new RuntimeException(e);
    }
}

/**
   * 字节数组转换至十六进制字符串
   *
   * @param bytes
   * @return String
   */

private static String getFormattedText(byte[] bytes) {
    int len = bytes.length;

    StringBuilder buf = new StringBuilder(len * 2);
    // 把密文转换成十六进制的字符串形式
    for (int j = 0; j < len; j++) {
        buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
        buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
    }

    return buf.toString();
}


RSA2048签名算法实现样例-Java语言


/** 需要导入包*/

import org.bouncycastle.jce.provider.BouncyCastleProvider;

/* 加密算法*/
public static final String RSA_ALGORITHM = "RSA";

public static final String BC_PROVIDER = "BC";

/**
 * 签名算法
 */

public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";


static {

      if (Security.getProvider("BC") == null) {

        Security.addProvider(new BouncyCastleProvider());

     } else {

        Security.removeProvider("BC");

        Security.addProvider(new BouncyCastleProvider());

      }

}
/**
 * <p>
 * 用私钥对信息生成数字签名
 * </p>
 *
 * @param data
 *            已加密数据
 * @param privateKey
 *            私钥(BASE64编码)
 * @return
 * @throws Exception
 */
public static String sign(byte[] data, String privateKey) throws Exception {
    byte[] keyBytes = decode64(privateKey);

    PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM,
            BC_PROVIDER);

    PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM,
            BC_PROVIDER);
    signature.initSign(privateK);
    signature.update(data);
    return encode64(signature.sign());
}

/**
 * Created on 2013-5-31
 * <p>
 * Discription:编码
 * </p>
 *
 * @return String
 */
public static String encode64(byte[] b) {
    return Base64.encodeBase64String(b);
}

/**
 * Created on 2013-5-31
 * <p>
 * Discription:编码
 * </p>
 *
 * @return btye[]
 */
public static byte[] decode64(String s) {
    return Base64.decodeBase64(s);
}




咨询服务