GCM(Galois/Counter Mode) 认证加密算法实现

news/2025/10/22 22:04:22/文章来源:https://www.cnblogs.com/luminescence/p/19158428

项目概述

根据NIST SP 800-38D标准实现 AES-GCM
GHASH、IV 处理、计数器生成、认证标签

实现

外部引入

使用 PyCryptodome 提供的 AES 块加密
使用Python标准库hmac
使用os.urandom生成随机比特流(经查询是密码学安全的随机数生成器)

结构

- gf_mul()      # 伽罗瓦域运算
- ghash()       # GHASH哈希函数
- _derive_j0()   # 预计数器块生成
- gcm_encrypt()  # 认证加密
- gcm_decrypt()  # 认证解密

比特流工具

#utils.py
BLOCK_SIZE = 16
def xor_bytes(a: bytes, b: bytes) -> bytes:return bytes(x ^ y for x, y in zip(a, b))def pad128(b: bytes) -> bytes:if len(b) % BLOCK_SIZE == 0:return breturn b + b'\x00' * (BLOCK_SIZE - (len(b) % BLOCK_SIZE))def int_from_bytes(b: bytes) -> int:return int.from_bytes(b, 'big')def int_to_bytes(i: int) -> bytes:return i.to_bytes(16, 'big')def inc32(counter_block: bytes) -> bytes:#新值 = (旧值 + 1) mod 2^32c = bytearray(counter_block)val = int.from_bytes(c[-4:], 'big')val = (val + 1) & 0xffffffffc[-4:] = val.to_bytes(4, 'big')return bytes(c)

伽罗瓦域\(GF(2^{128})\)

位移和条件异或实现

R_POLY = 0xE1000000000000000000000000000000
def gf_mul(x: int, y: int) -> int:# GF(2^128) multiply (NIST/IEEE 1619)z = 0v = xfor i in range(128):if (y >> (127 - i)) & 1:z ^= vif v & 1:v = (v >> 1) ^ R_POLYelse:v >>= 1return z & ((1 << 128) - 1)

CHASH模块

分别处理AAD和密文,最后添加长度编码
使用块级迭代处理,可进行流式计算

from utils import *
from gf128 import *
def ghash(H: bytes, A: bytes, C: bytes) -> bytes:# H: 16 bytes (AES_K(0^128))H_int = int_from_bytes(H)X = 0A_padded = pad128(A)for i in range(0, len(A_padded), 16):block = int_from_bytes(A_padded[i:i+16])X = gf_mul(X ^ block, H_int)C_padded = pad128(C)for i in range(0, len(C_padded), 16):block = int_from_bytes(C_padded[i:i+16])X = gf_mul(X ^ block, H_int)len_block = (len(A) * 8).to_bytes(8, 'big') + (len(C) * 8).to_bytes(8, 'big')X = gf_mul(X ^ int_from_bytes(len_block), H_int)return int_to_bytes(X)

计数器

生成预计数器块\(J_0\)

def _derive_j0(H: bytes, iv: bytes) -> bytes:if len(iv) == 12:return iv + b'\x00\x00\x00\x01'else:# J0 = GHASH(H, IV)return ghash(H, b'', iv)

加解密

image
ICB 初始计数器块
CIPH(X) 在密钥 K 下,对数据块 X 应⽤块密码的正向加密函数的输出
GCTR(ICB, X) 对给定的块密码 K 应⽤于⽐特串 X,并使⽤初始计数器块 ICB,GCTR 函数的输出
GHASH(X) 在哈希⼦密钥 H 下,GHASH 函数应⽤于⽐特串 X 的输出
inc(X):新值 = (旧值 + 1) mod 2^32
MSB(X):由 X 的最左边的 s 位组成的位串

加密流程

输入: 密钥(K), 初始化向量(IV), 明文(P), 附加认证数据(AAD)
输出: 密文(C), 认证标签(T)
流程:

  1. 生成哈希子密钥 \(H = AES_K(0^128)\)
  2. 生成预计数器块 \(J0 = derive_J0(H, IV)\)
  3. 计数器模式加密 \(C = GCTR_K(inc32(J0), P)\)
  4. 计算认证标签 \(T = MSB_t(GCTR_K(J0, GHASH_H(A||C)))\)

预计数器块\(J_0\)

根据定义

if len(IV) == 96:IV = [96位IV] || [32位计数器]J0 = IV || 0x00000001
else:J0 = GHASH_H(IV || 0^s || [len(IV)]64)#s = 128 - (len(IV) mod 128)

CTR

明文分块: \(P_1, P_2, P_3, ..., P_n\)
计数器序列: \(CB_1, CB2, CB_3, ..., CB_n\)
密钥流: \(KS_1, KS_2, KS_3, ..., KS_n\)
密文分块: \(C_1, C_2, C_3, ..., C_n\)

其中:
\(CB_1 = inc32(J_0)\)
\(CB_i = inc32(CB_{i-1})\)
\(KS_i = AES_K(CB_i)\)
\(C_i = P_i\) XOR \(K_Si\)

