2024网鼎杯青龙组wp:Crypto1

题目

附件内容如下

from Crypto.Util.number import *
from secret import flag
from Cryptodome.PublicKey import RSAp = getPrime(512)
q = getPrime(512)
n = p * q
d = getPrime(299)
e = inverse(d,(p-1)*(q-1))
m = bytes_to_long(flag)
c = pow(m,e,n)
hint1 = p >> (512-70)
hint2 = q >> (512-70)print(f"n = {n}")
print(f"e = {e}")
print(f"c = {c}")
print(f"hint1 = {hint1}")
print(f"hint2 = {hint2}")n = 65318835751656706270462803918372182811096669561139853833192009681234356986381524661604904085035483519298788284835759796179173585004238691057332447589167439506386243352011548441011828732868691543989256629925692290088144403935880664585931943707422938295860559274669263630591393175387389387981929391774213395003
e = 40738963799387627677248718814260921636491770341278750841486515130562842134876396915106681433734276005332410415984785584884091334455816402584507178231273998519376915363193650533215442952274343814099450187672503465016280527554101223321817109358581483535333734940968961773897326303002987203525415266163296607215
c = 28858301095788879003830568949705095027466057921892765321643055383309726369907606901866332954652632036004551285284813812187678314978562231120323470819722044516158810710408496414616381570397632550468546302235826400628265458069027801013266037490695637948933487646553291637002155559023268928639502489285322508063
hint1 = 624859718207126357681
hint2 = 810475217500119132950

除了已知条件,还需要知道p和q,再利用p和q计算d

已知p和q的高比特(70位),可以利用穷举或者boneh-durfee方法进行计算

Boneh-Durfee

Boneh-Durfee 是一种针对 RSA 公钥加密的攻击方法,特别适用于低指数加密的情况。它由密码学家 Dan Boneh 和 Ramarathnam V. Durfee 在 1999 年提出。这种攻击方法主要针对 RSA 加密中的一个特定场景:即密钥的私钥指数 ddd 过小的时候。

攻击背景

在 RSA 加密算法中,公钥由模数 NNN 和公钥指数 eee 构成,而私钥由模数 NNN 和私钥指数 ddd 构成。公钥和私钥满足以下关系:

e⋅d≡1 (mod ϕ(N))e \cdot d \equiv 1 \ (\text{mod} \ \phi(N))e⋅d≡1 (mod ϕ(N))

其中 ϕ(N)\phi(N)ϕ(N) 是 NNN 的欧拉函数。如果私钥指数 ddd 非常小,那么可以通过数学上的技巧推导出 ddd 的可能值。尤其当 d<N0.292d < N^{0.292}d<N0.292 时,Boneh 和 Durfee 攻击可以用 lattice(格)的方法有效地恢复 ddd。

攻击原理

Boneh-Durfee 攻击利用的是 lattice reduction(格约减)算法,具体来说,利用了 LLL 算法(Lenstra-Lenstra-Lovász)来进行维度缩减。这种方法背后的思想是,将 RSA 的密钥方程转换为求解一个二维格上的近似最小解的问题。这些数学操作可以有效缩小搜索范围,从而恢复私钥 ddd。

攻击条件和适用范围
  • Boneh-Durfee 攻击适用于当私钥指数 ddd 非常小时的情况,一般要求 d<N0.292d < N^{0.292}d<N0.292。
  • 这意味着在某些特定的 RSA 实现中,为了加快加密速度,私钥 ddd 可能被选择得很小,此时可能会受到此类攻击的威胁。
攻击的限制

Boneh-Durfee 攻击虽然强大,但在实际应用中有一定的局限性。首先,它依赖于私钥 ddd 足够小,若 ddd 大于 N0.292N^{0.292}N0.292,则该攻击将变得不可行。此外,这种攻击也依赖于 lattice-based 技术的成功运用,并且计算量较大,需要对 LLL 算法有较深入的理解和高效的实现。

防御方法

为了避免 Boneh-Durfee 攻击,主要建议:

  • 使用较大的私钥指数 ddd:尽量避免选择太小的 ddd 值。
  • 增加密钥的位数:一般来说,增加 NNN 的位数(如 2048 位或更高)可以大大增强 RSA 的安全性,使得攻击变得不可行。

