白盒 SDK 加密 —— Go 语言中直调 C 动态库实现

news2024/11/25 21:27:55

文章目录

    • 1.背景
    • 2.实现方式
      • 2.1.C 库 .so 文件生成
      • 2.2.C 库 .h 文件
      • 2.3.Goland 调用实现
        • 2.3.1 整体
        • 2.3.2 注释块部分
        • 2.3.3 逻辑实现部分
    • 3.小结

1.背景

在重构的历史项目中,有一点是语言转换:从 PHP 转至 Goland ,在压缩资源的同时,享受语言实现级别进步带来的性能红利。
在这里插入图片描述

在功能点覆盖上存在白盒 SDK 加密场景,如 流量校验、对端数据传输…等。

  • 原 PHP 实现中是通过扩展方式进行调用:将白盒 SDK 以 .so 文件的形式补充至 php-config --extension-dir,并添加 extension=XXX.sophp.ini 配置文件。

  • 现 Goland 实现中,使用直调 C 动态库的方式实现【无成熟的 go-sdk, 存在额外的实现成本】。


2.实现方式

在 Goland 中,也提供了像 Java、Python、C++ …中调用 动态库的原生能力,只是在调度过程实现上存在略微不同。

之前架构设计中提到的 千万级入口服务 —— 框架设计(一:组件模式) 组件也是通过 动态库的方式实现。

  1. Goland 原生动态库构建的时候只要通过 go build -buildmode=plugin -o XX.so 进行 .go 文件到 .so 动态库的状态转换。

  2. C 则需要使用 gcc\g++ gcc/g++ 百科介绍来进行源码文件到 .so 动态库的状态转换。
    在这里插入图片描述


2.1.C 库 .so 文件生成

将目标 C库 的 .a 文件拆解,重新编译 .so 文件。

ar -x XXprotect_sec.a 
g++ -shared *.o -o XXprotect_sec.so

有了 .so 文件之后,还需要有 C 库 的接口文件 .h 文件。.h 文件用来在 Goland 调度过程中进行二次封装调用。


2.2.C 库 .h 文件

在 Goland 中调用 C 库接口,允许存在中间处理环节,即二次封装。而进行的前提是基于 .h 文件提供的 C 库接口。

