这节先不继续往下看,巩固一下对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) in0.(* 总的进程 *)
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) inlet (=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).processnew 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) inevent 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) inif 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.--------------------------------------------------------------

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

  1. 【ProVerif学习笔记】2:协议建模中的声明

    ProVerif验证的加密协议并发程序通过公共通道来进行信息较交互,最终实现一些目标.认为攻击者对这样的通道有完全的控制能力,包括阅读.修改.删除和注入消息,也可以解密自己持有密钥的消息(视解密为获取 ...

  2. IOS之学习笔记十五(协议和委托的使用)

    1.协议和委托的使用 1).协议可以看下我的这篇博客 IOS之学习笔记十四(协议的定义和实现) https://blog.csdn.net/u011068702/article/details/809 ...

  3. 网络协议学习笔记-IGMP协议

     网络协议学习笔记-IGMP协议 http://hi.baidu.com/clxye/item/3db870336d86c0c11a969614 IGMP协议(Internet Group Man ...

  4. 【转】:TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute

    TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute 分类:            TCP/IP详解学习笔记计算机网络2006-04-20 18:147970人阅读评论(1)收 ...

  5. 【学习笔记】正确写作美国大学生数学建模竞赛论文(已获得国二、美O)

    [学习笔记]正确写作美国大学生数学建模竞赛论文(已获得国二.美O) 第2章 正确使用英文 第3章 写作规范 第4章 数学表达式 第5章 MCM/ICM竞赛论文写作 最近在学习总结如何写作美赛论文,就把 ...

  6. 【ProVerif学习笔记】3:进程宏和进程书写的语法规则

    1 进程宏 进程宏(Process Macros)用来定义子进程,因为在用ProVerif对协议进行建模时,直接一个大的主进程比较混乱,进程宏的形式为: l e t R ( x 1 : t 1 , . ...

  7. 【ProVerif学习笔记】4:信息安全性质(Security Property)

    1 Reachability和Secrecy 证明Reachability是最基本的能力,因为需要知道攻击者能访问到哪些term,而Secrecy就可以根据这个来评估--能访问到的term不满足Sec ...

  8. 以太网学习笔记1——主要协议及帧结构

    目录奉上,用者自取: 文章目录 1. 以太网主要协议关系介绍 2. 协议介绍及帧结构 2.1 媒体访问控制子层协议MAC 2.2 地址解析协议ARP 2.2.1ARP帧结构 2.2.2 ARP协议工作 ...

  9. FPGA学习笔记_UART串口协议_串口接收端设计

    FPGA学习笔记 1. UART串口协议以及串口接收端设计 1 原理图 2 Verilog 代码 3 Modelsim仿真 4. FPGA板级验证 1.1 串口协议接收端设计 目标:FPGA接收其他设 ...

最新文章

  1. 在shell脚本中没有换行符的#39;echo#39;
  2. RxSwift之UI控件Label扩展的使用
  3. h5适配华为手机_知道为什么建站大多选H5自适应网站吗?现在我就告诉你
  4. Android PermissionUtils:运行时权限工具类及申请权限的正确姿势
  5. 《C++ Primer 第五版》(第4.11节类型转换) ————关于无符号数和有符号数的运算探究
  6. java 树同构_有根树的同构 和 无根树的同构
  7. 年度旗舰机广告片遭电视台泄露 三星:我有句话不知当讲不当讲
  8. iOS-保存图片到(自定义)相册步骤
  9. jenkins pipeline之如何串联多个Job
  10. linux内存管理(十四)-内存OOM触发分析
  11. Java IO(五)——字符流进阶及BufferedWriter、BufferedReader
  12. 对模型方差和偏差的解释之二:泛化误差
  13. 安装360后无法远程sqlserver error:64
  14. MySQL(4) 数据库增删改查SQL语句(整理集合大全)
  15. Spark-Sql源码解析之三 Analyzer:Unresolved logical plan – analyzed logical plan
  16. px、em、rem、rpx 用法 与 区别
  17. 中央电大c 语言程序设计本科试题,中央电大本科C语言程序设计A试题2010年7月.doc...
  18. 让设计师哭笑不得的文案
  19. 搭建个人网站需要的三个步骤
  20. Day02—homework

热门文章

  1. 算法工程师5——计算机视觉知识点概览
  2. vscode代码拼写检查插件的使用(超详细)
  3. python圆的半径计算圆的周长列表_用python计算圆的周长
  4. SY6982E芯片了解
  5. Map和Set的常用方法和简述
  6. 曾经写过得太监小说4《无名》
  7. html文档中的元素分为两部分,云开HTML5开发基础与应用(20秋)形考作业2【标准答案】...
  8. 新学期,新FLAG | 尽人事,听天命,守得云开见月明
  9. 职场上个人价值的三个驱动力
  10. 小可爱怎么备份word自动图文集呢?