密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议

这篇具有很好参考价值的文章主要介绍了密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

配置ProVerif环境

实验环境: Windows 11 X64
根据ProVerif用户手册1.4.3节,Windows用户可以使用二进制发行版安装ProVerif。首先现在你想要的文件路径中新建一个proverif文件夹。

相关依赖组件安装

graphviz

graphviz是一种以图形方式显示ProVerif可能发现攻击的组件,可以通过官网链接进行下载。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
我的操作系统是64位系统,所以我选择64位的 EXE installer。
下载后将其解压到解压到proverif文件中。
接下来配置环境变量,配置路径:控制面板->系统->高级系统设置->环境变量。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
在命令行窗口中输入dot -version查看是否已经安装成功,出现以下内容则已经安装成功。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

GTK+2.24(可选)

如果要运行交互式模拟器proverif交互,则需要安装GTK+2.24,也可以通过官网链接进行下载。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
同样下载适配我的电脑的版本。下载完之后是一个压缩包:gtk+-bundle_2.24.10-20120208_win32.zip,解压到proverif文件中,将解压文件改名为GTK
同样对其进行环境配置,配置路径:控制面板->系统->高级系统设置->环境变量。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

ProVerif安装

Windows二进制包proverifbin2.05.tar.gz从以下老的不行的官网链接进行下载。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
下载之后将它放到之前建好的proverif文件夹中,我们使用以下命令行窗口来解压。

	cd /d D:\proverif
	tar -zxvf proverif2.05.tar.gz

解压完成后,proverif文件夹就会出现一个名为proverif2.05的文件。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

测试

proverif2.05文件中新建一个txt文件,输入以下内容:

free c:channel.

free Cocks:bitstring[private].
free RSA:bitstring[private].

query attacker(RSA).
query attacker(Cocks).

process
   out(c,RSA);
   0

命名为hello.pv(记得修改文件后缀名,不然会不成功)。
在命令行窗口中输入proverif hello.pv,出现以下内容即成功。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

HandShake Protocol握手协议

(* Symmetric key encryption *)

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

(* Asymmetric key encryption *)

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.


(* Digital signatures *)

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).

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
	out(c,senc(s,k)).

let serverB(pkB:spkey,skB:sskey) =
	in(c,pkX:pkey);
	new k:key;
	out(c,aenc(sign((pkB,k),skB),pkX));
	in(c,x:bitstring);
	let z = sdec(x,k) in
	0.

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)) )

协议分析

这里首先分析一下上面的代码的工作,proverif从process标记的主进程开始分析,所以这里看process后面的内容。

首先是为clientA生成了非对称加密私钥skA,同时为serverB生成了签名用的私钥skB,并分别为这两个私钥生成对应的公钥(pkA,pkB),并通过公开信道c将这两个公钥发送出去。

接下来调用两个进程宏clientA和serverB来实现两个进程的并发执行,这里用replication的方式让两个主体都以无限数量会话并发执行(clientA和serverB前面的感叹号表示重复无限多个会话并发)。

然后关注clientA和serverB这两个模块,这里要把两个模块结合起来看,首先是A把自己公钥pkA发出去,B会接收到这个公钥pkX,同时创建一个对称密钥k(k这里起到临时会话密钥的作用)。

然后B将这个临时密钥k和自己的公钥pkB一起打包成元组,先用自己的私钥skB签名(sign部分),再用收到的公钥pkX加密,并通过公共信道发出去(aenc部分,这里aenc表示非对称加密)。

A通过信道接收到这个发来的bitstring,然后用自己私钥解密,解密成功之后得到y,之后用B的公钥pkB验证签名,如果验证通过了就会得到元组(m,k),第一项就是pkB(这里用=pkB来匹配),第二项就是对称密钥kA再用这个k给消息s进行对称加密然后发出去,B接收到发来的bitstring之后,用自己刚刚创建的对称密钥k解密就得到了内容z,这应该和s是一样的内容