总之,Boneh-Durfee 攻击是一种非常经典的针对低私钥指数的 RSA 的攻击方法,通过格约减技术可以有效恢复小 ddd 情况下的 RSA 私钥。这类攻击提醒了我们在选择密钥时应当小心,并遵循推荐的密钥大小和指数选择。

payload

import time
time.clock = time.time# 调试模式标志
debug = True# 严格模式标志
strict = False# 仅考虑有用的向量
helpful_only = True
dimension_min = 7  # 如果晶格达到该尺寸,则停止移除无用向量# 显示有用向量的统计数据
def helpful_vectors(BB, modulus):nothelpful = 0  # 记录无用向量的数量for ii in range(BB.dimensions()[0]):if BB[ii, ii] >= modulus:nothelpful += 1  # 如果当前向量大于等于模数,则认为是无用向量print(nothelpful, "/", BB.dimensions()[0], " vectors are not helpful")return nothelpful  # 返回无用向量的数量# 显示带有 0 和 X 的矩阵
def matrix_overview(BB, bound):for ii in range(BB.dimensions()[0]):a = ('%02d ' % ii)  # 输出当前向量的索引for jj in range(BB.dimensions()[1]):a += '0' if BB[ii,jj] == 0 else 'X'  # 用 0 或 X 表示向量中元素if BB.dimensions()[0] < 60: a += ' 'if BB[ii, ii] >= bound:a += '~'  # 用 ~ 表示大于界限的向量# print(a)  # 可选,调试输出# 尝试删除无用的向量
def remove_unhelpful(BB, monomials, bound, current):# 从当前 = n-1(最后一个向量)开始if current == -1 or BB.dimensions()[0] <= dimension_min:return BB  # 如果没有向量或达到最小维度,返回原矩阵# 从后面检查for ii in range(current, -1, -1):if BB[ii, ii] >= bound:  # 如果当前向量被认为是无用的affected_vectors = 0affected_vector_index = 0# 检查是否影响其他向量for jj in range(ii + 1, BB.dimensions()[0]):if BB[jj, ii] != 0:affected_vectors += 1  # 受影响的向量数量affected_vector_index = jj  # 记录受影响的向量索引# 等级:0if affected_vectors == 0:  # 如果没有向量受到影响# print("* removing unhelpful vector", ii)BB = BB.delete_columns([ii])  # 删除当前向量BB = BB.delete_rows([ii])monomials.pop(ii)  # 从单项式列表中删除BB = remove_unhelpful(BB, monomials, bound, ii - 1)  # 递归调用return BB# 等级:1elif affected_vectors == 1:affected_deeper = Truefor kk in range(affected_vector_index + 1, BB.dimensions()[0]):if BB[kk, affected_vector_index] != 0:affected_deeper = False  # 如果有其他向量受到影响,则不删除if affected_deeper and abs(bound - BB[affected_vector_index, affected_vector_index]) < abs(bound - BB[ii, ii]):# 如果没有其他向量受到影响且当前向量更无用# print("* removing unhelpful vectors", ii, "and", affected_vector_index)BB = BB.delete_columns([affected_vector_index, ii])BB = BB.delete_rows([affected_vector_index, ii])monomials.pop(affected_vector_index)monomials.pop(ii)BB = remove_unhelpful(BB, monomials, bound, ii - 1)  # 递归调用return BB# 如果没有向量被删除,返回原矩阵return BBdef boneh_durfee(pol, modulus, mm, tt, XX, YY):PR.<u, x, y> = PolynomialRing(ZZ)  # 创建多项式环Q = PR.quotient(x * y + 1 - u)     # 设定 u = xy + 1polZ = Q(pol).lift()  # 提升多项式UU = XX * YY + 1  # 计算 UU# x-移位gg = []for kk in range(mm + 1):for ii in range(mm - kk + 1):xshift = x^ii * modulus^(mm - kk) * polZ(u, x, y)^kk  # 生成 x 的移位gg.append(xshift)gg.sort()  # 排序# 单项式 x 移位列表monomials = []for polynomial in gg:for monomial in polynomial.monomials():  # 获取单项式if monomial not in monomials:  # 如果单项式不在列表中monomials.append(monomial)monomials.sort()  # 排序# y-移位for jj in range(1, tt + 1):for kk in range(floor(mm / tt) * jj, mm + 1):yshift = y^jj * polZ(u, x, y)^kk * modulus^(mm - kk)  # 生成 y 的移位yshift = Q(yshift).lift()  # 提升gg.append(yshift)  # 添加到移位列表# 单项式 y 移位列表for jj in range(1, tt + 1):for kk in range(floor(mm / tt) * jj, mm + 1):monomials.append(u^kk * y^jj)  # 添加到单项式列表# 构造格 Bnn = len(monomials)  # 单项式数量BB = Matrix(ZZ, nn)  # 初始化格矩阵for ii in range(nn):BB[ii, 0] = gg[ii](0, 0, 0)  # 设置第一列for jj in range(1, ii + 1):if monomials[jj] in gg[ii].monomials():BB[ii, jj] = gg[ii].monomial_coefficient(monomials[jj]) * monomials[jj](UU, XX, YY)# 如果只考虑有用的向量,尝试移除无用向量if helpful_only:BB = remove_unhelpful(BB, monomials, modulus^mm, nn - 1)nn = BB.dimensions()[0]  # 更新维度if nn == 0:print("failure")  # 如果没有向量,返回失败return 0, 0# 检查向量是否有帮助if debug:helpful_vectors(BB, modulus^mm)# 检查行列式是否正确界定det = BB.det()bound = modulus^(mm * nn)if det >= bound:print("We do not have det < bound. Solutions might not be found.")print("Try with higher m and t.")if debug:diff = (log(det) - log(bound)) / log(2)print("size det(L) - size e^(m*n) = ", floor(diff))if strict:return -1, -1  # 如果严格模式并且行列式不符合约束,返回失败else:print("det(L) < e^(m*n) (good! If a solution exists < N^delta, it will be found)")# 显示格基if debug:matrix_overview(BB, modulus^mm)# LLL算法优化格基if debug:print("optimizing basis of the lattice via LLL, this can take a long time")BB = BB.LLL()  # 使用LLL算法进行优化if debug:print("LLL is done!")# 查找线性无关的向量if debug:print("在格中寻找线性无关向量")found_polynomials = Falsefor pol1_idx in range(nn - 1):for pol2_idx in range(pol1_idx + 1, nn):# 构造两个多项式PR.<w, z> = PolynomialRing(ZZ)pol1 = pol2 = 0for jj in range(nn):pol1 += monomials[jj](w * z + 1, w, z) * BB[pol1_idx, jj] / monomials[jj](UU, XX, YY)pol2 += monomials[jj](w * z + 1, w, z) * BB[pol2_idx, jj] / monomials[jj](UU, XX, YY)# 结果PR.<q> = PolynomialRing(ZZ)rr = pol1.resultant(pol2)  # 计算结果if rr.is_zero() or rr.monomials() == [1]:continue  # 如果结果为零或为常数,继续else:print("found them, using vectors", pol1_idx, "and", pol2_idx)found_polynomials = Truebreak  # 找到后跳出循环if found_polynomials:break  # 如果找到多项式,跳出外循环if not found_polynomials:print("no independant vectors could be found. This should very rarely happen...")return 0, 0  # 如果没有找到独立向量,返回失败rr = rr(q, q)  # 使用 q 替代变量# 获取解soly = rr.roots()  # 计算根if len(soly) == 0:print("Your prediction (delta) is too small")return 0, 0  # 如果没有根,返回失败soly = soly[0][0]  # 选择第一个根ss = pol1(q, soly)  # 计算另一个多项式solx = ss.roots()[0][0]  # 获取解 xreturn solx, soly  # 返回解def example():############################################# 随机生成数据##########################################start = time.clock()  # 记录开始时间size = 512  # 设置大小length_N = 2 * sizess = 0  # 解决方案计数s = 70  # 指定比特数M = 1  # 实验次数delta = 299 / 1024  # 设置 delta 值# 进行实验for i in range(M):N = 65318835751656706270462803918372182811096669561139853833192009681234356986381524661604904085035483519298788284835759796179173585004238691057332447589167439506386243352011548441011828732868691543989256629925692290088144403935880664585931943707422938295860559274669263630591393175387389387981929391774213395003e = 40738963799387627677248718814260921636491770341278750841486515130562842134876396915106681433734276005332410415984785584884091334455816402584507178231273998519376915363193650533215442952274343814099450187672503465016280527554101223321817109358581483535333734940968961773897326303002987203525415266163296607215c = 28858301095788879003830568949705095027466057921892765321643055383309726369907606901866332954652632036004551285284813812187678314978562231120323470819722044516158810710408496414616381570397632550468546302235826400628265458069027801013266037490695637948933487646553291637002155559023268928639502489285322508063hint1 = 624859718207126357681  # p 的高位hint2 = 810475217500119132950  # q 的高位# 解密指数 d 的最大值m = 7  # 设置格大小t = round(((1 - 2 * delta) * m))  # 根据 Herrmann 和 May 的优化计算X = floor(N**delta)  # 计算 XY = floor(N**(1/2) / 2**s)  # 计算 Y# 循环范围内进行测试for l in range(int(hint1), int(hint1) + 1):print('\n\n\n l=', l)pM = lp0 = pM * 2**(size - s) + 2**(size - s) - 1  # 计算 p 的值q0 = N / p0  # 计算 q 的值qM = int(q0 / 2**(size - s))  # 计算 q 的高位A = N + 1 - pM * 2**(size - s) - qM * 2**(size - s)  # 计算 AP.<x, y> = PolynomialRing(ZZ)  # 创建多项式环pol = 1 + x * (A + y)  # 构建多项式方程# 运行 Boneh-Durfee 算法if debug:start_time = time.time()  # 记录开始时间solx, soly = boneh_durfee(pol, e, m, t, X, Y)  # 调用算法if solx > 0:d_sol = int(pol(solx, soly) / e)  # 计算解 dss += 1  # 增加解决方案计数print("=== solution found ===")print("p的高比特为:", l)print("q的高比特为:", qM)print("d =", d_sol)  # 输出解if debug:print("=== %s seconds ===" % (time.time() - start_time))print("ss =", ss)  # 输出解决方案计数end = time.clock()  # 记录结束时间print('Running time: %s Seconds' % (end - start))  # 输出运行时间if __name__ == "__main__":example()  # 执行示例

