文档中心>人脸核身

E证通获取实名信息指引

最近更新时间:2025-03-14 15:33:12

我的收藏
基于对个人隐私信息的保护,按照最小必要返回身份信息的要求,E证通服务不再返回姓名和身份证号的明文信息。如因业务需要返回,可以在 控制台 申请加密的形式返回。申请流程如下:

1. 申请实名信息返回

登录腾讯云 人脸核身控制台,单击自助接入-E证通服务,在E证通服务列表右侧操作栏中单击申请返回身份信息。 将 CA 证书申请表CSR(证书签名请求)文件上传到控制台,确认后单击提交进行申请。


CA 证书申请表参考 模板 进行填写,并上传控制台。
注意
三联申请表及办理人身份证、营业执照复印件需要加盖单位公章。
CSR(证书签名请求)文件制作操作步骤参考如下步骤2。

2. 制作 CSR 文件

2.1 安装国密 SSL
注意
目前该工具安装暂不支持 MAC M1 处理器。
提供两种下载方式:
git 下载,需要先安装 git 工具。
# 拉取源码
git clone -b GmSSL-v2 https://github.com/guanzhi/GmSSL.git
# 进入目录
cd GmSSL
链接下载。
# 下载源码包
wget https://github.com/guanzhi/GmSSL/archive/refs/heads/GmSSL-v2.zip
# 解压文件
unzip GmSSL-v2.zip
# 进入目录
cd GmSSL-GmSSL-v2
下载方式任选一种,成功执行后,已经进入相应文件夹内,然后执行下方操作:
# 如果 MAC 机器,执行,Linux 环境机器跳过该步骤直接编译即可
sed -i '' 's%qw/glob%qw/:glob%g' Configure
sed -i '' 's%qw/glob%qw/:glob%g' test/build.info
# 编译
./config
# 安装(如果有旧版本,可以使用 make uninstall 卸载,然后删除对应文件)
make
sudo make install
# 安装成功后,查看安装信息
gmssl version -a
2. 2 生成公私钥对
gmssl ecparam -genkey -name sm2p256v1 -out CAkey.pem
2.3 查看并保留私钥
注意:
请务必复制保存私钥。
gmssl pkey -in CAkey.pem -noout -text



2.4 创建证书请求
gmssl req -utf8 -new -sm3 -key CAkey.pem -out CAcsr.pem



2.5 查看证书请求
gmssl req -in CAcsr.pem -noout -text -subject
至此,证书请求制作完成,请将 CAcsr.pem 文件上传 控制台数据解密需要使用CAkey.pem(私钥),请自行妥善保存,否则将无法完成解密

3. 解密流程

在拉到核身结果后,EidInfo 中会有 DesKey 和 UserInfo,需要使用上面生成私钥解密。解密过程如下:
使用 SM2 和上面生成的私钥对 DesKey(Base64 decode 成字节数组)解密获得“会话密钥”。
使用会话密钥和sm4算法 ecb 模式(无填充)解密获得明文字符串。
字符串格式为{"name":"姓名","idtype":"01(代表身份证)","idnum":"身份证号"}。

3.1 Demo 代码

GO 代码示例:
// require github.com/tjfoc/gmsm v1.4.1 或者go get github.com/tjfoc/gmsm
import(
"github.com/tjfoc/gmsm/sm2"
"github.com/tjfoc/gmsm/sm4"
"github.com/tjfoc/gmsm/x509"
)
// 上述2.3 查看并保留私钥过程中获取到的priv内容,去掉冒号,即为PrivateKey的值
const PrivateKey = "f9b587743f051b1e59efa05125f31b5bf371957bf3d3012c1739091334b73738"
// GetEidResult接口返回的DesKey字段值
const DesKey = "xxx"
// GetEidResult接口返回的UserInfo字段值
const UserInfo = "xxx"

func decode() {
privateKey, err := x509.ReadPrivateKeyFromHex(PrivateKey) //上述私钥16进制
dek, _ := base64.StdEncoding.DecodeString(DesKey)
sm4Key, err := sm2.Decrypt(privateKey, dek, 0)
info, _ := base64.StdEncoding.DecodeString(UserInfo)
out, err := sm4.Sm4Ecb(sm4Key, info, false)
fmt.Println(string(out), err)
}
Java 代码示例:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.62</version>
</dependency>
// bouncycastle 版本 >=1.62

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.engines.SM2Engine.Mode;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.Key;
import java.security.Security;