#pragma once
#ifdef __cplusplus
extern "C" {
#endif

/**
* \brief XX get version function
* \return version string.
*/
typedef const void * (*FN10)(void);
#define XX_VERSION() \
((FN10)gsecfv3[1])()

......

/**
* \brief XX initialize function
* \return return context if successful
*/
typedef void * (*FN11)(const char *, char *, char *);
#define XX_INIT(akey, encrypt_key, decrypt_key) \
((FN11)gsecfv3[2])(akey, encrypt_key, decrypt_key)

2.3.Goland 调用实现

此处聚焦 直调 C 库调用过程,白盒 SDK 加密逻辑及原理 可留言沟通 或 关注后续博文 。

在这里插入图片描述

2.3.1 整体

整体看:在 package 下方的依赖包引入中,import "C" 必须单起一行,且二次封装的接口务必以注释的方式在其上方编排;下方 Goland 函数中使用时,以 C 库开头直接调用即可。

需要注意的是:

  1. 注释中的 #include .h 行,不仅仅是 C 库的接口,也可以是 C 中的原生包。比如:#include<stdio.h>
  2. Goland 中调用使用到的 C 库,务必在注释行引入。如果不引入,项目编译时就会报出 could not determine kind of name for C.XX...错误。
  3. C 动态库编译的版本与 Goland 执行版本中的需兼容。否则会报出 :c running gcc failed: exit status 1 //opt/compiler/gcc-8.2/lib64/libstdc++.so.6: undefined reference to... 错误。
package encrypt

/*
   #cgo CFLAGS: -I.
   #cgo LDFLAGS: -L. -lXXprotect_sec -Wl,-rpath,./
   #include "XXlib_v3.h" // C 库接口文件

   const char *XX_version() {
       return XX_VERSION();
   }

   void *XX_init(const char *akey, char *encrypt_key, char *decrypt_key) {
       return  XX_INIT(akey, encrypt_key, decrypt_key);
   }
	......
   int XX_destory(void *context) {
       return XX_DESTORY(context);
   }

*/
import "C" // import “C” 必须单起一行,并且紧跟在注释行之后

import (
	"context"
	"reflect"
	......
	"unsafe"
)

func XXEncrypt(ctx context.Context, tp string, data string, ver string, iv string) (string, error) {
	iv = iv + "\x00"
	// 打印白盒SDK版本号
	log.Println(C.GoString(C.bdswb_version()))
	......
	return "", nil
}
2.3.2 注释块部分

接下来,看到注释块中,前两行标记了当前 C 库调用动态库 的位置及特征。使用的是 #cgo cgo 详细介绍 方式。

在注释主体中,是对 C 库接口的二次封装,类似 Hook 方式,给予开发者适当的操作空间。

需要注意的是:

  1. 动态库在项目编译时,需要在 环境变量中引入。可覆盖、追加变量 LD_LIBRARY_PATH,否则无法从位置路径中获取到 .so 动态库。比如:export LD_LIBRARY_PATH=/root/codes/XXXso/path:$LD_LIBRARY_PATH
  2. 最好是在 ~/.bash_profile 中变更,这样对每次终端都生效,不要忘记重启 source ~/.bash_profile
2.3.3 逻辑实现部分

Goland 实现部分,特地写了 iv = iv + "\x00" 代码行。这里是将 Goland 中的字符串转为 C 中的格式。这种写法是未引用 C 库原生函数的情况下进行。另一种方式是使用原生库,不过需要在 注释部分追加对应的包。

需要注意的是:

  1. 在 Goland 调用的参数部分,格式需要转换为 C 中的样式,会比较常用到 (*C.uchar)(unsafe.Pointer) … 等业务开发中少用到的转换方式。

3.小结

整体下来看,Goland 中直调 C 库 操作是很流程化的。在此前提下,也给予了调用规则适当的灵活性。

在这里插入图片描述

但综上,是不建议初学者使用的。尤其是不充分了解、熟悉 Goland、C 语言特性 及 项目主体逻辑、C 库逻辑 的场景;

  1. 在调用过程调试中,数据格式转换、库函数使用…等语言差异导致的问题容易频发。
  2. C 动态库 对于 Goland 调用主体来讲,完全是黑盒、透明的,出现问题不易排查且是维护盲区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1049510.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringMVC+统一表现层返回值+异常处理器

一、统一表现层返回值 根据我们不同的处理方法&#xff0c;返回的数据格式都会不同&#xff0c;例如添加只返回true|false&#xff0c;删除同理&#xff0c;而查询却返回数据。 Result类 为此我们封装一个result类来用于表现层的返回。 public class Result {//描述统一格式…

B. Sets and Union

题目&#xff1a; 样例&#xff1a; 输入 4 3 3 1 2 3 2 4 5 2 3 4 4 4 1 2 3 4 3 2 5 6 3 3 5 6 3 4 5 6 5 1 1 3 3 6 10 1 9 2 1 3 3 5 8 9 1 2 4 28输出 4 5 6 0 思路&#xff1a; 这里题目的意思是&#xff0c;要求合并尽可能多的集合&#xff0c;使它的集合大小最大&…

flink中不同序列化器性能对比

背景 flink有多种序列化方式&#xff0c;包括flink内置的以及fallback到kryo的&#xff0c;那么他们之间有多大的性能差距呢&#xff0c;本文就从https://flink.apache.org/2020/04/15/flink-serialization-tuning-vol.-1-choosing-your-serializer-if-you-can/这篇文章里摘录…

分类预测 | MATLAB实现PSO-CNN粒子群算法优化卷积神经网络数据分类预测

分类预测 | MATLAB实现PSO-CNN粒子群算法优化卷积神经网络数据分类预测 目录 分类预测 | MATLAB实现PSO-CNN粒子群算法优化卷积神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO-CNN多特征分类预测&#xff0c;多特征输入模型&#xf…

【计算机视觉|人脸建模】PanoHead:360度几何感知的3D全头合成

本系列博文为深度学习/计算机视觉论文笔记&#xff0c;转载请注明出处 标题&#xff1a;PanoHead: Geometry-Aware 3D Full-Head Synthesis in 360 ∘ ^{\circ} ∘ 链接&#xff1a;[2303.13071] PanoHead: Geometry-Aware 3D Full-Head Synthesis in 360 ∘ ^{\circ} ∘ (arx…

JavaScript 函数柯里化

&#x1f3b6;什么是柯里化 柯里化&#xff08;Currying&#xff09;是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数&#xff0c;并且返回接受余下的参数且返回结果的新函数的技术。 &#x1f3a1;简单的函数柯里化的实现 // ------------- 原函数…

Mac电脑强大的字体管理 RightFont for Mac

RightFont for Mac软件特色 速度有多快&#xff1f;RightFont可以在0.9秒以内加载30,000个字体&#xff01; 自动从Google字体/ Adobe Typekit集合&#xff08;通过Adobe Creative Cloud客户端&#xff09;同步字体。 轻松切换组视图以折叠/展开字体系列。 通过简单的拖放导入…

怎么保护苹果手机移动应用程序ipa中文件安全?

目录 前言 1. 对敏感文件进行文件名称混淆 2. 更改文件的MD5值 3. 增加不可见水印处理 3. 对html&#xff0c;js&#xff0c;css等资源进行压缩 5. 删除可执行文件中的调试信息 前言 ios应用程序存储一些图片&#xff0c;资源&#xff0c;配置信息&#xff0c;甚至敏感数…

raw图片处理软件:DxO PhotoLab 6 mac中文版支持相机格式

DxO PhotoLab 6 mac是一款专业的RAW图片处理软件&#xff0c;适用于Mac操作系统。它具有先进的图像处理技术和直观易用的界面&#xff0c;可帮助用户轻松地将RAW格式的照片转换为高质量的JPEG或TIFF图像。 DxO PhotoLab 6支持多种相机品牌的RAW格式&#xff0c;包括佳能、尼康、…

多叉树+图实现简单业务流程

文章目录 场景整体架构流程业务界面技术细节小结 场景 这次遇到一个需求,大致就是任务组织成方案,方案组织成预案,预案可裁剪调整.预案关联事件等级配置,告警触发预案产生事件.然后任务执行是有先后的,也就是有流程概念. 整体架构流程 方案管理、预案管理构成任务流程的基础条…

Redis学习第九天

今天是Jedis&#xff01;作者的Redis在游戏本上&#xff0c;但是Java的IDEA总是下载不了&#xff0c;所以只能作为概念听一听了&#xff0c;目前无法做到实操。 Jedis概念 Jedis实操 首先要保证redis的服务器开启&#xff0c;然后引入jedis依赖&#xff0c;最后通过服务器的I…

【学习笔记】深度学习分布式系统

深度学习分布式系统 前言1. 数据并行&#xff1a;参数服务器2. 流水线并行&#xff1a;GPipe3. 张量并行&#xff1a;Megatron LM4. 切片并行&#xff1a;ZeRO5. 异步分布式&#xff1a;PATHWAYS总结参考链接 前言 最近跟着李沐老师的视频学习了深度学习分布式系统的发展。这里…

作用域 CSS 回来了

几年前&#xff0c;消失的作用域 CSS&#xff0c;如今它回来了&#xff0c;而且比以前的版本要好得多。 更好的是&#xff0c;W3C规范基本稳定&#xff0c;现在Chrome中已经有一个工作原型。我们只需要社区稍微关注一下&#xff0c;引诱其他浏览器构建它们的实现&#xff0c;并…

嵌入式数据库sqlite3基本命令操作基础(05)

前言 数据在实际工作中应用非常广泛&#xff0c;数据库的产品也比较多&#xff0c;oracle、DB2、SQL2000、mySQL&#xff1b;基于嵌入式linux的数据库主要有SQLite, Firebird, Berkeley DB, eXtremeDB。 本文主要讲解数据库SQLite&#xff0c;通过这个开源的小型的嵌入式数据…

MySQL5.7高级函数:JSON_ARRAYAGG和JSON_OBJECT的使用

前置准备 DROP TABLE IF EXISTS t_user; CREATE TABLE t_user (id bigint(20) NOT NULL,name varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci …

Unity - 实践: Metallic流程贴图 转 Specular流程贴图

文章目录 目的Metallic Flow - SP - 输出输出的 MRA (MGA) 贴图 Metallic->Specular (根据教程一步一步实践)1. Base color Metallic -> Diffuse2. Base color Metallic -> Specular3. Roughness -> Glossiness输出贴图&#xff0c;在 unity 中展示&#xff1a;M…

内网测速工具-LibreSpeed

github链接&#xff1a; https://github.com/librespeed/speedtest-android

如何系列 如何使用OpenCV进行图像操作

文章目录 简介集成代码示例加载和显示图像编辑和保存图像边缘检测图片属性图像旋转图像缩放图像拼接颜色空间转换图像模糊平滑化腐蚀和膨胀直方图均衡化图像分割模板匹配图像特征提取图像拟合图像标注轮廓检测背景减除图像混合颜色分割图像旋转裁剪在图像上写文字检测和裁剪人脸…

大模型Tuning分类

类型总结 微调&#xff08;Fine-tunning&#xff09; 语言模型的参数需要一起参与梯度更新 轻量微调&#xff08;lightweight fine-tunning&#xff09; 冻结了大部分预训练参数&#xff0c;仅添加任务层&#xff0c;语言模型层参数不变 适配器微调 &#xff08;Adapter-t…

Java项目-文件搜索工具

目录 项目背景 项目效果 SQLite的下载安装 使用JDBC操作SQLite 第三方库pinyin4j pinyin4j的具体使用 封装pinyin4j 数据库的设计 创建实体类 实现DBUtil 封装FileDao 设计scan方法 多线程扫描 周期性扫描 控制台版本的客户端 图形化界面 设计图形化界面 项目…