腾讯云人脸核身实证 NFC 查询结果_AI解决方案_同尘科技
合作伙伴服务端验证结果
此方式用于:合作伙伴服务端生成签名,并调用实证 NFC 服务端查询结果,鉴权完成后返回结果(服务端上送 orderNo 和 appId 查询)。
合作方后台生成签名
准备步骤
前置条件:请合作方确保 SIGN ticket 已经正常获取,获取方式见 获取 SIGN ticket。
合作方为实证 NFC 识别服务生成签名,需要具有以下参数:
| 参数 | 说明 | 来源 | 
| appId | 腾讯服务分配的 Appid | 参考 获取 WBappid 指引在人脸核身控制台内申请 | 
| orderNo | 订单号,本次 NFC 识别合作伙伴上送的订单号,唯一标识,字母/数字组成的字符串 | 合作方自行分配 | 
| version | 默认值:1.0.0 | – | 
| api ticket | 合作伙伴服务端缓存的 tikcet,注意是 SIGN 类型 | 获取方式见 获取 SIGN ticket | 
| nonceStr | 32位随机字符串,字母和数字 | 合作方自行生成 | 
基本步骤
1. 生成一个 32 位的随机字符串 nonceStr(其为字母和数字,登录时也要用到)。2. 将 appId、orderNo、version 连同 ticket、nonceStr 共五个参数的值进行字典序排序。3. 将排序后的所有参数字符串拼接成一个字符串。4. 将排序后的字符串进行 SHA1 编码,编码后的 40 位字符串作为签名(sign)。注意 签名算法可参考 签名算法说明。
实证 NFC 识别结果查询接口
请求
请求 URL:https://miniprogram-kyc.tencentcloudapi.com/api/v2/nfcpaas/getIdcardNfcResult?orderNo=xxx注意 为方便查询耗时,该请求 url 后面请拼接 orderNo 订单号参数。请求方法:POST。
报文格式:Content-Type: application/json。
请求参数:
| 参数 | 说明 | 类型 | 长度(字节) | 是否必填 | 
| appId | 腾讯服务分配的 Appid | 字符串 | 腾讯服务分配 | 是 | 
| orderNo | 订单号,合作方订单的唯一标识,字母/数字组成的字符串 | 字符串 | 32 | 是 | 
| nonce | 随机数 | 字符串 | 32 | 是 | 
| version | 版本号,默认值:1.0.0 | 字符串 | 20 | 是 | 
| sign | 签名值,使用本页第一步生成的签名 | 字符串 | 40 | 是 | 
| reqId | 本次实证 NFC读取唯一标识 | 字符串 | 40 | 是 | 
| getPhoto | 是否需要获取 NFC 识别的证件图片文件,值为1则返回图片 | 字符串 | 1 | 否 | 
响应
响应参数:
| 参数 | 类型 | 说明 | 
| code | String | 0:成功;非0:失败;详情请参见 SaaS 服务错误码 | 
| msg | String | 请求结果描述 | 
| result | NfcQueryRsp | nfc 查询加密结果集 | 
| transactionTime | String | 交易时间戳 | 
NfcQueryRsp 响应参数结构:
| 参数 | 类型 | 说明 | 
| code | String | 0:成功;非0:失败;详情请参见 SaaS 服务错误码 | 
| msg | String | 请求结果描述 | 
| nfcEnResult | String | 加密的 nfc 识别结果 | 
| transactionTime | String | 交易时间戳 | 
nfcEnResult 响应参数结构内容:
| 参数 | 类型 | 说明 | 居民身份证 | 港澳回乡证 | 
| orderNo | string | 订单编号 | ✓ | ✓ | 
| reqId | string | 本次实证 NFC 读取唯一标识 | ✓ | ✓ | 
| name | string | 姓名 | ✓ | ✓ | 
| enName | string | 英文名 | – | ✓ | 
| sex | string | 性别 | ✓ | ✓ | 
| nation | string | 民族 | ✓ | – | 
| birth | string | 出生日期 | ✓ | ✓ | 
| address | string | 地址 | ✓ | – | 
| idcard | string | 证件号 | ✓ | ✓ | 
| validDateBegin | string | 证件的有效期起始时间 | ✓ | – | 
| validDateEnd | string | 证件的有效期结束时间 | ✓ | ✓ | 
| signingOrganization | string | 发证机关 | ✓ | – | 
| frontPhoto | Base 64 string | 证件正面照 | ✓ | – | 
| backPhoto | Base 64 string | 证件反面照 | ✓ | – | 
| portraitPhoto | Base 64 string | 证件人像照 | ✓ | ✓ | 
{    "code": "0",    "msg": "请求成功",    "result": {"bizSeqNo": "1607280FD01141000000000000009003","nfcEnResult":SgoeKZt5nIHQmiLluNxxsdfasdfasdfasdfa1uOswIiebhOPe0SgoeKZt5nIHQmiLluN123123MdsdfKsmiLluN123123MdfsIHQmiLluN123123MdsdfKdf1uOswIiebhOPe0SgoeKZt5nIH"},    "bizSeqNo": "1607280FD01141000000000000009003",        "transactionTime": "20160728075617"}
注意照片均为 base64 位编码,其中照片解码后格式一般为 JPG。返回报文加密nfcEnResult部分,解密后为响应参数。解密示例:
第一步先 base64解码 nfcEnResult 字段,第二步通过 SM4国密算法根据下发的处理后密钥(主力方式:将十六进制密钥转为字节数组)解密第一步解码结果,第三步将第二步结果 json 解析为 nfcEnResult 解密结构内容。
解密代码示例(JAVA):
import com.google.common.io.BaseEncoding;import org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.Cipher;import javax.crypto.spec.SecretKeySpec;import java.security.Key;import java.security.Security;import java.util.Random;/** *     项目所依赖的类: *      List utils = [ *      "commons-io:commons-io:2.7", *      "com.google.guava:guava:16.0.1", *      "org.bouncycastle:bcprov-jdk15to18:1.66", *      ] * * @date 2022-03-04-10:27 */public class SM4 {    private static final String ENCODING = "UTF-8";    public static final String ALGORITHM_NAME = "SM4";    // 加密算法/分组加密模式/分组填充方式    // PKCS5Padding-以8个字节为一组进行分组加密    // 定义分组加密模式使用:PKCS5Padding    public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";    /**     * 生成 SM4 Cipher     * @return     * @throws Exception     */    protected static Cipher generateCipher(int mode,byte[] keyData) throws Exception {        Cipher cipher = Cipher.getInstance(ALGORITHM_NAME_ECB_PADDING,BouncyCastleProvider.PROVIDER_NAME);        Key sm4Key = new SecretKeySpec(keyData,ALGORITHM_NAME);        cipher.init(mode,sm4Key);        return cipher;    }    /**     * 加密模式之     * @param key  密钥     * @param data 待加密的内容     * @return     * @throws Exception     * @explain     */    public static byte[] encrypt(byte[] key,byte[] data) throws Exception {        Cipher cipher = generateCipher(Cipher.ENCRYPT_MODE,key);        return cipher.doFinal(data);    }    /**     * sm4解密     * @param     * @param cipherText 16进制的加密字符串(忽略大小写)     * @return 解密后的字符串     * @throws Exception     * @explain 解密模式:采用ECB     */    public static String decrypt(String key,String cipherText) throws Exception {        // 用于接收解密后的字符串        String decryptStr = "";        byte[] keyData = key.getBytes();        byte[] cipherData = cipherText.getBytes();        // 解密        byte[] srcData = decrypt(keyData,cipherData);        // byte[]-->String        decryptStr = new String(srcData,ENCODING);        return decryptStr;    }    /**     * 解密     * @param key     * @param cipherText     * @return 解密后的内容  byte[]     * @throws Exception     * @explain     */    public static byte[] decrypt(byte[] key,byte[] cipherText) throws Exception {        Cipher cipher = generateCipher(Cipher.DECRYPT_MODE,key);        return cipher.doFinal(cipherText);    }    /**     * 将byte转换为16进制字符串     * @param src     * @return     */    public static String byteToHexString(byte[] src) {        StringBuilder sb = new StringBuilder();        for (int i = 0; i < src.length; i++) {            int v = src[i] & 0xff;            String hv = Integer.toHexString(v);            if (hv.length() < 2) {                sb.append("0");            }            sb.append(hv);        }        return sb.toString();    }    /**     * 将16进制字符串转换为字节数组     * @param str 16进制字符串     * @return byte[]     */    public static byte[] hexStringToBytes(String str) {        byte[] bytes;        bytes = new byte[str.length() / 2];        for (int i = 0; i < bytes.length; i++) {            bytes[i] = (byte) Integer.parseInt(str.substring(2 * i,2 * i + 2),16);        }        return bytes;    }    /**     * 接入方拿到key(即控制台申请的 NFC 秘钥) 先可以跑通下面的案例,并认真阅读 1,2,3,4     * 项目所依赖的类:     * List utils = [     * "commons-io:commons-io:2.7",     * "com.google.guava:guava:16.0.1",     * "org.bouncycastle:bcprov-jdk15to18:1.66",     * ]     * @param args     * @throws Exception     */    public static void main(String[] args) throws Exception {        // 1. 系统初始话的时候,需要注入所使用的 provider        Security.addProvider(new BouncyCastleProvider());        // 2.收到key后,先从hex转成byte[],加解密就是用byte[]输入        byte[] key = hexStringToBytes("7F26724F72D48EBA5AD3848B30B81122");        // 3.测试的文本内容        String src = "168,FM973 全角半角测试,你好,大家好,你好,美丽人生Efgkymk";        byte[] enSrc = encrypt(key,src.getBytes());        String base64EnStr = BaseEncoding.base64().encode(enSrc);        System.out.println("base64 en:" + base64EnStr);        // 4.解密,用户只需要执行解密即可(先base64 转成byte[] 然后执行解密)        byte[] decSrc = decrypt(key,BaseEncoding.base64().decode(base64EnStr));        System.out.println("===== base64 dec:" + new String(decSrc,ENCODING));    }}
对解决方案有疑惑?想了解解决方案收费?  联系解决方案专家
腾讯云限时活动1折起,即将结束: 马上收藏
同尘科技为腾讯云授权服务中心,购买腾讯云享受折上折,更有现金返利:同意关联,立享优惠
阿里云解决方案也看看?: 点击对比阿里云的解决方案
 
								 
										 
										
暂无评论,你要说点什么吗?