【ProVerif学习笔记】6:握手协议(handshake protocol)建模

2023-10-31

这节先不继续往下看,巩固一下对ProVerif建模握手协议的理解。

握手协议的流程如下:
在这里插入图片描述

ex_handshake.pv(只验证保密性)

手册里在引入security性质之前,握手协议的模型如下:

(* ------------------------对称加密相关------------------------ *)
(* 对称密钥 *)
type key.
(* 对称加密:传入要加密的内容和密钥,返回加密结果 *)
fun senc(bitstring, key): bitstring.
(* 对称解密:用于析构对称加密,传入加密结果senc(m,k),用同一个密钥k可解密出原始信息m *)
reduc forall m: bitstring, k: key; sdec(senc(m,k),k) = m.


(* ------------------------非对称加密相关------------------------ *)
(* 非对称加密-私钥 *)
type skey.
(* 非对称加密-公钥 *)
type pkey.
(* 从私钥获取公钥:可以用于密钥配对 *)
fun pk(skey): pkey.
(* 非对称加密:传入要加密的内容和公钥,返回加密结果 *)
fun aenc(bitstring, pkey): bitstring.
(* 非对称解密:用于析构非对称加密,传入加密结果aenc(m,pk(sk)),用其私钥sk可解密出原始信息m *)
reduc forall m: bitstring, sk: skey; adec(aenc(m,pk(sk)),sk) = m.


(* ------------------------数字签名相关------------------------ *)
(* 数字签名-私钥 *)
type sskey.
(* 数字签名-公钥 *)
type spkey.
(* 从私钥获取公钥:可以用于密钥配对 *)
fun spk(sskey): spkey.
(* 数字签名:传入要签名的内容和私钥,返回签名结果 *)
fun sign(bitstring, sskey): bitstring.
(* 获取消息:无视签名用的私钥ssk,直接获取其中的消息m *)
reduc forall m: bitstring, ssk: sskey; getmess(sign(m,ssk)) = m.
(* 验证签名后获取消息:使用公钥spk(ssk)方能对使用ssk签名的消息验证,并成功取出m *)
reduc forall m: bitstring, ssk: sskey; checksign(sign(m,ssk),spk(ssk)) = m.


(* ------------------------全局声明相关------------------------ *)
(* 通信信道c,是一个公有的信道 *)
free c:channel.
(* 要传输的保密消息s,由于使用[private]修饰,所以攻击者无法直接获取 *)
free s:bitstring [private].


(* ------------------------查询相关------------------------ *)
(* 查询攻击者能否窃取s,即关于s的保密性 *)
query attacker(s).


(* ------------------------进程相关------------------------ *)
(* 客户端进程A:A公钥、A私钥、B公钥 *)
let clientA(pkA:pkey,skA:skey,pkB:spkey) =
	(* 将A公钥发送到通道c *)
	out(c,pkA);
	(* 从通道c取回B传来的结果x *)
	in(c,x:bitstring);
	(* 用自己的私钥skA对结果x解密得到y *)
	let y = adec(x,skA) in
	(* 用B的公钥pkB对y验证,验证结果需是(pkB, k),第二项k即是对称密钥 *)
	let (=pkB,k:key) = checksign(y,pkB) in
	(* 使用对称密钥k对消息明文s加密并发送 *)
	out(c,senc(s,k)).

(* 服务器进程B:B公钥、B私钥 *)
let serverB(pkB:spkey,skB:sskey) =
	(* 从通道c取出公钥,是A的公钥 *)
	in(c,pkX:pkey);
	(* 新建一个对称密钥k *)
	new k:key;
	(*(pkB,k)用B的私钥skB签名,然后用A的公钥pkX加密,发到通道c *)
	out(c,aenc(sign((pkB,k),skB),pkX));
	(* 从通道c拿到A发来的消息x *)
	in(c,x:bitstring);
	(* 使用对称密钥k解密即可得到消息明文z *)
	let z = sdec(x,k) in
	0.

(* 总的进程 *)
process
	(* A的私钥 *)
	new skA:skey;
	(* B的私钥 *)
	new skB:sskey;
	(* A的公钥,生成后发到通道c上,攻击者可获取 *)
	let pkA = pk(skA) in out(c,pkA);
	(* B的公钥,生成后发到通道c上,攻击者可获取 *)
	let pkB = spk(skB) in out(c,pkB); 
	(* 实际行为是无限个客户端A和无限个服务器B的并发执行 *)
	( (!clientA(pkA,skA,pkB)) | (!serverB(pkB,skB)) )