不难看出,这段代码很简单,所以也不难想到中间人攻击。

proverif协议分析

将上述代码保存为ex_handshake.pv文件,然后执行以下命令,可以得到proverif分析上述握手协议的结果。

proverif ex_handshake.pv

ProVerif会输出其考虑过程的内部表示,然后一次处理逻辑中的查询(由query关键字表示),查询攻击者的输出可以分为三个部分:

  • Abbreviations到detailsed部分:proverif推导出的导致攻击的流程
  • detailed到trace has been found:描述了上述攻击的轨迹
  • result:最终结论,true表示不存在攻击,false表示存在攻击者获取相关信息

这里分部分来看,首先是abbreviations的部分:
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

  1. attacker用一个已知的私钥 k_3 生成对应的公钥 pk(k_3) (对应abbreviations的前两步,这里的k_3 可以是attacker自己生成的,或者通过其他方式已知的)。
  2. 然后这里标记了代码的{16}位置,该位置表示可以从信道中收到攻击者发出的公钥 pk(k_3) ,同时在{18}位置会将消息aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3)) 消息通过信道发出,此时
    attacker可以接收到这条消息(也即attacker获取到了这个知识)。
  3. 然后attacker可以从信道中获得这条加密的消息( aenc ),attacker利用私钥 k_3 对其解密,可以得到 sign((spk(skB[],k_2),skB[])) ,并通过 getmess 获取签名的内容(也即(spk(skB[]),k_2) ),这里意味着attacker可以获得 k_2。
  4. 之后attacker获取A的公钥 pkA ,并用该公钥对sign((spk(skB[]),k_2),skB[]) 进行加密并发送出去。
  5. 这条消息会在{10}被client收到,client验证签名政确之后,会在{13}将消息 senc(s[],k_2) 发送出去,attacker会收到这条消息。
  6. 之后attacker就可以用 k_2 解密得到 s[]。

然后看detailed output的部分
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

  • 前两行对应的是公钥密钥对和签名密钥对的创建过程。
  • 然后是三个out,前两个out表示attacker将加密公钥和签名公钥分别保存在 ~M 和 ~M_1 中,第三个out表示client在{9}处的输出,attacker将其保存为 ~M_2。
  • 从下面开始,之后的每一行后面都跟了一个 in copy a 或者 in copy a_2 ,相同的标识表示相同的会话, copy a 表示当前attacker正在与client进行通信, copy a_2 表示当前attacker正在和server通信
  • 接下来,表示attacker向server发送了一个公钥,同时server返回了一个用server私钥签名并加密的消息,这里attacker将这条消息保存为 ~M_3。
  • 然后,里表示attacker在{10}这里,用 a_1 这个私钥解密 ~M_3 ,再用client的公钥加密(这里的 ~M 就是client的公钥),将加密后的消息发送出去,当client在{13}返回加密的消息时,attacker可以利用 k_4 解密并获得 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)).

完整的协议如下:

(* Symmetric key encryption *)

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


(* Asymmetric key encryption *)

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.


(* Digital signatures *)

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
	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)) )

这一版只是加了认证性质的验证,但是还是没有解决中间人攻击问题。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析
结果第一条表明,对消息s还是不满足安全性的。

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

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

所以我们需要进步以改进这个协议,让服务器回传的信息中包含客户端的标识来防止中间人攻击的发生。

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)) )

现在三条性质都能验证通过。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

Needham-Schroeder Protocol

Needham-Schroeder认证协议,是一种多次提问——响应协议,可以对付重放攻击。每一个会话回合都有一个新的随机数在起作用。
密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

  1. A 向KDC 发送报文1,表明要与B通信。KDC以报文2回答。报文1中加入了由A 指定的随机数R_A, KDC 的回答报文中也有R_A, 它的这个作用是保证报文2是新鲜的,而不是重放的。
  2. 报文2中的K_B(A, K_S) 是KDC 交给A 的入场券,其中有KDC 指定的会话键K_S, 并且用B和KDC 之间的密钥加密,A 无法打开,只能原样发给B。

