【HW系列+技战法】搞定通信加密,力防数据泄露

news/2024/11/17 7:45:40/文章来源:https://www.cnblogs.com/o-O-oO/p/18375720
一、 通信加密流程二、密钥协商算法三、密钥生成四、 密钥交换五、密钥存储

原创 菜鸟学信安

移动互联网主流的网络通信方式面临诸多风险:

算法破解协议破解中间人攻击……

攻击者利用多种攻击方式,不断对移动应用发起攻击。

在移动应用未做有效保护措施的情况下,如果加密 Key、通信协议、核心算法等被破解,会就会导致核心业务逻辑和重要接口暴露,轻则影响正常使用体验,重则发生数据泄漏或财产损失

因此,通信加密是一套保障移动应用通信数据机密性的专业解决方案。


一、 通信加密流程

通信加密是对网络传输的消息体整体进行加密,移动客户端将要发送至服务端的消息整体进行加密,服务端接收到消息后进行解密。

同理,服务端发送至移动客户端的消息也需整体进行加密,移动客户端对接收到消息进行解密。通信加密示例流程如图 1 所示。

【图1】 通信加密示例流程

通过整体加密客户端和服务端通信消息,可防止客户端与服务端的通信内容不被篡改和伪造,也在一定程度上防御了中间人攻击。

二、密钥协商算法

实施通信加密,最核心的是选用哪种类型的加密算法。目前常用的加密算法分类可以分为 对称加密非对称加密

不过,对称加密算法相比于非对称加密算法来说,加解密的效率要高得多。而客户端与服务端通信对效率要求比较高,需要选用对称加密作为加密算法。

为了保证加密算法的安全,使用 ECDH 密钥协商算法生成密钥,防范将密钥预埋到客户端上或通过网络传输时的潜在安全风险。

ECDH 密钥协商算法虽然解决了密钥存储和传输的安全问题,但是该算法本身是无法抵抗中间人攻击的。如果密钥协商过程中被中间人攻击,就会导致生成的密钥不可信。

为了解决该问题,便有了升级版的密钥协商算法 ECDHE。它可在密钥协商时使用非对称 ECDSA 签名算法对服务端的公钥进行签名。客户端进行验签操作可有效防御中间人攻击。

HTTPS 的握手过程就是使用的 ECDHE 算法,客户端与服务端的密钥协商流程如图 2 所示。

【图2】 客户端与服务端的密钥协商流程

ECDHE 是基于椭圆曲线的密钥交换算法,可以利用 OpenSSL 库中封装的椭圆曲线算法实现我们自己的密钥协商。

三、密钥生成

密钥协商中最重要的是生成用于协商的公私钥对,生成公私钥的参考示例代码如下:

int generate_key(unsigned char **prikey, unsigned char **pubkey){
EC_KEY *ec_key;
int ret;
int prikey_len;
int pubkey_len;
ret = init_key(&ec_key);
prikey_len = i2d_ECPrivateKey(ec_key, NULL);
if(0 != prikey_len){
*prikey = calloc(prikey_len + 1, sizeof(char));
int ret = i2d_ECPrivateKey(ec_key, prikey);
if(0 == ret){
EC_KEY_free(ec_key);
return ret;
}
}
pubkey_len = i2o_ECPublicKey(ec_key, NULL);
if(0 != pubkey_len){
*pubkey = calloc(pubkey_len + 1, sizeof(char));
ret = i2o_ECPublicKey(ec_key, pubkey);
if(0 == ret){
EC_KEY_free(ec_key);
return ret;
}
}
}

四、 密钥交换

生成公私钥后就要进行另一个环节——密钥交换。只要我们确保 交换过程中的任何一方公钥不被劫持替换 就能保证不被中间人攻击。

对服务端下发到客户端的公钥使用非对称的 ECDSA 算法进行签名,客户端使用预埋的公钥进行验签,具体校验流程如图 3 所示。

【图3】 客户端校验流程

密钥协商过程中客户端校验签名的示例代码如下:

int ecdsa_verify(unsigned char *server_pubkey, unsigned char *server_pubkey_sign, EC_KEY *ecdsa_pubkey) {
ECDSA_SIG* ecdsa_sign = d2i_ECDSA_SIG(NULL, (const unsigned char **)&server_pubkey_sign, strlen(server_pubkey_sign));
if(ecdsa_sign == NULL){
return -1;
}
ret = ECDSA_do_verify(server_pubkey, strlen((const char *)server_pubkey), ecdsa_sign, ecdsa_pubkey);
if(1 != ret) {
ECDSA_SIG_free(ecdsa_sign);
return -1;
} 
ECDSA_SIG_free(ecdsa_sign);
return 1;
}

密钥协商中最重要的一步就是客户端和服务端各自用自己的私钥及接收的对方公钥计算出通信加密时所用的密钥。核心示例代码如下:

unsigned char* generate_secret_key(unsigned char *server_pubkey, unsigned char *client_prikey){
EC_KEY* ec_prikey = d2i_ECPrivateKey(NULL, (const unsigned char **)&client_prikey, strlen(client_prikey));
if(ec_key_pri == NULL){
return NULL;
}
EC_KEY* ec_pubkey = o2i_ECPublicKey(ec_pubkey, (const unsigned char **)&server_pubkey, strlen(server_pubkey));
if(ec_pubkey == NULL){
return NULL;
}
EC_POINT* ec_point = (EC_POINT *)EC_KEY_get0_public_key(ec_pubkey);
if(ec_point == NULL){
return NULL;
}
unsigned char *secret_key = OPENSSL_malloc(48);
int ret = ECDH_compute_key(secret_key, 48, ec_point, ec_prikey, NULL);
if(ret < 0) {
free(secret_key);
EC_KEY_free(ec_pubkey);
EC_KEY_free(ec_prikey);
return NULL;
}
EC_KEY_free(ec_pubkey);
EC_KEY_free(ec_prikey);
return secret_key;
}

五、密钥存储

使用的密钥协商算法生成密钥后,就涉及另一个问题:生成的密钥要怎么存储

在其生成后对密钥进行简单的移位变形处理存储在应用的数据目录中即可。因通过密钥协商方式生成出密钥各用户是独立的。每个用户都拥有自己唯一的密钥,即使泄漏也不会影响其他用户,相对于所有用户使用同一密钥的安全性要高。

通信加密使用的加密算法为 AES,加密模式为 CBC。选用该模式是其破解难度高,同时符合 SSL/TLS、IPSec 标准。

协商得到的密钥可以通过一系列的字符串变换,得到 AES 加密算法可直接使用的 key 和 iv,此处就不做过多介绍。AES 算法就使用 OpenSSL 库封装即可,示例代码如下:

}

char* aes_decrypt(unsigned char *ciphertext, unsigned char *key, unsigned char *iv) {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
char* plaintext = calloc(strlen(ciphertext) + 1, sizeof(char));
int len;
if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv)) {
return NULL;
}if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, strlen(ciphertext))) {
return NULL;
}if(1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) {
return NULL;
}EVP_CIPHER_CTX_free(ctx);
return plaintext;
}

密钥协商成功后,客户端与服务端通信数据全为密文数据,加密后的通信数据示例如图 4 所示。

【图4】 加密后的通信数据示例

通信数据全部为密文,即使攻击者成功绕过了客户端的防抓包策略,抓取到客户端与服务端的通信数据,也无法对其正常进行分析。

这样,攻击者就无法通过通信数据中的关键字段快速定位到客户端中相应的功能代码,从而在一定程度上提高客户端安全防护水平。

作者简介:

安亚龙,现任好未来集团应用安全负责人,曾担任陌陌的移动安全负责人等。10余年深耕App安全,精通App攻防、业务风控、隐私合规、逆向工程和病毒分析等领域。在与黑灰产的长期对抗过程中,主导开发了具备真机识别、环境分析、通信加密等功能的SDK,现在超亿级客户端上稳定运行,为用户和企业提供坚实的安全保障。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基础组件:表单

