ProVerif验证的加密协议并发程序通过公共通道来进行信息较交互,最终实现一些目标。认为攻击者对这样的通道有完全的控制能力,包括阅读、修改、删除和注入消息,也可以解密自己持有密钥的消息(视解密为获取密文的唯一途径,不考虑攻击者用其它方式获取密文,所以如果自己没有解密的密钥就不行)。

1 握手协议

握手协议(Handshake protocol)是有一个客户端A和服务器B,假设每一方都有自己的公私钥对,然后A知道B的公钥pk(skB),协议的目的是让客户端A能向服务器B分享自己的私密信息s。

协议按照如下的方式工作。应客户端A的要求,B生成一个新的对称的密钥k,作为会话密钥,把这个k和自己的公钥pk(skB)打包,然后先用自己的私钥skB签名,再用A的公钥pk(skA)加密,也就是说要发送的是:
aenc(sign((pk(skB),k),skB),pk(skA))aenc(sign((pk(skB),k),skB),pk(skA))aenc(sign((pk(skB),k),skB),pk(skA))

其中sign是签名,aenc是非对称加密。

A收到消息后,先用自己的密钥skA解密,再用B的公钥pk(skB)验证一下内容无误,然后提取出会话密钥k,就能用这个k给自己的私密信息s加密然后发送了。

这个协议背后的基本原理在于,A收到的是用她的公钥非对称加密的结果,因此她应该是唯一能够解密其内容的人。而数字签名是用来确保B是这个消息的发起者。

整个过程如下:
A→B:pk(skA)B→A:aenc(sign((pk(skB),k),skB),pk(skA))A→B:senc(s,k)\begin{aligned} A \to B &: pk(skA) \\ B \to A &: aenc(sign((pk(skB),k),skB),pk(skA)) \\ A \to B &: senc(s, k) \end{aligned} A→BB→AA→B​:pk(skA):aenc(sign((pk(skB),k),skB),pk(skA)):senc(s,k)​

上面的协议叙述还不够清晰,比如要检查每一步收到的格式是正确的,叙述里没有,但是协议建模到ProVerif时要做这些事。

用自然语言描述希望这个协议所具有的三个性质:

  1. 保密性:只有A和B知道s的值
  2. 认证性(A到B):如果B运行到了末尾,他认为和A共享了k,那么A确实是B的对话者,共享了这个k
  3. 认证性(B到A):如果B运行到了末尾,她认为和B共享了k,那么B确实是提供k的一方

这个协议可以受到中间人攻击,一个中间人I可以先和B通信,再冒充B和A通信:
I→B:pk(skI)B→I:aenc(sign((pk(skB),k),skB),pk(skI))A→B:pk(skA)I→A:aenc(sign((pk(skB),k),skB),pk(skA))A→I:senc(s,k)\begin{aligned} I \to B &: pk(skI) \\ B \to I &: aenc(sign((pk(skB),k),skB),pk(skI)) \\ A \to B &: pk(skA) \\ I \to A &: aenc(sign((pk(skB),k),skB),pk(skA)) \\ A \to I &: senc(s, k) \end{aligned} I→BB→IA→BI→AA→I​:pk(skI):aenc(sign((pk(skB),k),skB),pk(skI)):pk(skA):aenc(sign((pk(skB),k),skB),pk(skA)):senc(s,k)​

只要让服务器回传的信息中包含目标客户端的标识(这里是用公钥)就可以防止这种攻击发生了:
A→B:pk(skA)B→A:aenc(sign((pk(skA),pk(skB),k),skB),pk(skA))A→B:senc(s,k)\begin{aligned} A \to B &: pk(skA) \\ B \to A &: aenc(sign((pk(skA),pk(skB),k),skB),pk(skA)) \\ A \to B &: senc(s, k) \end{aligned} A→BB→AA→B​:pk(skA):aenc(sign((pk(skA),pk(skB),k),skB),pk(skA)):senc(s,k)​

2 声明

用户定义类型,其中t是类型名称:

type t.

定义free的变量(原文是free names),其中n是变量名称,t是类型名:

free n : t.

定义一连串的free names,都是t类型的:

free n1,...,nk : t.

channel c.free c : channel.是同一个意思,都是声明一个公共信道c,如果要指定不被攻击者获取,使用:

free n : t [private].

构造器(函数)用来构建密码协议使用的建模原语,例如单向哈希、加密、数字签名等:

fun f(t1,...,tn) : t.

其中f是有n个参数的构造器,t是返回值类型,t1tn是参数。构造器默认是可以被攻击者使用的,如果要禁止攻击者使用,则要:

fun f(t1,...,tn) : t [private].

例如,这种私有的构造可以用在对服务器密钥表的建模上。


密码原语之间的关系由析构器指明,析构函数用于操作构造器组成的项。析构器使用如下的重写规则:

reduc forall x1,1 : t1,1,...,x1,n1 : t1,n1; g(M1,1,...,M1,k) = M1,0 ;...forall xm,1 : tm,1,...,xm,nm : tm,nm;g(Mm,1,...,Mm,k) = Mm,0 .

其中ggg是有k个参数的析构器,项M1,1,...,M1,k,M1,0M_{1,1},...,M_{1,k},M_{1,0}M1,1​,...,M1,k​,M1,0​是将构造器作用于t1,1,...,t1,n1t_{1,1},...,t_{1,n_1}t1,1​,...,t1,n1​​类型的x1,1,...,x1,n1x_{1,1},...,x_{1,n_1}x1,1​,...,x1,n1​​上得到的。上面每一行重写规则,ggg的返回值M1,0M_{1,0}M1,0​到Mm,0M_{m,0}Mm,0​都应该具有相同的类型,同样的,析构函数里每次传的参数表相应位置上也必须是相同的类型。