下面给出Needham-Schroeder 密钥共享协议的三个变体,说明各个协议变体存在的缺陷,尝试给出攻击方式。

NeedhamSchroederPK-var1.pv

free c: channel.

(* Public key encryption *)
type pkey.
type skey.

fun pk(skey): pkey.
fun aenc(bitstring, pkey): bitstring.
reduc forall x: bitstring, y: skey; adec(aenc(x, pk(y)),y) = x.

(* Signatures *)
type spkey.
type sskey.

fun spk(sskey): spkey.
fun sign(bitstring, sskey): bitstring.
reduc forall x: bitstring, y: sskey; getmess(sign(x,y)) = x.
reduc forall x: bitstring, y: sskey; checksign(sign(x,y), spk(y)) = x.

(* Shared key encryption *)
fun senc(bitstring,bitstring): bitstring.
reduc forall x: bitstring, y: bitstring; sdec(senc(x,y),y) = x.
(* Authentication queries *)
event beginBparam(pkey).
event endBparam(pkey).
event beginAparam(pkey).
event endAparam(pkey).

query x: pkey; inj-event(endBparam(x)) ==> inj-event(beginBparam(x)).
query x: pkey; inj-event(endAparam(x)) ==> inj-event(beginAparam(x)).

(* Secrecy queries *)
free secretANa, secretANb, secretBNa, secretBNb: bitstring [private].

query attacker(secretANa);
      attacker(secretANb);
      attacker(secretBNa);
      attacker(secretBNb).

(* Alice *)
let processA(pkB: pkey, skA: skey) =
	in(c, pkX: pkey);
	event beginBparam(pkX); 
	new Na: bitstring; 
	out(c, aenc((Na, pk(skA)), pkX));
	in(c, m: bitstring); 
	let (=Na, NX: bitstring) = adec(m, skA) in
	out(c, aenc(NX, pkX));
	if pkX = pkB  then
	event endAparam(pk(skA));
	out(c, senc(secretANa, Na));
	out(c, senc(secretANb, NX)).

(* Bob *)
let processB(pkA: pkey, skB: skey) =
	in(c, m: bitstring);
	let (NY: bitstring, pkY: pkey) = adec(m, skB) in
	event beginAparam(pkY);
	new Nb: bitstring;
	out(c, aenc((NY, Nb), pkY));
	in(c, m3: bitstring);
	if Nb = adec(m3, skB) then
	if pkY = pkA then
	event endBparam(pk(skB));
	out(c, senc(secretBNa, NY));
	out(c, senc(secretBNb, Nb)).

(* Main *)
process 
	new skA: skey; let pkA = pk(skA) in out(c, pkA);
	new skB: skey; let pkB = pk(skB) in out(c, pkB);
	( (!processA(pkB, skA)) | (!processB(pkA, skB)) )

使用proverif分析结果

密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

  1. 这个查询表示当B的参数结束时,相应的B的参数开始是否受到注入攻击。由于结果是false,说明在这个情况下,检测到乐注入攻击。

  2. 这个查询表示当A的参数结束时,相应的A的参数开始是否受到注入攻击。由于结果是true,说明在这个情况下,没有检测到注入攻击。

  3. 这个查询表示攻击者是否能够获得A的某个密钥(可能是Na)。结果是true,说明攻击者无法获取此密钥

  4. 这个查询类似于上一个,表示攻击者是否能够获得A的另一个密钥。结果是true,说明攻击者无法获取此密钥。

  5. 这个查询表示攻击者是否能够获得B的某个密钥(可能是Na)。结果是false,说明攻击者能够获取此密钥。

  6. 这个查询类似于上一个,表示攻击者是否能够获得B的另一个密钥。结果是false,说明攻击者能够获取此密钥。

漏洞分析

注入攻击检测不完善

