【Proverif语法(五)】

握手协议的保密性和认证性

event acceptsClient(key):客户端接受了【使用收到的key和服务器交互】这件事。
event acceptsServer(key,pkey):服务器接受了【使用key和公钥为pkey的客户端交互】这件事。
event termClient(key,pkey):客户端认为已经完成了【使用key为会话密钥以及pkey作为客户端公钥,和服务器运行协议】这件事。
event termServer(key):服务器认为已经完成了【使用key作为会话密钥,和客户端运行协议】这件事。
对客户端A而言,她只想和服务器B分享自己的加密信息,所以如果他执行完协议,B对A的认证就应该保持。
对服务器B而言,他可以和很多客户端交互,所以在运行完协议之后,如果B认为A是他的对话者(pkX==pkA),那么A对B的认证就应该保持。

关于 Correspondence assertions

query event ( evCocks ) ==> event (evRSA ) is true if and only if, for all executions of the protocol, if the event evCocks has been executed, then the event evRSA has also been executed before.

关于 Injective correspondence

我们刚才讨论的通信定义不足以在需要每个参与者执行的协议运行数之间的一对一关系的情况下捕获身份验证。例如,考虑服务器请求来自客户端的支付的金融交易;对于客户端启动的每个事务,服务器应该只完成一次事务(如果不是这样的话,那么客户机可能要为多个事务收费,即使客户机只启动了一个事务。)对于访问控制和其他场景,情况类似。单射对应断言捕获一对一关系并表示为:
在这里插入图片描述在这里插入图片描述

握手协议的保密性和认证性(例子)
(*握手协议的保密性和认证性*)
free c:channel.

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,k:skey;adec(aenc(m,pk(k)),k)=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.
(*签名、检查签名*)

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

event acceptsClient(key).
event acceptsServer(key,pkey).
event termClient(key,pkey).
event termServer(key).
(*这里的【A认为】意思就是A所接收到的信息表明了这件事,因此可以声明如下这些事件:*)
(*客户端接受了【使用收到的key和服务器交互】这件事;*)
(*服务器接受了【使用key和公钥为pkey的客户端交互】这件事;*)
(*客户端认为已经完成了【使用key为会话密钥以及pkey作为客户端公钥,和服务器运行协议】这件事;*)
(*服务器认为已经完成了【使用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)). 
(*这个意思是 ==>之后的 acceptsClient(x)的发生次数大于等于==>之前的termServer(x)的发生次数的。另外要注意, ==>之前写inj−event或者写event都行,只有箭头之后写什么才重要。*)

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
	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);
	out(c,aenc(sign((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))))

运行结果:

D:\proverif2.02pl1>proverif session3.pv
Process 0 (that is, the initial process):
{1}new skA: skey;
{2}new skB: sskey;
{3}let pkA: pkey = pk(skA) in
{4}out(c, pkA);
{5}let pkB: spkey = spk(skB) in
{6}out(c, pkB);
(
    {7}!
    {8}let skA_1: skey = skA in
    {9}out(c, pkA);
    {10}in(c, x: bitstring);
    {11}let y: bitstring = adec(x,skA_1) in
    {12}let (=pkB,k: key) = checksign(y,pkB) in
    {13}event acceptsClient(k);
    {14}out(c, senc(s,k));
    {15}event termClient(k,pkA)
) | (
    {16}!
    {17}let skB_1: sskey = skB in
    {18}in(c, pkX: pkey);
    {19}new k_1: key;
    {20}event acceptsServer(k_1,pkX);
    {21}out(c, aenc(sign((pkB,k_1),skB_1),pkX));
    {22}in(c, x_1: bitstring);
    {23}let z: bitstring = sdec(x_1,k_1) in
    {24}if (pkX = pkA) then
    {25}event termServer(k_1)
)

--  Process 1 (that is, process 0, with let moved downwards):
{1}new skA: skey;
{2}new skB: sskey;
{3}let pkA: pkey = pk(skA) in
{4}out(c, pkA);
{5}let pkB: spkey = spk(skB) in
{6}out(c, pkB);
(
    {7}!
    {9}out(c, pkA);
    {10}in(c, x: bitstring);
    {8}let skA_1: skey = skA in
    {11}let y: bitstring = adec(x,skA_1) in
    {12}let (=pkB,k: key) = checksign(y,pkB) in
    {13}event acceptsClient(k);
    {14}out(c, senc(s,k));
    {15}event termClient(k,pkA)
) | (
    {16}!
    {18}in(c, pkX: pkey);
    {19}new k_1: key;
    {20}event acceptsServer(k_1,pkX);
    {17}let skB_1: sskey = skB in
    {21}out(c, aenc(sign((pkB,k_1),skB_1),pkX));
    {22}in(c, x_1: bitstring);
    {23}let z: bitstring = sdec(x_1,k_1) in
    {24}if (pkX = pkA) then
    {25}event termServer(k_1)
)