/**
* EID解密工具类
*/
public class EIDUtil {
static {
Security.addProvider(new BouncyCastleProvider());
}

public static byte[] decodeUserInfo(String privateKeyHex, String desKey, String userInfo) throws Exception {
byte[] sm4KeyBytes = EIDUtil.sm2Decrypt(privateKeyHex, Base64.decode(desKey));
return EIDUtil.sm4Decrypt(sm4KeyBytes, Base64.decode(userInfo));
}

public static byte[] sm2Decrypt(String privateKeyHex, byte[] sm2Cipher) throws Exception {
X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
ECDomainParameters domainParameters = new ECDomainParameters(
sm2ECParameters.getCurve(),
sm2ECParameters.getG(),
sm2ECParameters.getN(),
sm2ECParameters.getH()
);
BigInteger d = new BigInteger(1, Hex.decode(privateKeyHex));
ECPrivateKeyParameters privateKey = new ECPrivateKeyParameters(d, domainParameters);
SM2Engine engine = new SM2Engine(Mode.C1C3C2);
engine.init(false, privateKey);
return engine.processBlock(sm2Cipher, 0, sm2Cipher.length);
}

public static byte[] sm4Decrypt(byte[] key, byte[] cipherText) throws Exception {
Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding", BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, "SM4");
cipher.init(Cipher.DECRYPT_MODE, sm4Key);
return cipher.doFinal(cipherText);
}

public static void main(String[] args) throws Exception {
// 上述2.3 查看并保留私钥过程中获取到的priv内容,去掉冒号,即为PrivateKey的值
String PrivateKeyHex = "f9b587743f051b1e59efa05125f31b5bf371957bf3d3012c1739091334b73738";
// GetEidResult接口返回的DesKey字段值
String DesKey = "";
// GetEidResult接口返回的UserInfo字段值
String UserInfo = "";
// 调用EIDUtil解密用户信息
byte[] b = EIDUtil.decodeUserInfo(PrivateKeyHex, DesKey, UserInfo);
System.out.println(new String(b));
}
}
nodejs 代码示例:
const {SM2, SM4} = require('gm-crypto')
// 上述2.3 查看并保留私钥过程中获取到的priv内容,去掉冒号,即为PrivateKey的值
const PrivateKeyHex = "f9b587743f051b1e59efa05125f31b5bf371957bf3d3012c1739091334b73738"
// GetEidResult接口返回的DesKey字段值
const DesKey = "xxx"
// GetEidResult接口返回的UserInfo字段值
const UserInfo = "xxx"

const sm4Key = SM2.decrypt(Buffer.from(DesKey, 'base64').toString("hex").substring(2),
PrivateKeyHex, {
inputEncoding: 'hex',
outputEncoding: 'hex',
mode: 1
})

const plaintext = SM4.decrypt(UserInfo, sm4Key, {
inputEncoding: 'base64',
outputEncoding: 'utf8'
})

console.log(plaintext)
PHP 代码实例:
<?php
// 确保已通过 Composer 安装 phpsm2sm3sm4 库。composer require lpilp/guomi
// 版本要求: PHP >= 7.2, 打开gmp组件支持 phpsm2sm3sm4 >= 2.0
require 'vendor/autoload.php';
use Rtgm\\sm\\RtSm2;
use Rtgm\\sm\\RtSm4;

// 上述2.3 查看并保留私钥过程中获取到的priv内容,去掉冒号,即为PrivateKey的值
$privateKey = 'f9b587743f051b1e59efa05125f31b5bf371957bf3d3012c1739091334b73738';
// GetEidResult接口返回的DesKey字段值
$desKey = 'xxx';
// GetEidResult接口返回的UserInfo字段值
$userInfo = "xxx";
// 使用sm2解密desKey
$sm2 = new RtSm2();
$key = $sm2->doDecrypt(bin2hex(base64_decode($desKey)), $privateKey, $trim = true, $model = C1C3C2);
// 使用sm4解密userInfo
$sm4 = new RtSm4($key);
$userInfo = $sm4->decrypt(bin2hex(base64_decode($userInfo)),'sm4-ecb', '', 'hex');
echo ("解密后的userInfo: ".$userInfo);