整体就是两类进程,客户端clientA和服务器serverB。认为一个服务器B的进程实体是可以服务任何一个具体的客户端的,所以在它的macro里只传入了自己签名用的公钥和私钥。而一个客户端A的进程实体只会找一个具体的服务器,所以是在自己的macro里传入了想要服务自己的服务器B的公钥,在这里定死了。

这里希望有无数的进程在并发执行,对客户端和服务器都是做了replication(符号!)然后再并发。

还有要注意的就是之前学习的解构器(destructor)模式匹配(pattern matching) 的使用。

解构器本身如果传入的东西不匹配就会解构失败, 解构失败会走let-in-else的else路线,如果else被省略掉(像上面一样)就会把进程直接halt掉,所以一般解构器本身就能检查传过来的东西是不是按期望的合规的。

模式匹配可以和解构器一起用,这样不仅要求解构成功,还需要模式匹配成功才能走let-in-else的in路线,否则一律走else路线。比如

let (=pkB,k:key) = checksign(y,pkB)

这一行,不仅要求y是用pkB对应的私钥skB签名的(这样才能解构成功),而且要求解构后的内容能匹配到一个二元组形式(分别是签名方公钥和签名方提供的对称密钥),还要求二元组的第二项能匹配到一个key类型(对称密钥),二元组的第一项能匹配到公钥pkB上(和自己期望的pkB是相同的,这块只是签名方自己声明自己的身份,其实在密码学上还不够强,比如第二节里学习到可能遭受中间人攻击)。

这个是最原始的握手协议,因为可能遭受中间人攻击,所以验证结果是不通过的:

--------------------------------------------------------------
Verification summary:

Query not attacker(s[]) is false.

--------------------------------------------------------------

ex_handshake_annotated.pv(加入对认证性的验证)

手册里3.2节讲security性质的时候引用了这个case,这里“annotated”意思就是如果要证明authentication(一种security性质,表达认证关系,包括用correspondence断言和injective correspondence断言两种声明),那么是需要用event来标记程序点的:

To reason with correspondence assertions, we annotate processes withevents, which markimportant stages reached by the protocol but do not otherwise affect behavior.

因为correspondence断言就是用来捕获事件先后关系的:

“if an event e has been executed, then event e′ has been previously executed.”

这种标记不会影响进程本身的行为,也不会让攻击者的知识有任何的增加或者减少。添加了事件标记的模型如下:

type key.
fun senc(bitstring, key): bitstring.
reduc forall m: bitstring, k: key; sdec(senc(m,k),k) = m.

type skey.
type pkey.
fun pk(skey): pkey.
fun aenc(bitstring, pkey): bitstring.
reduc forall m: bitstring, sk: skey; adec(aenc(m,pk(sk)),sk) = m.

type sskey.
type spkey.
fun spk(sskey): spkey.
fun sign(bitstring, sskey): bitstring.
reduc forall m: bitstring, ssk: sskey; getmess(sign(m,ssk)) = m.
reduc forall m: bitstring, ssk: sskey; checksign(sign(m,ssk),spk(ssk)) = m.

free c:channel.
free s:bitstring [private].
query attacker(s).

(* 客户端认为自己在使用key对称密钥和服务器进行协议交互 *)
event acceptsClient(key).
(* 服务器认为自己在使用key对称密钥和pkey公钥标识的客户端进行协议交互 *)
event acceptsServer(key,pkey).
(* pkey标识的客户端认为自己使用key和服务器进行协议交互结束 *)
event termClient(key,pkey).
(* 服务器认为自己使用key对称密钥和客户端进行协议交互结束 *)
event termServer(key).

(*
对于每个以对称密钥x和服务器交互结束的客户端y
前面总是存在认定以对称密钥x和客户端y交互的服务器
*)
query x:key,y:pkey; event(termClient(x,y))==>event(acceptsServer(x,y)).
(*
对于每个以对称密钥x交互结束的服务器
前面总是存在一个区别于其它的“以对称密钥x和服务器交互的客户端”
即单射关系
*)
query x:key; inj-event(termServer(x))==>inj-event(acceptsClient(x)).

let clientA(pkA:pkey,skA:skey,pkB:spkey) = 
	out(c,pkA);
	in(c,x:bitstring); 
	let y = adec(x,skA) in
	let (=pkB,k:key) = checksign(y,pkB) in
	(* 客户端解密成功+验证成功后即认为接受了使用密钥k通信 *)
	event acceptsClient(k);
	out(c,senc(s,k));
	(* 客户端运行结束,本次是使用k通信,自己的公钥是pkA *)
	event termClient(k,pkA).