认证标签生成

\(S = GHASH_H(AAD || C || [len(AAD)]_{64} || [len(C)]_{64})\)
\(T = MSB_t(AES_K(J_0), S)\)

解密流程

输入: 密钥(K), 初始化向量(IV), 密文(C), 附加认证数据(AAD), 认证标签(T)
输出: 明文(P) 或 认证失败

流程:

  1. 重新生成哈希子密钥 \(H = AES_K(0^{128})\)
  2. 重新生成预计数器块 \(J0 = derive_J0(H, IV)\)
  3. 重新计算认证标签 \(T' = MSB_t(GCTR_K(J_0, GHASH_H(AAD||C)))\)
  4. 验证标签: 比较 \(T'\)\(T\)
  5. 如果验证通过,\(CTR\)解密: \(P = GCTR_K(inc32(J_0), C)\)

功能实现

"""
NIST SP 800-38D AES-GCM
"""
from Crypto.Cipher import AESimport hmac
import osfrom utils import xor_bytes, pad128, int_from_bytes, int_to_bytes, inc32
from ghash import ghash
MAX_TAG_LEN = 16
def _derive_j0(H: bytes, iv: bytes) -> bytes:if len(iv) == 12:return iv + b'\x00\x00\x00\x01'else:# J0 = GHASH(H, IV)return ghash(H, b'', iv)def _aes_encrypt_block(key: bytes, block: bytes) -> bytes:return AES.new(key, AES.MODE_ECB).encrypt(block)def gcm_encrypt(key: bytes, iv: bytes, plaintext: bytes, aad: bytes = b'', tag_len: int = 16):if tag_len < 4 or tag_len > MAX_TAG_LEN or tag_len % 2 != 0:raise ValueError("tag_len must be even and between 4 and 16")# H = AES_K(0^128)H = _aes_encrypt_block(key, b'\x00' * 16)J0 = _derive_j0(H, iv)counter = inc32(J0)cipher_stream = b''cipher = AES.new(key, AES.MODE_ECB)out = bytearray()for i in range(0, len(plaintext), 16):block = plaintext[i:i+16]s = cipher.encrypt(counter)counter = inc32(counter)out_block = xor_bytes(block, s[:len(block)])out.extend(out_block)C = bytes(out)#tagS = ghash(H, aad, C)E_J0 = _aes_encrypt_block(key, J0)tag_full = xor_bytes(E_J0, S)return C, tag_full[:tag_len]def gcm_decrypt(key: bytes, iv: bytes, ciphertext: bytes, aad: bytes = b'', tag: bytes = b''):if len(tag) == 0:raise ValueError("tag required for decryption")H = _aes_encrypt_block(key, b'\x00' * 16)J0 = _derive_j0(H, iv)counter = inc32(J0)cipher = AES.new(key, AES.MODE_ECB)out = bytearray()for i in range(0, len(ciphertext), 16):block = ciphertext[i:i+16]s = cipher.encrypt(counter)counter = inc32(counter)out_block = xor_bytes(block, s[:len(block)])out.extend(out_block)plaintext = bytes(out)S = ghash(H, aad, ciphertext)E_J0 = _aes_encrypt_block(key, J0)tag_full = xor_bytes(E_J0, S)expected = tag_full[:len(tag)]if not hmac.compare_digest(expected, tag):raise ValueError("authentication failed")return plaintext

调用

if __name__ == "__main__":key = os.urandom(16)iv = os.urandom(12)aad = "1234".encode('utf-8')pt = "明文".encode('utf-8')ct, tg = gcm_encrypt(key, iv, pt, aad, tag_len=16)print("明文:", pt.hex())print("密文:", ct.hex())print("tag:", tg.hex())pt2 = gcm_decrypt(key, iv, ct, aad, tg)print("验证:", pt2 == pt)

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

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

相关文章

10.13-10.19学习做题笔记

10.13 咕咕咕。 upd-10.18 补了一下[Ynoi2016]炸脖龙I。 显然是数据结构题Ynoi能不是吗。 看见这个幂塔,就可以想到拓展欧拉定理。发现\(a^p\equiv a^{\varphi(p)}\),而\(\begin{matrix}\underbrace{\varphi(\varphi(…

20232411 2025-2026-1 《网络与系统攻防技术》实验二实验报告

1.实验内容 掌握后门原理及免杀技术。 问题回答:例举你能想到的一个后门进入到你系统中的可能方式? 回答:同一网络的其他计算机遭到攻击,后门通过网络绕过防火墙进入到我系统中。 例举你知道的后门如何启动起来(wi…

Lampiao 靶场

nmap起手访问80页面访问1898有两个文件一个音频,一个图片 音频说了 tiagodirb目录枚举 dirb http://192.168.1.71:1898 扫描一下敏感信息生成字典 cewl http://192.168.1.71:1898/?q=node/1 -w lam.txt 爆破一下ssh h…

【学习笔记】slope-trick

[BalticOI 2004] Sequence (Day1) \(f_{i,x}\) 表示考虑前 \(i\) 个位置,当前放了 \(x\)。转移式如下: \[f_{i,x} = |a_i - x| + f_{i - 1,x} \]考虑建坐标系,有点 $(x,f_{i,x})。然后它就相当于给当前的函数加上个…

2025.10.22

今天早八上了离散数学,然后上了马原课,中午外卖到的时间很好,不太好吃,下次不点了,然后睡觉睡了一下午,晚上上音乐鉴赏课,然后去科技楼开部长例会。

有一云AI编辑器:2025年微信公众号排版的高效选择

作为个人自媒体运营者,你是否还在为公众号编辑器排版而头疼?写稿、找图、排版、分发……每一个环节都可能耗费大量时间。为了帮助大家找到最适合自己的工具,我亲测了市面上8款主流的微信公众号编辑器,从功能完整度…

20232318 2025-2026-1 《网络与系统攻防技术》实验二实验报告

一、实验核心原理与内容解析 本次实验聚焦 “后门原理与实践”,核心是通过工具配置、定时触发、漏洞利用等手段,实现对目标主机的远程控制与信息窃取,同时理解后门的植入、启动与隐藏机制。实验内容涵盖五类典型场景…

ubuntu 25.10 修改源 - ldx

ubuntu 25.10 修改源# Ubuntu sources have moved to /etc/apt/sources.list.d/ubuntu.sourcessudo gedit /etc/apt/sources.list.d/*.list

pytorch学习笔记(1)

pytorch的模块 Pytorch 官方文档链接: https://pytorch.org/docs/stable torch.nn:神经网络相关api torch.option: 优化算法 torch.utils.data : dataset,dataLoader1.pytorch和tensorflow区别2.tensor(向量)相关操作…

20232404 2025-2026-2 《网络与系统攻防技术》实验二实验报告

一、实验内容 (一)主要内容掌握后门核心原理。 学会如何设置后门,如netcat、socat、MSF meterpreter等工具的使用。 熟悉Linux与Windows系统的后门启动机制。(二)回答问题 (1) 例举你能想到的一个后门进入到你系统…

1020302118兰逸霏的第一次作业

作业一 1.用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020 )的数据,屏幕打印爬取的大学排名信息。排名 学校名称 省市 学校类型 总分1 清华大学 北京 综合 852…

MathType 7下载安装教程及激活教程wps嵌入教程(含下载+安装+汉化激活+安装包)

目录一、写在前面:为啥这篇MathType 7教程一定要看?二、先搞懂:MathType 7为啥是教育/科研必备?三、第一步:MathType 7安装包下载(2025实测无病毒,直链速取)四、核心步骤:MathType 7安装+汉化激活(每步带避坑…

论学习有感——驳学习(读书)无用论

从读书以来学习已经二十年有余,一直依靠着天分和性情在体制化的学习道路上浑浑噩噩的深造。有些许个问题,长期以来也没个自己的答案,顺着接受校方和老师的短期目标,也就一直这么过来了。近年来,随着社会上一些争执…

嵌入式软件分层架构设计 - lucky

一、什么是嵌入式分层架构 “嵌入式分层架构”并不是一个全新的架构类型,而是指在嵌入式系统开发中应用和实现分层架构的设计模式,它继承了通用分层架构的所有核心思想和优点,但根据嵌入式系统的独特约束和需求进行…

DP 基础题乱做

恶补基础 DP. CF1061C 多样性 转移是经典的子序列 DP,考虑前 \(i\) 个数,子序列长度为 \(j\) 的方案数. 转移: \[f_{i,j}=\begin{cases} f_{i-1,j-1}+f_{i-1,j}&j\mid a_i\\ f_{i-1,j}&otherwise. \end{cas…

20232315 2025-2026-1 《网络与系统攻防技术》实验二实验报告

20232315 2025-2026-1 《网络与系统攻防技术》实验二实验报告20232315 2025-2026-1 《网络与系统攻防技术》实验二实验报告 目录一、实验基本信息二、实验内容三、实验要求四、实验过程4.1使用netcat获取主机操作Shell…

2025-10-21 XQQ Round 赛后总结

赛时心路历程开 T1,然后 think 一会就秒掉了。大洋里一遍过。 开 T2,然后 think 一会就秒掉了。大洋里也是一遍过。 15:48 think T3,结果假了。但是注意到在 \(m=0\) 的时候是对的,10 分也是分。 16:25 想不到 T3。…

《中华人民共和国网络安全法》第二十一条这一核心考点

《网络安全法》第二十一条 考点精析 法条原文:国家实行网络安全等级保护制度。网络运营者应当按照网络安全等级保护制度的要求,履行下列安全保护义务,保障网络免受干扰、破坏或者未经授权的访问,防止网络数据泄露或…

二三级区别

等保第二级 vs 第三级核心差异及考点精析 核心关系:第二级是 “指导防护” ,第三级是 “强制管控、增强审计” 。从二级到三级是质的飞跃,而非简单量的增加,这正是考试的重点。核心差异对比与考点解析控制领域 核心…