腾讯云人脸核身实证 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折起,即将结束: 马上收藏
同尘科技为腾讯云授权服务中心,购买腾讯云享受折上折,更有现金返利:同意关联,立享优惠
阿里云解决方案也看看?: 点击对比阿里云的解决方案
暂无评论,你要说点什么吗?