let serverB(pkB:spkey,skB:sskey,pkA:pkey) = 
	in(c,pkX:pkey);
	new k:key;
	(* 服务器收到客户端公钥pkX,并创建了密钥k,即认为接受了使用密钥k和客户端pkX通信 *)
	event acceptsServer(k,pkX);
	out(c,aenc(sign((pkB,k),skB),pkX));
	in(c,x:bitstring);
	let z = sdec(x,k) in
	(* 如果接收到的pkX确实是pkA,即认为服务器使用对称密钥k运行结束 *)
	if pkX = pkA then event termServer(k).

process
	new skA:skey;
	new skB:sskey;
	let pkA = pk(skA) in out(c,pkA);
	let pkB = spk(skB) in out(c,pkB);
	( (!clientA(pkA,skA,pkB)) | (!serverB(pkB,skB,pkA)) )

注意这一版不仅加入了event,而且在serverB的macro中传入了pkA,这是因为termServer本身需要判断自己交互的pkX是pkA。

这一版只是加了认证性质的验证,但是还是没有解决中间人攻击问题。

--------------------------------------------------------------
Verification summary:

Query not attacker(s[]) is false.

Query event(termClient(x_2,y_1)) ==> event(acceptsServer(x_2,y_1)) is false.

Query inj-event(termServer(x_2)) ==> inj-event(acceptsClient(x_2)) is true.

--------------------------------------------------------------

结果第一条表明,对消息s还是不满足的。

结果第二条表明,从B(服务器)到A(客户端)的认证是不满足的,也就是说如果客户端觉得自己和服务器完成了协议流程,不一定真的有这个服务器在和客户端走协议,这个也是因为中间人可以冒充服务器来和客户端通信。

结果第三条表明,从A(客户端)到B(服务器)的认证是满足的,也就是说如果服务器觉得自己走完了协议流程,一定至少有一个客户端是在和自己走协议的。

ex_handshake_annotated_fixed.pv(解决中间人攻击)

这里主要就是像第二节里说的那样,让服务器回传的信息中包含目标客户端的标识(这里是用公钥)来防止中间人攻击发生。

type key.
fun senc(bitstring, key): bitstring.
reduc forall m: bitstring, k: key; sdec(senc(m,k),k) = m.

type skey.
type pkey.
fun pk(skey): pkey.
fun aenc(bitstring, pkey): bitstring.
reduc forall m: bitstring, sk: skey; adec(aenc(m,pk(sk)),sk) = m.

type sskey.
type spkey.
fun spk(sskey): spkey.
fun sign(bitstring, sskey): bitstring.
reduc forall m: bitstring, ssk: sskey; getmess(sign(m,ssk)) = m.
reduc forall m: bitstring, ssk: sskey; checksign(sign(m,ssk),spk(ssk)) = m.

free c:channel.
free s:bitstring [private].
query attacker(s).

event acceptsClient(key).
event acceptsServer(key,pkey).
event termClient(key,pkey).
event termServer(key).

query x:key,y:pkey; event(termClient(x,y))==>event(acceptsServer(x,y)).
query x:key; inj-event(termServer(x))==>inj-event(acceptsClient(x)).

let clientA(pkA:pkey,skA:skey,pkB:spkey) = 
	out(c,pkA);
	in(c,x:bitstring); 
	let y = adec(x,skA) in
	(* 这里检查一下这个包确实是要发给自己pkA的 *)
	let (=pkA,=pkB,k:key) = checksign(y,pkB) in
	event acceptsClient(k);
	out(c,senc(s,k));
	event termClient(k,pkA).

let serverB(pkB:spkey,skB:sskey,pkA:pkey) = 
	in(c,pkX:pkey);
	new k:key; 
	event acceptsServer(k,pkX);
	(* 这里把要通信的客户端标识pkX放进去 *)
	out(c,aenc(sign((pkX,pkB,k),skB),pkX));
	in(c,x:bitstring); 
	let z = sdec(x,k) in
	if pkX = pkA then event termServer(k).

process 
	new skA:skey; 
	new skB:sskey;
	let pkA = pk(skA) in out(c,pkA);
	let pkB = spk(skB) in out(c,pkB);
	( (!clientA(pkA,skA,pkB)) | (!serverB(pkB,skB,pkA)) )