查询 inj-event(endBparam(x)) ==> inj-event(beginBparam(x)) is false 表明系统在B参数结束时未能检测到注入攻击。这可能意味着系统对于某些情况下的注入攻击检测不够强大,需要进一步改进。

密钥泄漏问题

查询 not attacker(secretBNa[]) is false 和 not attacker(secretBNb[]) is false 表明攻击者能够获取B的某些密钥。这可能是系统中的一个重大漏洞,需要加强密钥管理和保护机制,以防止攻击者获取关键信息。

部分成功的注入攻击

查询 inj-event(endAparam(x)) ==> inj-event(beginAparam(x)) is true 表明系统在A参数结束时检测到了注入攻击。这可能表示在某些情况下系统能够成功地检测到攻击,但在其他情况下可能会失败。需要深入研究系统在各种场景下的注入攻击检测能力。

部分密钥保护

查询 not attacker(secretANa[]) is true 和 not attacker(secretANb[]) is true 表明攻击者无法获取A的某些密钥。这是系统的一个积极方面,但仍然需要确保所有关键密钥都得到足够的保护。

NeedhamSchroederPK-var2.pv

free c: channel.

(* Public key encryption *)
type pkey.
type skey.

fun pk(skey): pkey.
fun aenc(bitstring, pkey): bitstring.
reduc forall x: bitstring, y: skey; adec(aenc(x, pk(y)),y) = x.

(* Signatures *)
type spkey.
type sskey.

fun spk(sskey): spkey.
fun sign(bitstring, sskey): bitstring.
reduc forall x: bitstring, y: sskey; getmess(sign(x,y)) = x.
reduc forall x: bitstring, y: sskey; checksign(sign(x,y), spk(y)) = x.

(* Shared key encryption *)
type nonce.

fun senc(bitstring,nonce): bitstring.
reduc forall x: bitstring, y: nonce; sdec(senc(x,y),y) = x.

(* Type converter *)
fun nonce_to_bitstring(nonce): bitstring [data,typeConverter].

(* Two honest host names A and B *)
type host.
free A, B: host.

(* Key table *)
table keys(host, pkey).

(* Authentication queries *)
event beginBparam(host).
event endBparam(host).
event beginAparam(host).
event endAparam(host).

query x: host; inj-event(endBparam(x)) ==> inj-event(beginBparam(x)).
query x: host; inj-event(endAparam(x)) ==> inj-event(beginAparam(x)).

(* Secrecy queries *)
free secretANa, secretANb, secretBNa, secretBNb: bitstring [private].

query attacker(secretANa);
      attacker(secretANb);
      attacker(secretBNa);
      attacker(secretBNb).

(* Alice *)
let processA(pkS: spkey, skA: skey) =
	in(c, hostX: host);
	event beginBparam(hostX); 		
	out(c, (A, hostX));                              (* msg 1 *)
	in(c, ms: bitstring);                            (* msg 2 *)
	let (pkX: pkey, =hostX) = checksign(ms, pkS) in
	new Na: nonce; 
	out(c, aenc((Na, A), pkX));                      (* msg 3 *)
	in(c, m: bitstring);                             (* msg 6 *)
	let (=Na, NX: nonce) = adec(m, skA) in
	out(c, aenc(nonce_to_bitstring(NX), pkX));       (* msg 7 *)
	if hostX = B then
	event endAparam(A);
	out(c, senc(secretANa, Na));
	out(c, senc(secretANb, NX)).

(* Bob *)
let processB(pkS: spkey, skB: skey) =
	in(c, m: bitstring);                             (* msg 3 *)
	let (NY: nonce, hostY: host) = adec(m, skB) in
	event beginAparam(hostY);
	out(c, (B, hostY));                              (* msg 4 *)
	in(c,ms: bitstring);                             (* msg 5 *)
	let (pkY: pkey,=hostY) = checksign(ms, pkS) in
	new Nb: nonce;
	out(c, aenc((NY, Nb), pkY));                     (* msg 6 *)
	in(c, m3: bitstring);                            (* msg 7 *)
	if nonce_to_bitstring(Nb) = adec(m3, skB) then
	if hostY = A then
	event endBparam(B);
	out(c, senc(secretBNa, NY));
	out(c, senc(secretBNb, Nb)).