-- Query not attacker(s[]) in process 1.
Translating the process into Horn clauses...
Completing...
Starting query not attacker(s[])
goal reachable: attacker(s[])

Derivation:
Abbreviations:
k_2 = k_1[pkX = pk(k_3),!1 = @sid]

1. The message spk(skB[]) may be sent to the attacker at output {6}.
attacker(spk(skB[])).

2. The attacker has some term k_3.
attacker(k_3).

3. By 2, the attacker may know k_3.
Using the function pk the attacker may obtain pk(k_3).
attacker(pk(k_3)).

4. The message pk(k_3) that the attacker may have by 3 may be received at input {18}.
So the message aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3)) may be sent to the attacker at output {21}.
attacker(aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3))).

5. By 4, the attacker may know aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3)).
By 2, the attacker may know k_3.
Using the function adec the attacker may obtain sign((spk(skB[]),k_2),skB[]).
attacker(sign((spk(skB[]),k_2),skB[])).

6. By 5, the attacker may know sign((spk(skB[]),k_2),skB[]).
By 1, the attacker may know spk(skB[]).
Using the function checksign the attacker may obtain (spk(skB[]),k_2).
attacker((spk(skB[]),k_2)).

7. By 6, the attacker may know (spk(skB[]),k_2).
Using the function 2-proj-2-tuple the attacker may obtain k_2.
attacker(k_2).

8. The message pk(skA[]) may be sent to the attacker at output {4}.
attacker(pk(skA[])).

9. By 5, the attacker may know sign((spk(skB[]),k_2),skB[]).
By 8, the attacker may know pk(skA[]).
Using the function aenc the attacker may obtain aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[])).
attacker(aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[]))).

10. The message aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[])) that the attacker may have by 9 may be received at input {10}.
So the message senc(s[],k_2) may be sent to the attacker at output {14}.
attacker(senc(s[],k_2)).

11. By 10, the attacker may know senc(s[],k_2).
By 7, the attacker may know k_2.
Using the function sdec the attacker may obtain s[].
attacker(s[]).

12. By 11, attacker(s[]).
The goal is reached, represented in the following fact:
attacker(s[]).


A more detailed output of the traces is available with
  set traceDisplay = long.

new skA: skey creating skA_2 at {1}

new skB: sskey creating skB_2 at {2}

out(c, ~M) with ~M = pk(skA_2) at {4}

out(c, ~M_1) with ~M_1 = spk(skB_2) at {6}

out(c, ~M_2) with ~M_2 = pk(skA_2) at {9} in copy a

in(c, pk(a_1)) at {18} in copy a_2

new k_1: key creating k_2 at {19} in copy a_2

event acceptsServer(k_2,pk(a_1)) at {20} in copy a_2

out(c, ~M_3) with ~M_3 = aenc(sign((spk(skB_2),k_2),skB_2),pk(a_1)) at {21} in copy a_2

in(c, aenc(adec(~M_3,a_1),~M)) with aenc(adec(~M_3,a_1),~M) = aenc(sign((spk(skB_2),k_2),skB_2),pk(skA_2)) at {10} in copy a

event acceptsClient(k_2) at {13} in copy a

out(c, ~M_4) with ~M_4 = senc(s,k_2) at {14} in copy a

event termClient(k_2,pk(skA_2)) at {15} in copy a

The attacker has the message sdec(~M_4,2-proj-2-tuple(checksign(adec(~M_3,a_1),~M_1))) = s.
A trace has been found.
RESULT not attacker(s[]) is false.
-- Query event(termClient(x_2,y_1)) ==> event(acceptsServer(x_2,y_1)) in process 1.
Translating the process into Horn clauses...
Completing...
Starting query event(termClient(x_2,y_1)) ==> event(acceptsServer(x_2,y_1))
goal reachable: begin(acceptsServer(k_2,pk(k_3))) && attacker(k_3) -> end(termClient(k_2,pk(skA[])))
Abbreviations:
k_2 = k_1[pkX = pk(k_3),!1 = @sid]

