当前位置: 首页 > java >正文

Go中使用国家新闻出版署实名认证

随着网络游戏防沉迷系统的接入,实名认证验证也是一个必不可少的部分,网上有第三方的实名认证但基本上都收费,国家新闻出版署提供了免费的接口,不过需要自己去提交申请,获取应用标识 (APPID)应用密钥 (Secret Key)业务权限标识(BizId),并将请求服务器的IP设为白名单后,就可以调用https:// api.wlc.nppa.gov.cn/idcard/authentication/check接口来获取实名认真了。

这个接口中请求体body使用了AES-128/GCM + BASE64算法加密,签名使用了sha256。直接上完整的代码

import ("bytes""crypto/aes""crypto/cipher""crypto/rand""crypto/sha256""encoding/base64""encoding/hex""encoding/json""fmt""io""io/ioutil""net/http""sort""strconv""time"
)// 国家新闻出版署配置信息
type nppaInfo struct {AppId     string // 应用标识SecretKey string // 应用密钥BizId     string // 业务权限标识
}var nppa nppaInfo// 输入国家新闻出版署配置信息
func NppaInit(appId, secretKey, bizId string) {nppa = nppaInfo{AppId:     appId,SecretKey: secretKey,BizId:     bizId,}
}// 实名验证
// ai 	- 游戏内部成员标识,固定32位字符,一般使用 md5(用户ID)
// name - 实名信息中的姓名
// id 	- 实名信息中身份证号码
// 返回
// 		- result 是否验证成功
// 		- errcode 状态码
// 		- errmsg 状态描述
func NppaCheck(ai, name, id string) (result bool, errcode int, errmsg string ) {client := &http.Client{}// body 参数param := map[string]string{"ai":    ai,"name":  name,"idNum": id,}// AES-128/GCM + BASE64算法加密jsonParam, _ := json.Marshal(param)cipher, _ := gcmEncrypt(string(jsonParam))body, _ := json.Marshal(map[string]string{"data": cipher,})// post请求地址req, _ := http.NewRequest("POST", "https://api.wlc.nppa.gov.cn/idcard/authentication/check", bytes.NewReader(body))// header头验证信息headers := map[string]string{"appId":      nppa.AppId,"bizId":      nppa.BizId,"timestamps": strconv.FormatInt(time.Now().UnixNano()/1e6, 10),}// 签名headers["sign"] = sign(headers, string(body))headers["Content-Type"] = "application/json;charset=utf-8"for k, v := range headers {req.Header.Set(k, v)}// 请求resp, err := client.Do(req)if err != nil {return false, -1, "Http请求错误"}defer resp.Body.Close()if resp.StatusCode != 200 {return false, resp.StatusCode, "Http请求返回码错误"}str, err := ioutil.ReadAll(resp.Body)if err != nil {return false, -2, "Http请求返回数据为空"}var msg map[string]interface{}err = json.Unmarshal(str, &msg)if err != nil {return false, -3, "Http请求返回数据格式错误"}ec, ok := msg["errcode"]if !ok {return false, -3, "Http请求返回数据格式错误"}errcode = int(ec.(float64))if errcode != 0 {errmsg, _:= msg["errmsg"]return false, errcode, errmsg.(string)}data, ok := msg["data"]if !ok {return false, -3, "Http请求返回数据格式错误"}r, ok := data.(map[string]interface{})["result"]if !ok {return false, -3, "Http请求返回数据格式错误"}status, ok := r.(map[string]interface{})["status"]if !ok {return false, -3, "Http请求返回数据格式错误"}errcode = int(status.(float64))if errcode == 0{return true, 0, "认证成功"} else if errcode == 1 {return false, errcode, "认证中"}else {return false, errcode, "认证失败"}
}func gcmEncrypt(originalText string) (string, error) {// 需要解码key, _ := hex.DecodeString(nppa.SecretKey)block, err := aes.NewCipher(key)if err != nil {return "", err}aesGcm, err := cipher.NewGCM(block)if err != nil {return "", err}// 向量nonce := make([]byte, aesGcm.NonceSize())if _, err := io.ReadFull(rand.Reader, nonce); err != nil {return "", err}cipherText := aesGcm.Seal(nonce, nonce, []byte(originalText), nil)// encode as base64 stringencoded := base64.StdEncoding.EncodeToString(cipherText)return encoded, nil
}func sign(headers map[string]string, body string) string {var data stringvar keys []string// key排序for k := range headers {keys = append(keys, k)}sort.Strings(keys)// 拼接for _, k := range keys {data = data + k + headers[k]}data = nppa.SecretKey + data + body// 对字符串进行sha256哈希h := sha256.New()h.Write([]byte(data))sum := h.Sum(nil)return hex.EncodeToString(sum)
}

调用

func main() {// 初始化NppaInit("test-appId","2836e95fcd10e04b0069bb1ee659955b","test-bizId")// 使用userId := "123456"name := "岑吾"id := "xxxxxxxxxxxxxxxxxx"h := md5.New()h.Write([]byte(userId))ok,code,msg := NppaCheck(hex.EncodeToString(h.Sum(nil)), name, id)fmt.Println(ok,code,msg)
}

详细返回参数可见网络游戏防沉迷实名认证系统

http://www.xdnf.cn/news/14810.html

相关文章:

  • 【ACP】阿里云云计算高级运维工程师--ACP
  • 硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
  • Docker Desktop 安装到D盘(包括镜像下载等)+ 汉化
  • 7.4_面试_JAVA_
  • css-多条记录,自动换行与自动并行布局及gap兼容
  • linux_git的使用
  • 如何调节笔记本电脑亮度?其实有很多种方式可以调整亮度
  • 深入剖析MYSQL MVCC多版本并发控制+ReadView视图快照规避幻读问题
  • AD7780BRUZ-REEL ADI 24位低功耗ADC转换器 高精度传感器信号链一站式解决方案
  • js中的FileReader对象
  • 指针篇(7)- 指针运算笔试题(阿里巴巴)
  • 计算机科学导论(1)哈佛架构
  • 高功率的照明LN2系列助力电子元件薄膜片检测
  • 二叉树题解——验证二叉搜索树【LeetCode】后序遍历
  • 【狂飙AGI】第8课:AGI-行业大模型(系列2)
  • LangChain 全面入门
  • [ctfshow web入门] web94 `==`特性与intval特性
  • 【Python小工具】使用 OpenCV 获取视频时长的详细指南
  • 【Note】《深入理解Linux内核》Chapter 9 :深入理解 Linux 内核中的进程地址空间管理机制
  • FASTAPI+VUE3平价商贸管理系统
  • MySQL数据库----DML语句
  • 论文阅读笔记——Autoregressive Image Generation without Vector Quantization
  • uniapp打包微信小程序主包过大问题_uniapp 微信小程序时主包太大和vendor.js过大
  • 深度学习-逻辑回归
  • 深入理解 Redis Cluster:分片、主从与脑裂
  • Gemini CLI初体验
  • MySQL 8.0 OCP 1Z0-908 题目解析(17)
  • SciPy 安装使用教程
  • 数据结构:数组在编译器中的表示(Array Representation by Compiler)
  • NumPy-核心函数transpose()深度解析