利用sagemath运行可得p,q,d

已知d,计算RSA解密公式 m=cdmod  nm = c^{d} \mod nm=cdmodn

Payload

from Crypto.Util.number import getPrime, inverse, long_to_bytes
from sympy import isprime# 已知的参数
n = 65318835751656706270462803918372182811096669561139853833192009681234356986381524661604904085035483519298788284835759796179173585004238691057332447589167439506386243352011548441011828732868691543989256629925692290088144403935880664585931943707422938295860559274669263630591393175387389387981929391774213395003
e = 40738963799387627677248718814260921636491770341278750841486515130562842134876396915106681433734276005332410415984785584884091334455816402584507178231273998519376915363193650533215442952274343814099450187672503465016280527554101223321817109358581483535333734940968961773897326303002987203525415266163296607215
c = 28858301095788879003830568949705095027466057921892765321643055383309726369907606901866332954652632036004551285284813812187678314978562231120323470819722044516158810710408496414616381570397632550468546302235826400628265458069027801013266037490695637948933487646553291637002155559023268928639502489285322508063
hint1 = 624859718207126357681
hint2 = 810475217500119132950
d = 514966421261428616864174659198108787824325455855002618826560538514908088230254475149863519# 根据 hint1 和 hint2 生成 p 和 q
def recover_p_q(hint1, hint2):# p 的可能值for i in range(2**70):  # 70 位可以变化的部分p_candidate = (hint1 << (512 - 70)) | iif isprime(p_candidate):for j in range(2**70):q_candidate = (hint2 << (512 - 70)) | jif isprime(q_candidate):if p_candidate * q_candidate == n:return p_candidate, q_candidatereturn None, Nonep, q = recover_p_q(hint1, hint2)if p and q:print(f"Recovered p: {p}")print(f"Recovered q: {q}")# 验证 d 是否正确phi_n = (p - 1) * (q - 1)assert (d * e) % phi_n == 1# 解密密文 cm = pow(c, d, n)plaintext = long_to_bytes(m)print(f"Recovered plaintext: {plaintext.decode('utf-8')}")
else:print("Failed to recover p and q.")