Derivation:
Abbreviations:
k_2 = k_1[pkX = pk(k_3),!1 = @sid]

1. The message pk(skA[]) may be sent to the attacker at output {4}.
attacker(pk(skA[])).

2. We assume as hypothesis that
attacker(k_3).

3. By 2, the attacker may know k_3.
Using the function pk the attacker may obtain pk(k_3).
attacker(pk(k_3)).

4. The message pk(k_3) that the attacker may have by 3 may be received at input {18}.
The event acceptsServer(k_2,pk(k_3)) may be executed at {20}.
So the message aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3)) may be sent to the attacker at output {21}.
attacker(aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3))).

5. By 4, the attacker may know aenc(sign((spk(skB[]),k_2),skB[]),pk(k_3)).
By 2, the attacker may know k_3.
Using the function adec the attacker may obtain sign((spk(skB[]),k_2),skB[]).
attacker(sign((spk(skB[]),k_2),skB[])).

6. By 5, the attacker may know sign((spk(skB[]),k_2),skB[]).
By 1, the attacker may know pk(skA[]).
Using the function aenc the attacker may obtain aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[])).
attacker(aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[]))).

7. The message aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[])) that the attacker may have by 6 may be received at input {10}.
So event termClient(k_2,pk(skA[])) may be executed at {15}.
end(termClient(k_2,pk(skA[]))).

8. By 7, end(termClient(k_2,pk(skA[]))).
The goal is reached, represented in the following fact:
end(termClient(k_2,pk(skA[]))).


A more detailed output of the traces is available with
  set traceDisplay = long.

new skA: skey creating skA_2 at {1}

new skB: sskey creating skB_2 at {2}

out(c, ~M) with ~M = pk(skA_2) at {4}

out(c, ~M_1) with ~M_1 = spk(skB_2) at {6}

out(c, ~M_2) with ~M_2 = pk(skA_2) at {9} in copy a

in(c, pk(a_1)) at {18} in copy a_2

new k_1: key creating k_2 at {19} in copy a_2

event acceptsServer(k_2,pk(a_1)) at {20} in copy a_2

out(c, ~M_3) with ~M_3 = aenc(sign((spk(skB_2),k_2),skB_2),pk(a_1)) at {21} in copy a_2

in(c, aenc(adec(~M_3,a_1),~M)) with aenc(adec(~M_3,a_1),~M) = aenc(sign((spk(skB_2),k_2),skB_2),pk(skA_2)) at {10} in copy a

event acceptsClient(k_2) at {13} in copy a

out(c, ~M_4) with ~M_4 = senc(s,k_2) at {14} in copy a

event termClient(k_2,pk(skA_2)) at {15} in copy a (goal)

The event termClient(k_2,pk(skA_2)) is executed at {15} in copy a.
A trace has been found.
RESULT 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)) in process 1.
Translating the process into Horn clauses...
Completing...
Starting query inj-event(termServer(x_2)) ==> inj-event(acceptsClient(x_2))
goal reachable: begin(acceptsClient(k_2),@occ13_1) -> end(@occ25_1,termServer(k_2))
The hypothesis occurs strictly before the conclusion.
Abbreviations:
k_2 = k_1[pkX = pk(skA[]),!1 = @sid]
@occ25_1 = @occ25[x_1 = senc(s[],k_2),pkX = pk(skA[]),!1 = @sid]
@occ13_1 = @occ13[x = aenc(sign((spk(skB[]),k_2),skB[]),pk(skA[])),!1 = @sid_1]
RESULT inj-event(termServer(x_2)) ==> inj-event(acceptsClient(x_2)) is true.

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

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

  • Query not attacker(s[]) is false. 通过中间人攻击,s可能会泄露;

  • Query event(termClient(x_2,y_1)) ==> event(acceptsServer(x_2,y_1)) is
    false.
    ClientA认为自己已经和serverB走完了协议流程,但和ClientA走完流程的不一定是serverB,因为有中间人攻击,它可以冒充serverB

  • Query inj-event(termServer(x_2)) ==> inj-event(acceptsClient(x_2)) is
    true.
    serverB认为自己和某个ClientX走完了协议,即至少有一个客户端和自己完成了这个协议。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值