现在三条性质就都能验证通过了:

--------------------------------------------------------------
Verification summary:

Query not attacker(s[]) is true.

Query event(termClient(x_2,y_1)) ==> event(acceptsServer(x_2,y_1)) is true.

Query inj-event(termServer(x_2)) ==> inj-event(acceptsClient(x_2)) is true.

--------------------------------------------------------------
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【ProVerif学习笔记】6:握手协议(handshake protocol)建模 的相关文章

  • 计算机网络——传输层

    一 传输层概述 传输层功能 完成主机进程 主机进程之间的报文传输 传输层是真正的端对端的通信 传输层协议在端主机上运行 路由器一般没有传输层 传输层从主机层面上对网络层采取相应补救措施 可以提供更高质量的数据传输能力 传输层独立于网络设备
  • 计算机网络体系结构 - 运输层

    一 运输层协议概述 运输层为应用进程之间提供端到端的逻辑通信 二 运输层的端口 端口 port 也称为协议端口号 protocol port number 对上层的应用进程进行标识 端口用一个16位端口号进行标志 端口号只具有本地意义 端口
  • 网络传输基本流程

    网络传输流程图 在数据链路层有一个标识 每一台主机的唯一符 MAC地址 MAC地址 计算机的网卡在出厂时就打上了一串数据 MAC 地址 其通常是唯一的 所以局域网中发消息必须加上目的主机的MAC地址 两台计算机通过 TCP IP 协议通讯的
  • TCP/IP、UDP协议

    TCP IP协议是Internet最基本的协议 Internet国际互联网络的基础 由网络层的IP协议和传输层的TCP协议组成 通俗而言 TCP负责发现传输的问题 一有问题就发出信号 要求重新传输 直到所有数据安全正确地传输到目的地 而IP
  • 【八股】2023秋招八股复习笔记1(CSBase+部分WXG题)

    文章目录 MYSQL redis 网络 系统 安全 C 招聘要求 x3 部分面经和题目 WXG 后端 x5 MYSQL redis redis memcached mysql 线程模型 6 0多线程 持久化 AOF RDB 功能 过期删除
  • IP地址和子网掩码详解

    原文链接 IP和子网掩码 我们都知道 是由四段数字组成 在此 我们先来了解一下3类常用的 A类IP段 0 0 0 0 到127 255 255 255 B类IP段 128 0 0 0 到191 255 255 255 C类IP段 192 0
  • 计算机网络系列五 -- 运输层详解

    1 运输层 1 1 运输层的定义 运输层是 OSI 七层参考模型的第四层 主要功能为应用层提供通信服务 它即是面向通信的最高层 也是用户功能的最底层 在计算机网络中 真正进行数据通信的是两个主机的进程 由于一个主机中有多个进程同时在通信 而
  • 【计算机网络09】传输层之TCP连接管理

    文章目录 1 深入理解序号seq 确认号ack 2 建立连接 三次握手 2 1 状态解读 2 2 前 2 次握手的特点 2 3 为什么建立连接要进行 3 次握手 2 次不行吗 2 4 第 3 次握手失败了会怎么处理 3 释放连接 四次挥手
  • 物理层(比特流)

    物理层 一 物理层的基本概念 二 数据通信的基础知识 1 数据通信系统的模型 2 有关信道的几个基本概念 3 信道的极限容量 4 信道的极限信息传输速率 三 物理层下面的传输媒体 1 导引型传输媒体 2 非导引型传输媒体 四 信道复用技术
  • tcp三次握手和四次挥手的过程

    TCP是面向连接的 无论哪一方向另一方发送数据之前 都必须先在双方之间建立一条连接 在TCP IP协议中 TCP 协议提供可靠的连接服务 连接是通过三次握手进行初始化的 三次握手的目的是同步连接双方的序列号和确认号 并交换 TCP窗口大小信
  • 交换机自学习和转发帧

    交换机自学习和转发帧 主机A给主机B发送帧 首先假设已经通过arp协议得到主机B的MAC地址 当交换机1收到该帧后将源MAC地址和接口登记 然后在帧交换表中查到目的MAC地址 没有找到就进行盲目转发 泛洪 交换机2收该帧后 做相同的动作 主
  • 端口介绍

    文章来源 https m toutiaocdn com group 6680437870504706572 app news article timestamp 1563010542 req id 201907131735410100230
  • 什么是protocol分层,垂直service??计算机网络详解【计算机网络养成】

    内容导航 分组丢失和延时 发生原因 四种分组延时 节点处理延迟 排队延迟 传输延时 Transmission 传播延时 Propagation 使用cmd命令tracert 和 tracerert 来检查延迟 分组丢失 吞吐量 有效的数据量
  • 根据子网掩码算出 IP 地址 的网络号和主机号

    我们如何根据子网掩码算出 IP 地址 的网络号和主机号呢 举个例子 比如 10 100 122 0 24 后面的 24表示就是 255 255 255 0 子网掩码 255 255 255 0 二进制是 11111111 11111111
  • 计算机网络笔记Part2 物理层(Physical Layer)

    计算机网络笔记Part2 物理层 Physical Layer 一 物理层基本概念 二 数据通信 1 一个数据通信例子 2 相关术语 3 三种通讯方式 4 两种数据传输方式 5 码元 Symbol 波特 Baud 速率 带宽 Band Wi
  • 图片详解TCP连接的三次握手,四次断开基本原理

    图片详解TCP连接的三次握手 四次断开 作者 林子 Blog http blog csdn net u013011841 时间 2014年8月 出处 http blog csdn net u013011841 article details
  • 计算机网络试题

    一 选择题 1 OSI模型与TCP IP模型都具有的层次是 A 会话层 网络层和物理层 B 表示层 会话层和数据链路层 C 网络层 传输层和应用层 D 表示层 数据链路层和物理层 2 对于计算机网络体系结构 下列关于第N层和第N 1层的关系
  • 计算机网络(二)| 物理层上 | 数据通信基础知识 调制 频率范围 信噪比

    文章目录 1 物理层基本概念 2 数据通信基础知识 2 1 数据通信基本概念 2 2 信道基本概念 2 2 1 基带调制 编码 方式 2 2 2 带通调制方式 2 3 信道的极
  • P2P应用

    目录 一 P2P的简介 二 P2P的工作方式 1 具有集中目录服务器的P2P工作方式 2 具有全分布式结构的P2P文件共享程序 一 P2P的简介 P2P 对等连接 是指两台主机在通信时 并不区分哪一个是服务请求方和哪一个是服务提供方 只要两
  • 计算机网络基础 走入计算机行业的重中之重

    计算机网络是指将地理位置不同的 功能独立的多台计算机通过通信线路连接起来 以功能完善的网络软件支撑 实现资源共享和信息传递的系统 对于信息安全高级工程师来说 理解计算机网络的基本原理是至关重要的 下面我们将逐一解析计算机网络的核心概念 网络