运行之后得到

有原题Σ(⊙▽⊙"a

Crypto01:  领航杯原题。参考: https://www.cnblogs.com/mumuhhh/p/17789591.html 

可以在sage notebook上跑,也可以命令行: sage  high_p_q_rsa.sage跑, 大概 10秒左右就出结果了~

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

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

相关文章

Golang | Leetcode Golang题解之第528题按权重随机选择

题目&#xff1a; 题解&#xff1a; type Solution struct {pre []int }func Constructor(w []int) Solution {for i : 1; i < len(w); i {w[i] w[i-1]}return Solution{w} }func (s *Solution) PickIndex() int {x : rand.Intn(s.pre[len(s.pre)-1]) 1return sort.Searc…

3D打印机 屏幕的固定挂钩断后的一次自己修复经历

引子 3D打印机的屏幕固定挂钩断了 这次确实不知道咋断的&#xff0c;这可咋办呢&#xff0c;到网上看了一下&#xff0c;一个屏幕要2佰多&#xff0c;有些小贵&#xff0c;要不就自己修修吧&#xff0c;打个挂钩按上&#xff0c;说干就干。 正文 freecad的设计图如下【其中各…

PHP合成图片,生成海报图,poster-editor使用说明

之前写过一篇使用Grafika插件生成海报图的文章&#xff0c;但是当我再次使用时&#xff0c;却发生了错误&#xff0c;回看Grafika文档&#xff0c;发现很久没更新了&#xff0c;不兼容新版的GD&#xff0c;所以改用了intervention/image插件来生成海报图。 但是后来需要对海报…

Java基于微信小程序的美食推荐系统(附源码,文档)

博主介绍&#xff1a;✌程序猿徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

Linux的IP网路命令: 用于显示和操作网络接口(网络设备)的命令ip link详解

目录 一、概述 二、用法 1、基本语法 2、常用选项 3、常用参数 4、获取帮助 三、示例 1. 显示所有网络接口的信息 &#xff08;1&#xff09;命令 &#xff08;2&#xff09;输出示例 &#xff08;3&#xff09;实际操作 2. 启动网络接口 3. 停止网络接口 4. 更改…

C语言 | Leetcode C语言题解之第526题优美的排列

题目&#xff1a; 题解&#xff1a; int countArrangement(int n) {int f[1 << n];memset(f, 0, sizeof(f));f[0] 1;for (int mask 1; mask < (1 << n); mask) {int num __builtin_popcount(mask);for (int i 0; i < n; i) {if (mask & (1 <<…

SpringBoot篇(自动装配原理)

目录 一、自动装配机制 1. 简介 2. 自动装配主要依靠三个核心的关键技术 3. run()方法加载启动类 4. 注解SpringBootApplication包含了多个注解 4.1 SpringBootConfiguration 4.2 ComponentScan 4.3 EnableAutoConfiguration 5. SpringBootApplication一共做了三件事 …

3D Gaussian Splatting代码详解(二):模型构建

3 模型构建 gaussians GaussianModel(dataset.sh_degree) 3.1 初始化函数 __init__ 构造函数 构造函数 __init__ 的主要作用是初始化 3D 高斯模型的各项参数和激活函数&#xff0c;用于生成 3D 空间中的高斯表示。 初始化球谐函数的参数&#xff1a; self.active_sh_degre…

如何在 linux 中使用 /etc/fstab 挂载远程共享 ?

在 Linux 领域&#xff0c;高效的管理文件系统和数据存储对于用户和管理员来说&#xff0c;是一项基本技能。 有一种特别有用的技术涉及自动建立远程共享&#xff0c;允许无缝访问网络存储&#xff0c;就好像是本地的一样。 本指南将引导您完成使用 /etc/fstab 文件以自动远程…

iOS用rime且导入自制输入方案

iPhone 16 的 cantonese 只能打传统汉字&#xff0c;没有繁简转换&#xff0c;m d sh d。考虑用「仓」输入法 [1] 使用 Rime 打字&#xff0c;且希望导入自制方案 [2]。 仓输入法有几种导入方案的方法&#xff0c;见 [3]&#xff0c;此处记录 wifi 上传法。准备工作&#xff1…

ts:常见的运算符

ts&#xff1a;常见的运算符 1 主要内容说明2 表格2.1 算数运算符2.2 赋值运算符2.3 比较运算符2.4 逻辑运算符2.5 位运算符2.6 三元运算符 3 例子3.1 位运算符3.1.1 源码1 &#xff08;位运算符&#xff09;3.1.2 源码1运行效果 3.结语4.定位日期 1 主要内容说明 ts中的各种运…

unity搭建场景学习

unity搭建场景学习 创建场景创建gameobject创建材质&#xff0c;用于给gameobject上色拖拽材质球上色上色原理设置多个材质方式设置贴图的方式 效果设置光滑度一些预览设置菜单渲染模型与碰撞模型网格渲染参数1. materials(材质)2. lighting(光照)3. reflection probes(反射探针…

『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC

『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC 文章目录 一. 『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC1. 介绍 二. 参考文献 一. 『Linux学习笔记』如何在 Ubuntu 22.04 上安装和配置 VNC 如何在 Ubuntu 22.04 上安装和配置 VNChttps://hub.docker.c…

xlwings,让excel飞起来!

excel已经成为必不可少的数据处理软件&#xff0c;几乎天天在用。python有很多支持操作excel的第三方库&#xff0c;xlwings是其中一个。 关于xlwings xlwings开源免费&#xff0c;能够非常方便的读写Excel文件中的数据&#xff0c;并且能够进行单元格格式的修改。 xlwings还…

03.DDD六边形架构

学习视频来源&#xff1a;DDD独家秘籍视频合集 https://space.bilibili.com/24690212/channel/collectiondetail?sid1940048&ctype0 文章目录 什么是依赖DDD四层架构六边形架构代码实现 想要详细了解六边形架构&#xff0c;可以看我之前的一篇文章。是对六边形架构原文的翻…

在VS Code中操作MySQL数据库

【基础篇】 【小白专用24.5.26 已验证】VSCode下载和安装与配置PHP开发环境&#xff08;详细版&#xff09;_vscode php-CSDN博客 ~~~~~~~~~~~~~~~~~~~~~~~~~ 在VS Code中下载插件 Prettier SQL VSCode 和 MySQL : 随后在VS Code中点击Database图标 在连接界面输入MySQL数据库…

使用WebAssembly优化Web应用性能

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用WebAssembly优化Web应用性能 引言 WebAssembly 简介 安装工具 创建 WebAssembly 项目 编写 WebAssembly 代码 编译 WebAssem…

AI工具列表

AI写作工具 工具名称推测的https://地址笔灵AI写作https://ibiling.cn/Paperpalhttps://paperpal.com新华妙笔https://miaobi.xinhuaskl.com/讯飞写作https://iflytek.com墨狐AIhttps://inkfox-ai.com/火山写作https://www.writingo.net/橙篇https://chengpian.com&#xff08…

HTML 基础标签——元数据标签 <meta>

文章目录 1. `<meta>` 标签概述2. 属性详解2.1 `charset` 属性2.2 `name` 属性2.3 `content` 属性2.4 `http-equiv` 属性3. 其他常见属性小结在 HTML 文档中,元数据标签 <meta> 是一种重要的标签,用于提供关于文档的信息,这些信息不直接显示在网页内容中,但对于…

基于STM32的智能手环设计

本设计的主控芯片采用STM32F103C8T6&#xff0c;体温模块采用DS18B20温度传感器&#xff0c;显示模块采用OLED显示&#xff0c;心率、血氧的测量采用MAX30102模块既不需要外接电路&#xff0c;又可以保障数据稳定&#xff0c;内部还具有降噪功能。采用这些模块&#xff0c;保证…