(* Trusted key server *)
let processS(skS: sskey) =  
	in(c,(a: host, b: host)); 
	get keys(=b, sb) in
	out(c,sign((sb,b), skS)).

(* Key registration *)
let processK =
	in(c, (h: host, k: pkey));
	if h <> A && h <> B then insert keys(h,k).

(* Main *)
process 
	new skA: skey; let pkA = pk(skA) in out(c, pkA); insert keys(A, pkA);
	new skB: skey; let pkB = pk(skB) in out(c, pkB); insert keys(B, pkB);
	new skS: sskey; let pkS = spk(skS) in out(c, pkS);
	( (!processA(pkS, skA)) | (!processB(pkS, skB)) | 
	  (!processS(skS)) | (!processK) )

使用proverif分析结果

密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

漏洞分析

NeedhamSchroederPK-var1.pv

NeedhamSchroederPK-var3.pv

(* Loops if types are ignored *)
set ignoreTypes = false.

free c: channel.

type host.
type nonce.
type pkey.
type skey.
type spkey.
type sskey.

fun nonce_to_bitstring(nonce): bitstring [data,typeConverter].

(* Public key encryption *)
fun pk(skey): pkey.
fun encrypt(bitstring, pkey): bitstring.
reduc forall x: bitstring, y: skey; decrypt(encrypt(x,pk(y)),y) = x.

(* Signatures *)
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.

(* Shared key encryption *)
fun sencrypt(bitstring,nonce): bitstring.
reduc forall x: bitstring, y: nonce; sdecrypt(sencrypt(x,y),y) = x.

(* Secrecy assumptions *)
not attacker(new skA).
not attacker(new skB).
not attacker(new skS).

(* 2 honest host names A and B *)
free A, B: host.

table keys(host, pkey).

(* Queries *)
free secretANa, secretANb, secretBNa, secretBNb: bitstring [private].
query attacker(secretANa);
      attacker(secretANb);
      attacker(secretBNa);
      attacker(secretBNb).

event beginBparam(host, host).
event endBparam(host, host).
event beginAparam(host, host).
event endAparam(host, host).
event beginBfull(host, host, pkey, pkey, nonce, nonce).
event endBfull(host, host, pkey, pkey, nonce, nonce).
event beginAfull(host, host, pkey, pkey, nonce, nonce).
event endAfull(host, host, pkey, pkey, nonce, nonce).

query x: host, y: host; 
	inj-event(endBparam(x,y)) ==> inj-event(beginBparam(x,y)).

query x1: host, x2: host, x3: pkey, x4: pkey, x5: nonce, x6: nonce; 
	inj-event(endBfull(x1,x2,x3,x4,x5,x6))  
			==> inj-event(beginBfull(x1,x2,x3,x4,x5,x6)).

query x: host, y: host; 
	inj-event(endAparam(x,y)) ==> inj-event(beginAparam(x,y)).

query x1: host, x2: host, x3: pkey, x4: pkey, x5: nonce, x6: nonce; 
	inj-event(endAfull(x1,x2,x3,x4,x5,x6)) 
			==> inj-event(beginAfull(x1,x2,x3,x4,x5,x6)).