随机推荐

  • 机器学习心得体会总结

    第一 线性代数是把复杂问题简单化解决 但是简单问题已经很复杂了 第二 国内还没有一本关于机器学习讲得连老百姓都能看得明白的书籍 第三 克拉默法则 逆矩阵 初等变换都可以求解方程Ax b 后者方法更简单
  • C语言

    目录 一 实验环境 二 黑白圣诞树 三 windows h简介 四 windows h实现彩色圣诞树 1 设置用户窗口 2 移动光标 3 修改字体颜色 4 绘制圣诞树 5 绘制雪景 6 完整代码 7 运行 一 实验环境 编译环境 vc 6
  • 【因果推断与机器学习】带入坑——之辛普森悖论

    因果推断与机器学习 Why you might Care Simpson s Paradox 考虑一个纯粹假设的未来 那里有一种被称为COVID 27的新疾病在人类中普遍存在 在这个纯粹假设的未来中 已经开发了两种治疗方法 治疗A和治疗B
  • 西门子dcs系统组态手册下载_PLC/DCS/HMI 知识普及

    什么是PLC 可编程控制器 简称PLC Programmable logic Controller 是指以计算机技术为基础的新型工业控制装置 在1987年国际电工委员会颁布的PLC标准草案中对PLC做了如下定义 PLC是一种专门为在工业环境
  • 原版安装Win10 1909专业版 64位MSDN镜像2020 05

    原版安装Win10 1909专业版 64位MSDN镜像2020 05 一 更新内容 1 去除预装kms激活 未激活的可以通过桌面自行激活 2 提升商店购买应用的速度性能 3 解决在IE浏览器中阻碍下载和安装 NET组件的问题 4 更新修复补
  • Qt5.14.2 MInGW静态编译配置教程

    Qt5 14 2 MinGW静态编译教程 1 安装Qt 1 1 下载安装包 1 2 安装 2 工具的下载安装 3 检查上述配置是否成功 4 静态编译qmake 4 1 静态编译配置 4 2 编译 4 3 安装静态库 4 4新增静态编译 1
  • SQL Server(五)-视图

    与表一样 视图也是由字段和记录组成的 只是这些字段和记录来源于其他被引用的表或视图 所以视图并不是真实存在的 而是一张虚拟的表 视图中的数据并不是存在于视图中的 而是存在于被引用的数据表当中的 当被引用的数据表中的记录内容改变时 视图中的记
  • 临沂地区的OLED拼接屏有哪些独特优点?

    临沂oled拼接屏是一种高清晰度的显示屏 由多个oled屏幕拼接而成 它可以用于商业广告 展览 会议 演出等场合 具有高亮度 高对比度 高色彩饱和度 高刷新率等优点 能够吸引人们的眼球 提高信息传递效果 临沂oled拼接屏的优点之一是高亮度
  • 虚拟偶像是未来趋势吗?

    Hello 我的朋友 这里是古希伯 今天聊聊 虚拟偶像行业是不是未来的趋势 虚拟偶像零都知道吧 日本初音未来 洛天依诸多的 日本虚拟偶像行业市场是最为发达的 日漫这一块本身具有先天优势存在 乃至于国内诸多公司都没有能力完全复刻 虚拟偶像目前
  • slot-插槽的基本使用-具名插槽的使用(重要)

    slot 插槽的基本使用 具名插槽的使用 为什么使用slot slot翻译为插槽 1 在生活中很多地方都有插槽 电脑的USB插槽 插板当中的电源插槽 2 插槽的目的是让我们原来的设备具有更多的扩展性 3 比如电脑的USB我们可以插入U盘 硬
  • 手撸,自定义application.yml配置项

    文章目录 前言 教程 1 加入配置依赖 及maven插件 2 元注解 分析 3 配置文件 4 测试能不能用 5 怎么从配置里面取值 并加载呢 第一 我们在配置中加入值 第二 编写一个自动配置类 前言 我们现在在springboot中 极其简
  • Spring Dynamic Modules - DMserver

    spring dm server 官网 http static springsource com projects dm server 1 0 x programmer guide htmlsingle programmer guide h
  • 英语发音规则---gh

    英语发音规则 gh 一 总结 一句话总结 gh字母组合的读音在中学英语课本中归纳起来主要有 发音 和 不发音 两种情况 gh字词首是发 g 因为需要开头啊 例如 ghost g st n 鬼 幽灵 gh在词尾读作 f 因为需要尾巴 例如 l
  • 什么是相关性

    我们曾经讲过 默认情况下 返回结果是按相关性倒序排列的 但是什么是相关性 相关性如何计算 每个文档都有相关性评分 用一个正浮点数字段 score 来表示 score 的评分越高 相关性越高 查询语句会为每个文档生成一个 score 字段 评
  • OPENCV+QT环境配置

    qt opencv开发入门 4步搞定opencv环境配置2 https www bilibili com video BV1f34y1v7t8 vd source 0aeb782d0b9c2e6b0e0cdea3e2121eba 第一步 安
  • U20.4 升级 pytorch 1.11

    一 系统环境 1 系统已安装 pytorch 1 7 1 8 a pip install torch 1 8 2 cu111 torchvision 0 9 2 cu111 torchaudio 0 8 2 f https download
  • 小编必看,教你如何使用微信公众号编辑器快速排版精美文章

    对于小编而言 写作就是每天的日常 图文排版是公众号的形象 也是新媒体运营小编必须掌握的技能 一篇文章除了内容优质之外 排版也是非常重要的 好的排版才能让读者有更好的阅读体验 俗话说 工欲善其事 必先利其器 众多微信公众号编辑器中 推荐使用来
  • CMAKE语法:add_definitions、add_compile_options

    前言 CMAKE命令通用理解 command
  • SQL_开发技巧(附阿里巴巴开发规范)

    目录 一 数据库命令规范 1 1 explain 1 2 单表delete或者update语句 加个limit 1 3 where后字段 隐式转换 1 4 减少不必要的查询字段 1 5 SQL命令行修改数据 养成begin commit 事
  • 【ProVerif学习笔记】6:握手协议(handshake protocol)建模

    这节先不继续往下看 巩固一下对ProVerif建模握手协议的理解 握手协议的流程如下 ex handshake pv 只验证保密性 手册里在引入security性质之前 握手协议的模型如下 对称加密相关 对称密钥 type key 对称加密