python版本使用椭圆曲线执行密钥交换

水一篇,

BirdTalk服务端基本快写完了,开始写一个完整的客户端测试;

决定从python入手,因为与其他功能对接时候或者写机器人客服,脚本用的比较多;

直接上代码,原理参考之前的文档。

from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend
import os
import struct
import base64
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMACclass ECDHKeyExchange:def __init__(self):self.private_key = Noneself.public_key = Noneself.shared_key = Noneself.key_print = 0def generate_key_pair(self):"""Generate an ECDH key pair."""self.private_key = ec.generate_private_key(ec.SECP256R1(), default_backend())self.public_key = self.private_key.public_key()print("Key pair generated.")def export_public_key(self, filename):"""Export the generated public key to a file."""if self.public_key is None:raise ValueError("Public key not generated yet.")pem = self.public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo)if filename != "":with open(filename, 'wb') as f:f.write(pem)print(f"Public key saved to {filename}.")return pem.decode('utf-8')def get_public_key(self):if self.public_key is None:raise ValueError("Public key not generated yet.")pem = self.public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo)return pemdef exchange_keys_from_file(self, peer_public_key_filename):"""Exchange keys and generate the shared key using the peer's public key."""if self.private_key is None:raise ValueError("Private key not generated yet.")with open(peer_public_key_filename, 'rb') as f:peer_public_key_pem = f.read()peer_public_key = serialization.load_pem_public_key(peer_public_key_pem, backend=default_backend())self.shared_key = self.private_key.exchange(ec.ECDH(), peer_public_key)print("Shared key generated.")def exchange_keys(self, peer_public_key_pem):"""Exchange keys and generate the shared key using the peer's public key PEM string."""if self.private_key is None:raise ValueError("Private key not generated yet.")peer_public_key = serialization.load_pem_public_key(peer_public_key_pem.encode('utf-8'), backend=default_backend())self.shared_key = self.private_key.exchange(ec.ECDH(), peer_public_key)print("Shared key generated.")def get_shared_key(self):if self.shared_key is None:raise ValueError("Shared key not generated yet.")return self.shared_keydef save_shared_key(self, filename):"""Save the shared key to a file."""if self.shared_key is None:raise ValueError("Shared key not generated yet.")with open(filename, 'wb') as f:f.write(self.shared_key)print(f"Shared key saved to {filename}.")def export_shared_key_base64(self):"""Export the shared key as a base64 encoded string."""if self.shared_key is None:raise ValueError("Shared key not generated yet.")return base64.b64encode(self.shared_key).decode('utf-8')def load_shared_key(self, filename):"""Load the shared key from a file."""with open(filename, 'rb') as f:self.shared_key = f.read()print(f"Shared key loaded from {filename}.")def save_key_print(self, filename):"""Save the shared key to a file."""if self.key_print is None:raise ValueError("Shared key not generated yet.")with open(filename, 'wb') as f:data = str(self.key_print).encode('utf-8')f.write(data)print(f"key print saved to {filename}.")def load_key_print(self, filename):"""Load the shared key from a file."""with open(filename, 'rb') as f:data = f.read()str = data.decode('utf-8')self.key_print = int(str)print(f"key print loaded from {filename}.")return self.key_printdef delete_key_file(self, filename):"""Delete a key file."""if os.path.exists(filename):os.remove(filename)print(f"File {filename} deleted.")else:print(f"File {filename} does not exist.")def get_int64_print(self):if self.shared_key is None:raise ValueError("Shared key not generated yet.")"""Convert a byte array to a 64-bit integer."""# 检查字节数组长度是否足够if len(self.shared_key) < 8:raise ValueError("Insufficient bytes to convert to int64")# 将字节数组转换为 int64self.key_print = struct.unpack('<q',  self.shared_key[:8])[0]  # 使用 little-endian 格式return self.key_printdef encrypt_aes_ctr(self, plaintext):if self.shared_key is None:raise ValueError("Shared key not generated yet.")# 生成随机的初始化向量(IV)iv = os.urandom(16)  # 初始化向量长度为 16 字节# 创建 AES-CTR 算法对象algorithm = algorithms.AES(self.shared_key)mode = modes.CTR(iv)cipher = Cipher(algorithm, mode, backend=default_backend())# 使用加密器加密数据encryptor = cipher.encryptor()encrypted_data = encryptor.update(plaintext) + encryptor.finalize()# 将随机初始化向量和加密后的数据拼接在一起ciphertext = iv + encrypted_datareturn ciphertextdef decrypt_aes_ctr(self, ciphertext):"""Decrypt ciphertext using AES-CTR with the shared key."""if self.shared_key is None:raise ValueError("Shared key not generated yet.")# 从密文中提取初始化向量(IV)iv = ciphertext[:16]  # 初始化向量长度为 16 字节encrypted_data = ciphertext[16:]# 创建 AES-CTR 算法对象algorithm = algorithms.AES(self.shared_key)mode = modes.CTR(iv)cipher = Cipher(algorithm, mode, backend=default_backend())# 使用解密器解密数据decryptor = cipher.decryptor()plaintext = decryptor.update(encrypted_data) + decryptor.finalize()return plaintext
###############################################################
def test_create():# 实例化两个 ECDHKeyExchange 对象,模拟两个参与方alice = ECDHKeyExchange()bob = ECDHKeyExchange()# Alice 生成密钥对并导出公钥alice.generate_key_pair()alice_pub_key = alice.export_public_key("alice_public_key.pem")print(alice_pub_key)# Bob 生成密钥对并导出公钥bob.generate_key_pair()bob_pub_key = bob.export_public_key("bob_public_key.pem")print(bob_pub_key)# Alice 和 Bob 交换公钥并生成共享密钥alice.exchange_keys(bob_pub_key)bob.exchange_keys(alice_pub_key)# 保存共享密钥alice.save_shared_key("alice_shared_key.bin")bob.save_shared_key("bob_shared_key.bin")# 加载共享密钥alice.load_shared_key("alice_shared_key.bin")bob.load_shared_key("bob_shared_key.bin")print(alice.get_int64_print())print(bob.get_int64_print())alice.save_key_print("alice_key_print.txt")keyprint = alice.load_key_print("alice_key_print.txt")print(keyprint)# 删除密钥文件# alice.delete_key_file("alice_public_key.pem")# alice.delete_key_file("alice_shared_key.bin")# bob.delete_key_file("bob_public_key.pem")# bob.delete_key_file("bob_shared_key.bin")def test_load():alice = ECDHKeyExchange()alice.load_shared_key("alice_shared_key.bin")#print(alice.get_shared_key())key_print = alice.load_key_print("alice_key_print.txt")print(key_print)tm = '123456789412'ciper = alice.encrypt_aes_ctr(tm.encode('utf-8'))plain = alice.decrypt_aes_ctr(ciper)print(plain)# 示例使用
if __name__ == "__main__":test_load()

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

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