(* Role of the initiator with identity xA and secret key skxA *)
let processInitiator(pkS: spkey, skA: skey, skB: skey) =
	(* The attacker starts the initiator by choosing identity xA,
	   and its interlocutor xB0.
	   We check that xA is honest (i.e. is A or B)
	   and get its corresponding key. *)
	in(c, (xA: host, hostX: host));
	if xA = A || xA = B then
	let skxA = if xA = A then skA else skB in
	let pkxA = pk(skxA) in
	(* Real start of the role *)
	event beginBparam(xA, hostX); 
	(* Message 1: Get the public key certificate for the other host *)
	out(c, (xA, hostX));
	(* Message 2 *)
	in(c, ms: bitstring); 
	let (pkX: pkey, =hostX) = checksign(ms,pkS) in
	(* Message 3 *)
	new Na: nonce; 
	out(c, encrypt((Na, xA), pkX));
	(* Message 6 *)
	in(c, m: bitstring); 
	let (=Na, NX2: nonce) = decrypt(m, skxA) in
	event beginBfull(xA, hostX, pkX, pkxA, Na, NX2);
	(* Message 7 *)
	out(c, encrypt(nonce_to_bitstring(NX2), pkX));
	(* OK *)
	if hostX = B || hostX = A then
	event endAparam(xA, hostX);
	event endAfull(xA, hostX, pkX, pkxA, Na, NX2);
	out(c, sencrypt(secretANa, Na));
	out(c, sencrypt(secretANb, NX2)).

(* Role of the responder with identity xB and secret key skxB *)
let processResponder(pkS: spkey, skA: skey, skB: skey) =
	(* The attacker starts the responder by choosing identity xB.
	   We check that xB is honest (i.e. is A or B). *)
	in(c, xB: host);
	if xB = A || xB = B then
	let skxB = if xB = A then skA else skB in
	let pkxB = pk(skxB) in
	(* Real start of the role *)
	(* Message 3 *)
	in(c, m: bitstring);
	let (NY: nonce, hostY: host) = decrypt(m, skxB) in
	event beginAparam(hostY, xB);
	(* Message 4: Get the public key certificate for the other host *)
	out(c, (xB, hostY));
	(* Message 5 *)
	in(c,ms: bitstring);
	let (pkY: pkey,=hostY) = checksign(ms,pkS) in
	(* Message 6 *)
	new Nb: nonce;
	event beginAfull(hostY, xB, pkxB, pkY, NY, Nb);
	out(c, encrypt((NY, Nb), pkY));
	(* Message 7 *)
	in(c, m3: bitstring);
	if nonce_to_bitstring(Nb) = decrypt(m3, skB) then
	(* OK *)
	if hostY = A || hostY = B then
	event endBparam(hostY, xB);
	event endBfull(hostY, xB, pkxB, pkY, NY, Nb);
	out(c, sencrypt(secretBNa, NY));
	out(c, sencrypt(secretBNb, Nb)).

(* Server *)
let processS(skS: sskey) =  
	in(c,(a: host, b: host)); 
	get keys(=b, sb) in
	out(c,sign((sb,b),skS)).

(* Key registration *)
let processK =
	in(c, (h: host, k: pkey));
	if h <> A && h <> B then insert keys(h,k).

(* Main *)
process 
	new skA: skey; let pkA = pk(skA) in	out(c, pkA); insert keys(A, pkA);
	new skB: skey; let pkB = pk(skB) in out(c, pkB); insert keys(B, pkB);
	new skS: sskey; let pkS = spk(skS) in out(c, pkS);
	(
		(* Launch an unbounded number of sessions of the initiator *)
		(!processInitiator(pkS, skA, skB)) | 
		(* Launch an unbounded number of sessions of the responder *)
		(!processResponder(pkS, skA, skB)) |
		(* Launch an unbounded number of sessions of the server *)
		(!processS(skS)) |
		(* Key registration process *)
		(!processK)
	)

使用proverif分析结果