每次执行到g(M1,1,...,M1,k)g(M_{1,1},...,M_{1,k})g(M1,1​,...,M1,k​)或者这一项的实例时,都会找一条合适的重写规则将其变成对应的M1,0M_{1,0}M1,0​。如果无法应用重写规则时,析构失败,进程会阻塞(除了let进程)。这和真实世界的密码原语是一致的。

如果多个变量有相同的类型,就只写最后一个的类型就行:

reduc forall x,y : t,z : t'; g(M_1,...,M_k)=M_0.

和构造器类似,析构器也可以加[private]声明为私有的。

3 示例:为握手协议声明加密原语

现在对握手协议中使用的密码学原语进行形式化。


首先是对称加密,这里定义一个密钥类型key,定义了一个对称加密函数senc,传入bitstring(内置的)和key,然后返回一个bitstring

type key.
fun senc(bitstring, key): bitstring.

再定义一个析构器,来对解密操作进行建模:

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

其中m表示消息,k表示对称密钥。


对于非对称加密,使用一元构造器pk,传入私钥,返回公钥。也可以理解成是传入一个私钥就能生成对应的公钥,从而得到公私钥对。解密的析构器也是和前面类似的做法。

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

对于数字签名,和非对称加密是类似的,需要有签名私钥sskey和签名公钥spkey,用私钥签名、公钥验证。下面是一种带有消息恢复的签名,getmess就是直接从签名后的信息中提取到原信息,而checksign则是用公钥对签名进行验证,只有验证通过时才能返回原信息m

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

还支持元组,元组是n>=2n>=2n>=2的(M1,...,Mn)(M_1,...,M_n)(M1​,...,Mn​)。如果允许攻击者访问某个元组,他可以取得其中的任何一项;反过来,如果攻击者有M1,...,MnM_1,...,M_nM1​,...,Mn​,他就可以构造元组。

元组中的每一项可以是任何类型,但是元组总是bitstring类型的,所以如果某个构造器的某个参数是bitstring类型的,那就可以传个元组进去。

需要注意元组一定是n>=2n>=2n>=2的,只有一个元素的(M1)(M_1)(M1​)和M1M_1M1​没区别,不是元组。

参考阅读

ProVerif的manual第3~3.1.2章节

【ProVerif学习笔记】2:协议建模中的声明相关推荐

  1. 【转】医疗业务学习笔记--DICOM协议的基础内容!!!!!!!!!!

    转自:医疗业务学习笔记--DICOM协议的基础内容 - 知乎 本文首发于"雨夜随笔"公众号,欢迎关注. DICOM协议是医疗领域对如何处理.存储.打印和传输医疗图片的一系列标准.D ...

  2. Go语言开发学习笔记(持续更新中)

    Go语言开发学习笔记(持续更新中) 仅供自我学习 更好的文档请选择下方 https://studygolang.com/pkgdoc https://www.topgoer.com/go%E5%9F% ...

  3. Java快速入门学习笔记9 | Java语言中的方法

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  4. Java快速入门学习笔记8 | Java语言中的数组

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  5. Java快速入门学习笔记7 | Java语言中的类与对象

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  6. Java快速入门学习笔记3 | Java语言中的表达式与操作符

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  7. Java快速入门学习笔记2 | Java语言中的基本类型

    有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...

  8. ROS学习笔记十一:ROS中数据的记录与重放

    ROS学习笔记十一:ROS中数据的记录与重放 本节主要介绍如何记录一个正在运行的ROS系统中的数据,然后在一个运行的系统中根据记录文件重新产生和记录时类似的运动情况.本例子还是以小海龟例程为例. 记录 ...

  9. python学习笔记26(python中__name__的使用)

    python学习笔记26(python中__name__的使用) 在python中,每个py文件都是一个模块,也都是一个可执行文件,即包含main方法.因此,对每个py文件,可以单独运行,也可以imp ...

最新文章

  1. Java EE---Spring AOP
  2. mysql 不要统计null_浅谈为什么Mysql数据库尽量避免NULL
  3. IDEA + Maven创建SpringMVC项目和XML配置
  4. jgGrid常用操作--持续更新
  5. malloc在函数内分配内存问题
  6. 为MySQL选择合适的备份方式
  7. java 选取topn_取Oracle中实现TOPN,选取前几条记录
  8. 普元EOS常见问题及处理经验
  9. FME中的栅格数据操作之十二——矢量数据栅格化
  10. uclinux上任天堂游戏模拟器移植
  11. 手机拍照反差对焦、相位对焦和激光对焦系统解析
  12. 自由复制360doc个人图书馆的文档
  13. markdown编辑器_Markdown编辑器
  14. KAZE FEATURES
  15. 3com - 美国设备提供商
  16. 一些实用的产品经理工具网站,助力提升你的专业技能!
  17. 如何与离职员工面谈沟通?
  18. 汇川PLC和PLC之间ModebusTCP通讯
  19. 【读书笔记】《游戏改变世界》
  20. 关于字符串拆分,合并问题的整理

热门文章

  1. MEM/MBA数学基础(02)实数运算和性质
  2. c语言实数加法程序,蓝桥杯 算法提高 实数相加(c语言版附注释)
  3. elf section类型_ELF格式解析库之基本数据类型
  4. 小蓝单车的“死法”:从梦幻开场到资金断链
  5. python项目策划书_Python实战计划学习第一周
  6. 企业现金流和资金链区别
  7. lisp 河道水面线计算_美国工程兵团河道水面线计算CAD(HEC-RAS)
  8. Nature Communications:基于弥散张量成像的人类纤维束连接体方法面临的挑战
  9. 为淘宝网店免费使用流量统计教程
  10. 常见互联网slb方案