相关文章

element-ui input输入框和多行文字输入框字体不一样

页面中未作样式修改&#xff0c;但是在项目中使用element-ui input输入框和多行文字输入框字体不一样&#xff0c;如下图所示&#xff1a; 这是因为字体不一致引起的&#xff0c;如果想要为Element UI的输入框设置特定的字体&#xff0c;你可以在你的样式表中添加以下CSS代码…

WWDC 2024 回顾:Apple Intelligence 的发布与解析

一年一度的苹果全球开发者大会&#xff08;WWDC&#xff09;如期而至&#xff0c;2024 年的 WWDC 再次成为科技界的焦点。本次发布会中&#xff0c;苹果正式推出了他们在 AI 领域的全新战略——Apple Intelligence。这一全新概念旨在为用户打造“强大、易用、全面、个性化、注重…

EFDC建模方法及在地表水环境评价、水源地划分、排污口论证

原文链接&#xff1a;EFDC建模方法及在地表水环境评价、水源地划分、排污口论证 近年&#xff0c;随着水环境问题的凸显&#xff0c;地表水水环境状况不仅是公众关注的焦点&#xff0c;也是环保、水务等部门兼管的重点&#xff0c;已成为项目审批、规划制定&#xff0c;甚至领…

FreeBSD jail里面pkg 无法update、search和install

FreeBSD里使用CBSD创建了一个jail&#xff0c; jail里面pkg 命令可以用&#xff0c;但是不管发什么命令&#xff0c;都会提示更新pkg&#xff0c;按Y确认更新&#xff0c; 更新完之后就退出。 再发pkg命令&#xff0c;又是同样提示更新pkg&#xff0c;导致无法pkg search &am…

LVS工作模式详解,NAT全方位剖析

请求到达&#xff1a; 当用户请求到达Director Server&#xff08;负载均衡服务器&#xff09;时&#xff0c;数据包会先到达内核空间的PREROUTING链。此时&#xff0c;数据包的源IP为CIP&#xff08;Client IP&#xff09;&#xff0c;目标IP为VIP&#xff08;Virtual IP&…

LeeCode 1987 DP / Trie

题意 传送门 LeeCode 1987 不同的好子序列数目 题解 DP 令以 b [ i ] b[i] b[i]为首元素的子序列集合为 S i \mathcal{S}_{i} Si​。若 b [ i ] b [ j ] b[i]b[j] b[i]b[j]&#xff0c;且 i < j i<j i<j&#xff0c;则 S j ⊆ S i \mathcal{S}_{j}\subseteq\mat…

论文学习记录