密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议,密码协议形式化分析与可证明安全实验,安全,密码学,威胁分析

  1. 这个查询表示攻击者无法获取A的某些比特串(Na)。结果是true,表明系统在防止攻击者获取A的某些敏感比特串方面是成功的。

  2. 类似于前一个查询,这个查询表示攻击者无法获取A的另一组比特串(Nb)。结果是true,表明系统在保护A的敏感比特串上是成功的。

  3. 这个查询表示攻击者能够获取B的某些比特串(Na)。结果是false,这是一个潜在的漏洞,系统可能需要改进B的比特串保护措施,以防止攻击者获取关键信息

  4. 类似于前一个查询,这个查询表示攻击者能够获取B的另一组比特串(Nb)。结果是false,系统可能需要改进B的比特串保护机制

  5. 这个查询表示,在B参数结束时的注入事件不会导致在B参数开始时的注入事件。结果是true,表明系统在B参数的结束处成功防止了注入攻击。

  6. 类似于前一个查询,这个查询表示在B的完整数据结束时的注入事件不会导致在B的完整数据开始时的注入事件。结果是true,表明系统在B的完整数据结束处成功防止了注入攻击。

  7. 这个查询表示,在A参数结束时的注入事件会导致在A参数开始时的注入事件。这意味着系统在A参数的结束处未能防止注入攻击,结果是false,系统可能需要加强对A参数的注入攻击检测和防护措施。

  8. 类似于前一个查询,这个查询表示在A的完整数据结束时的注入事件会导致在A的完整数据开始时的注入事件。结果是false,表明系统在A的完整数据结束处未能防止注入攻击。系统可能需要改进对A的完整数据的注入攻击检测和防护机制

漏洞分析

A参数注入漏洞

漏洞分析: 可能存在未经过充分验证和过滤的A参数输入,导致在A参数结束时的注入事件影响了A参数的开始。

攻击方法: 攻击者可能会尝试通过在A参数结束时注入恶意代码或数据,来影响A参数的开始,执行未授权的操作或者篡改系统状态。

B参数比特串保护不足

漏洞分析: 暗示攻击者能够获取B参数的某些比特串,可能意味着存在对B参数比特串的不充分保护。

攻击方法: 攻击者可能会尝试通过拦截或者篡改B参数的比特串,来绕过安全控制,获取敏感信息或者执行未授权的操作。

A完整数据注入漏洞

漏洞分析: 暗示在A的完整数据结束时的注入事件可能影响A的完整数据的开始,表明存在对A完整数据注入的不足防护。

攻击方法: 攻击者可能会试图通过在A完整数据结束时注入恶意数据,来影响A完整数据的开始,导致数据不一致或者执行不当操作。

B完整数据注入漏洞

漏洞分析: 表明在B的完整数据结束时的注入事件无法有效防止在B的完整数据开始时的注入事件,存在B完整数据注入漏洞。

攻击方法: 攻击者可能会尝试通过在B完整数据结束时注入恶意数据,来绕过防护,影响B完整数据的开始,导致数据不一致或者执行不当操作。

引用参考

https://blog.csdn.net/JingYan_Chan/article/details/133149371
https://lauzyhou.blog.csdn.net/article/details/116376508
https://blog.csdn.net/LiLiLiZuoBuKai/article/details/126676169?ops_request_misc=&request_id=&biz_id=102&utm_term=needham-schroeder%20%E5%8D%8F%E8%AE%AE%E5%88%86%E6%9E%90&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-6-126676169.142v99control&spm=1018.2226.3001.4187文章来源地址https://www.toymoban.com/news/detail-783726.html