实际业务中,在正式向服务器提交数据前,都会对各个输入框数据进行合法性校验,但是对每一个TextField都分别进行校验将会是一件很麻烦的事。还有,如果用户想清除一组TextField的内容,除了一个一个清除有没有什么更好的办法呢?为此,Flutter提供了一个Form 组件,它可以对输…

ctfhub-rce-部分做题记录

命令注入 检查网页显示内容,可以直接看到源代码。大致意思是:检查用户输入的 GET 请求,判断用户是否输入了 ip 信息。如果输入了 ip 信息,则使用用户输入的这个 ip 数据执行一个 shell 命令 "ping -c 4" 。 输入 127.0.0.1;cat 104211044913917.php 没回显,查看…

linux 安装nginx

1.nginx 官网下载nginx 包 (选择稳定版) https://nginx.org/en/download.html 2.上传到linux服务器,解压 tar -zxvf nginx-1.26.2.tar.gz 3.cd到 nginx-1.26.2 , 执行 ./configure 4. 执行 make 5 .执行 make install 7.搜索 nginx 所安装的目录 , whereis …

Android Qcom USB Driver学习(八)

因为要看usb charging的问题,所以需要补充一下battery的相关知识,算是入门吧 BAT SCH(1)VBATT_VSNS_P (2)BAT_THERM (3)I2C_SDA (4)I2C_SCL (5)VBATT_VSNS_M sbl1_hw_pre_ddr_init: (1)pm_device_init (2)pm_driver_init (3) pm_sbl_chg_init (1) pm_device_init没有研究过,…

JuiceFS 在多云架构中加速大模型推理

在大模型的开发与应用中,数据预处理、模型开发、训练和推理构成四个关键环节。本文将重点探讨推理环节。在之前的博客中,社区用户 BentoML 和贝壳的案例提到了使用 JuiceFS 社区版来提高模型加载的效率。本文将结合我们的实际经验,详细介绍企业版在此场景下的优势。 下图是一…

基础组件:ICON

Flutter 中,可以像 Web 开发一样使用 iconfont,iconfont 即“字体图标”,它是将图标做成字体文件,然后通过指定不同的字符而显示不同的图片。在字体文件中,每一个字符都对应一个位码,而每一个位码对应一个显示字形,不同的字体就是指字形不同,即字符对应的字形是不同的。…

Docker部署Nginx,无法访问的解决办法

最近用阿里云的服务器部署了一下Nginx,发现无法通过外网访问,排除掉防火墙和端口映射的问题,最终在阿里云官方发现解决办法,docker0网桥的网段与内网eth0网段冲突,可能导致Nginx无法访问,修改Docker的网段后正常访问. 1.运行以下命令,查看docker0和eth0网段是否冲突 route …

一起单测引起的项目加载失败惨案

一、前言最近在开发一个功能模块时,在功能自测阶段,通过使用单测测试功能的完整性,在测试单测联通性使用到静态方法测试时,发现单测报错,通过查阅解决方案发现需要对Javaassist包进行排包或者升版本处理。通过排包解决掉单测报错,在部署项目时发现频繁报bean注入失败问题…

基础组件:图片

Flutter 中,我们可以通过Image组件来加载并显示图片,Image的数据源可以是asset、文件、内存以及网络。 ImageProvider ImageProvider 是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvider ,如AssetImage是实现了从Asset中…

第6篇 好用免费的开发AI:FittenCode Chart,功能类似chatgpt

你所不知道的免费,又好用的AI,帮助你提高工作效率; 1.打开vs,点击扩展》管理工具,然后搜索Fitten Code,安装下载完成后,重新打开vs2.打开vs,管理工具,就会出现Fitten Code ,选择 open chat window,解决方案管理下就会出现Fittencode Chart,3.输入问题,就可以对话,…

SonarQube 安装及使用

简介 SonarQube是一款用于代码质量管理的开源工具,是静态代码检查工具,采用 B/S 架构它主要用于管理源代码的质量,可以支持众多计算机语言,比如 php,java, C#, go,C/C++, Cobol, JavaScrip, Groovy 等。sonar 可以通过 PMD,CheckStyle,Findbugs 等等代码规则检测工具来…