目录标题 pcl下载pcl安装学习地址问题[vtkOpenGLPolyDataMapper::SetVertexShaderCode was deprecated for VTK 9.0 and will be removed in a future version. Use vtkOpenGLShaderProperty::SetVertexShaderCode instead.](https://blog.csdn.net/qq_39784672/article/detail…

Cesium4Unreal - # 011 加载显示geojson

文章目录 加载显示geojson1 思路2 步骤2.1 添加依赖模块2.3 创建Actor2.3.1 <font color=#4ea1db>MyGeoJsonLoaderActor.h2.3.2 <font color=#4ea1db>MyGeoJsonLoaderActor.cpp2.3 蓝图代码3 资源加载显示geojson 1 思路 在Unreal Engine中加载显示geojson和加载…

服务和协议的关系?

文章目录 前言一、协议协议有三个要素:二、服务三、服务与协议的区别:前言 前文介绍了很多UDS服务和ISO 14229协议的文章,有读者会有疑问服务和协议的关系到底是什么呢? ISO14229系列规范介绍 UDS服务列表 本文小编将展开介绍。 一、协议 为进行网络中的数据交换而建立的…

MySQL学习笔记-进阶篇-SQL优化

SQL优化 插入数据 insert优化 1&#xff09;批量插入 insert into tb_user values(1,Tom),(2,Cat),(3,Jerry); 2&#xff09;手动提交事务 mysql 默认是自动提交事务&#xff0c;这样会导致频繁的开启和提交事务&#xff0c;影响性能 start transaction insert into tb_us…

Mongodb学习

mongodb应用场景&#xff1a; mongodb特点&#xff1a;高扩展性&#xff08;分片水平扩展&#xff09;、高可用&#xff0c;对事务性要求不高、应用需要大量的地理位置查询、文本查询 mongodb部署架构&#xff1a;副本集、分片集群 MongoDB 是一个开源、高性能、无模式的文档…

【最新鸿蒙应用开发】——警惕这些坑!不同API版本带来的差异

关于HarmonyOS的API从8到API12&#xff0c;存在不少版本的差异&#xff0c;比如一些ArkTS语法上的差异&#xff1b;一些组件在API9之前不支持的功能&#xff0c;本人在项目开发过程中也是踩了不少坑&#xff0c;现在给大家分享一下心得。 1.语法差异 首先是ArkTS语法上的差异…

实拆一个风扇

fr:徐海涛(hunkxu)

Qwen2——阿里巴巴最新的多语言模型挑战 Llama 3 等 SOTA

引言 经过几个月的期待&#xff0c; 阿里巴巴 Qwen 团队终于发布了 Qwen2 – 他们强大的语言模型系列的下一代发展。 Qwen2 代表了一次重大飞跃&#xff0c;拥有尖端的进步&#xff0c;有可能将其定位为 Meta 著名的最佳替代品 骆驼3 模型。在本次技术深入探讨中&#xff0c;我…

神经网络学习2

张量&#xff08;Tensor&#xff09;是深度学习和科学计算中的基本数据结构&#xff0c;用于表示多维数组。张量可以看作是一个更广义的概念&#xff0c;涵盖了标量、向量、矩阵以及更高维度的数据结构。具体来说&#xff0c;张量的维度可以是以下几种形式&#xff1a; 标量&am…

Spring-boot-logback-spring.xml文件Appender标签下的属性

在logback-spring.xml文件中&#xff0c;标签是通过set方法设置的值&#xff0c;例如下面的代码&#xff0c;属性hrName的值为TYC&#xff0c;当服务启动的时候&#xff0c;控制台会一直打印TYC三个字母 首先&#xff0c;我们自定义一个Appender&#xff0c;然后里面有一个属性…

【打鼹鼠game】

好的&#xff0c;我将为您编写一个简单的打鼹鼠游戏的代码。这个游戏会模拟一个简单的打鼹鼠游戏&#xff0c;玩家需要点击随机出现的鼹鼠。我们将使用Python编程语言和Pygame库来创建这个游戏。代码将包括以下部分&#xff1a; 初始化Pygame和游戏窗口。创建鼹鼠的类和属性。…

python面试题4: Python是按引用调用还是按值调用(难度--简单)

文章目录 题目回答 题目 Python是按引用调用还是按值调用&#xff1f; 回答 这题主要是考试对于python数据类型的认知。 1.首先对于不可变对象&#xff0c;字符&#xff0c;元组&#xff0c;数字往往是按引用进行调用,示例如下&#xff1a; def add(s):ssodd so add(s) …

LogicFlow 学习笔记——2. LogicFlow 基础 实例

LogicFlow 实例 创建实例 每一个流程设计界面&#xff0c;就是一个 LogicFlow 的实例。 <template><div id"container"></div><!-- 用于显示 LogicFlow 图表的容器 --> </template> <script>// 创建 LogicFlow 实例const lf …

Day03 链表概念与单向不循环链表的实现

目录 1、顺序表的优缺点 2、链式存储的线性表 3、单向不循环链表实现 1、顺序表的优缺点 顺序表的优点是: 由于顺序表数据元素的内存地址都是连续的,所以可以实现随机访问,而且不需要多余的信息来描述相关的数据,所以存储密度高。 顺序表的缺点是: 顺序表的数据在进行…