到了这里,关于密码协议形式化分析与可证明安全实验1——使用proverif来分析密码协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 软件工程——第4章形式化说明技术(非重点)

    本专栏是博主个人笔记,主要目的是利用碎片化的时间来记忆软工知识点,特此声明! 1.软件工程方法划分成哪三类?并各自举例 2.形式化方法的定义?

    2024年02月11日
    浏览(33)
  • 傻白入门芯片设计,形式化验证方法学——AveMC工具学习(二十)

    目录 一、形式验证方法学 (一)什么是形式化验证? (二)与传统验证的区别? 二、AveMC工具学习 (一)什么是AveMC? (二)AveMC的工作逻辑?  (三)AveMC验证应用场景? (四)AveMC的多种debug方式? (一)什么是形式化验证? 形式化验证方法学是 使用数学证明的方法,

    2024年02月11日
    浏览(26)
  • 密码学:可证明安全

    观看浙江大学暑期crypto school讲座的可证明安全有感,总结如下: 目录 · 概述 · 公钥密码 · 单向函数 · 离散对数 · DH密钥协商协议 · 用可证明安全证明DH密钥协商协议的安全性 可证明安全主要分为三个步骤: 确定威胁模型; 其次构造方案; 给出一个正式的安全性证明。

    2024年02月02日
    浏览(84)
  • 密码学之可证明安全初探

    本文将简要介绍现代密码学中的一项关键技术: 安全性证明 . 任何一个现代密码算法或协议都需要先经过完整的安全性证明, 才能去讨论其理论和应用价值. 如果一个密码方案无法做到可证明安全, 那么它声称的各种能力都将只是空中楼阁. 然而, 刚开始阅读现代密码学论文的时

    2024年02月12日
    浏览(24)
  • 切诺夫界(Chernoff Bound)形式及其证明

    设随机变量X的取值为 非负数 ,马尔可夫不等式形式为: P ( X ≥ ξ ) ≤ E ( X ) ξ P(X ge xi) le frac{E(X)}{xi} P ( X ≥ ξ ) ≤ ξ E ( X ) ​ p r o o f . proof. p roo f . 设非负随机变量 X X X 的概率密度函数为 f ( x ) f(x) f ( x ) E ( X ) = ∫ 0 ∞ x f ( x ) d x = ∫ 0 ξ x f ( x ) d x + ∫ ξ ∞ x f ( x ) d

    2024年02月03日
    浏览(29)
  • 《网络协议》05. 网络通信安全 · 密码技术

    title: 《网络协议》05. 网络通信安全 · 密码技术 date: 2022-09-10 15:16:15 updated: 2023-11-12 07:03:52 categories: 学习记录:网络协议 excerpt: 网络通信安全(ARP 欺骗,DoS DDoS,SYN 洪水攻击,LAND 攻击,DNS 劫持,HTTP 劫持)、密码技术(单向散列函数,对称加密,非对称加密,混合密码系统

    2024年01月24日
    浏览(34)
  • Win10文件夹共享(有密码的安全共享)(SMB协议共享)

    局域网内(无安全问题,比如自己家里wifi)无密码访问,参考之前的操作视频 【电脑文件全平台共享、播放器推荐】手机、电视、平板播放硬盘中的音、视频资源 下面讲解公共网络如办公室网络、咖啡厅网络等等环境下带密码的安全共享方式。 将插到电脑上的移动硬盘里面

    2024年04月14日
    浏览(46)
  • 7.6 密码设置与安全性分析(project)(安全意识)

    目录   第1关 随机生成一个n位密码 第2关 将随机生成的n位密码MD5加密 第3关 生成黑客密码字典 第4关 模拟碰撞破解MD5密码 第5关 检查密码是否泄漏 第1关  随机生成一个n位密码 本关任务:编写一个能随机生成一个n位密码的小程序。 1pass01.txt 1pass02.txt 1pass03.txt Linux密码中

    2024年02月01日
    浏览(85)
  • http协议为何不安全?教你使用抓包抓取到登录时输入的账号密码!

    大家可以发现,在2023年,基本上需要用户输入数据的网站都是使用https协议,简单来说就是比http更安全,使用了更高级的加密方式,即使部分网站使用http协议,用户输入数据也会使用哈希函数或者其他加密方式,http协议为什么不安全呢?我们不妨亲自抓包感受一下,自己输

    2024年02月07日
    浏览(26)
  • Shell脚本实现SFTP传输文件,通过密码形式

    cat 读取文件内容 grep server : 查找文件内容中包含server字符的,行内容 awk -F ‘=’ :实现字符串分割,分割字符’‘=’ ${print $2}: 其中$2 表示切割后数组中第几值 base -d :解码base64字符串,转为可识别字符串

    2024年02月12日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包