-
Notifications
You must be signed in to change notification settings - Fork 17
/
security.html
228 lines (219 loc) · 14.3 KB
/
security.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
<h1>Security Considerations</h1>
<section class="informative">
<h2>Guarantees</h2>
<p>This spec uses a <a target="aries"
href="https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0003-protocols/README.md#what-is-a-protocol">
protocol</a>, rather than a public oracle, as the root of trust. This protocol reliably communicates data
about peer DIDs and peer DID docs; peers must persist that data into a local cache or database that functions
as the <a target="didspec" href="https://w3c-ccg.github.io/did-spec/#dfn-dir">Decentralized Identifier
Registry</a> for the method. The method is worthy of trust because it guarantees the following properties:
</p>
<dl>
<dt>DIDs are associated with exactly one <a>inception key</a> pair at the moment of creation.</dt>
<dd>This prevents a category of man-in-the-middle attacks where an attacker could rotate a DID's keys
at the outset of a relationship, unbeknownst to peers. It also prevents any party other than the holder
of the inception key from using the DID in an unintended context.
</dd>
<dt>DIDs have an acceptable level of uniqueness.</dt>
<dd>This is NOT a guarantee that DIDs will never be improperly reused by their owner, NOR is it a guarantee that
collusion cannot subvert uniqueness. Thus, it is not a uniqueness upon which deep trust can be based.
Rather, it is a guarantee that good behavior will not produce accidental collisions. In this
sense, it is a bit like the uniqueness offered by NATing mechanisms in IPv4. It provides
enough uniqueness that a DID can be used as an index in a database or as a routing target
in DID communication. It also makes it possible for blockchains to <a href="#grafting">graft</a> a peer
DID by mapping it into their namespace, without incurring the risk of ambiguity. Any time a peer
DID is discovered to be less than unique, a true problem exists and systems can fairly
raise an exception.
</dd>
<dt>The values of DIDs are securely random.</dt>
<dd>This prevents attackers from discovering patterns in DIDs that might undermine privacy.
</dd>
<dt>Parties to a relationship can prove the orderly and authorized evolution of their
keys to one another, in an unbroken chain of custody stretching back to the moment of inception.</dt>
<dd>DIDs cannot be registered with any peer or any <a href="#grafting">grafting</a> ledger contrary to the
wishes of the DID controller(s). A peer DID can be shared out of context (e.g., observed and recorded by
an eavesdropper) -- but any reputable party will not accept a registration unless it's authorized by
a key with the <a>register</a> privilege.</dd>
</dl>
</section>
<section class="informative">
<h2>Enforcement</h2>
<p>In centralized systems, security is enforced at the center. This is so obvious that we take it for
granted—you can't access a database unless you log in first, and it's the database that enforces
this.
</p>
<p>Despite their other decentralized features, blockchains are no different in this respect. If a
blockchain accepts updates to a DID doc, then the blockchain must guarantee that those updates are
only made by authorized parties. Thus, most DID methods imagine a blockchain parsing the
authorization section of a DID doc, and rejecting mischief from hackers.
</p>
<p>However, in a peer relationship, there IS no centralized authority. This leads to an interesting
inversion of responsibility that must be understood: Bob enforces Alice's <a href="#authorization">
authorization policy</a>, and Alice enforces Bob's.
</p>
<p>This might seem wrong—shouldn't Alice enforce her own security? But it is quite rational. Who cares
whether the agents he is dealing with truly belong to Alice and are authorized by her? Bob does.
And if one of Alice's agents gets hacked and attempts to subvert the Alice:Bob relationship,
who is the uncontaminated party that can refuse to cooperate with the rogue agent? Bob is.
</p>
<p>Another way to think about this is that, within the Alice:Bob relationship, Bob acts as a substitute
for a centralized resource that Alice's agents try to access. In such a mental model, of course, Bob
would be a logical place to enforce access rules for Alice.
</p>
</section>
<section>
<h2>Secure communication</h2>
<p>All the messages in this protocol (except for a connection invitation that requires no security, by design)
must be sent encrypted, using the encryption format specified in <a target="aries"
href="https://github.com/hyperledger/aries-rfcs/blob/master/features/0019-encryption-envelope/README.md">
DIDComm's encryption envelope</a>. This gives strong guarantees about the confidentiality and integrity of
exchanged data, regardless of the transport mechanism used to transmit the messages.</p>
</section>
<section>
<h2>Proof of Control</h2>
<p>Because peer DIDs are generated from an <a href="#generation-method">algorithm</a> that includes the values of their initial public key(s)
as input, they cannot be created without the creator controlling them. As mentioned earlier, this prevents
man-in-the-middle attacks at the time of creation. A man-in-the-middle attacker might still try to exchange
the public key(s) in a DID Doc, while keeping the DID the same. If unnoticed, this would bind a DID generated
by an honest party to the attacker's public key(s). To prevent this, the receiver of a freshly generated peer
DID and DID Doc must verify that the DID was properly generated using the <a href="#generation-method">algorithm</a>.
This check is required when the received (DID, DID Doc) pair was not otherwise authenticated, which is the case
for the exchange request during <a href="#create-register">peer DID Exchange</a>.
</p>
</section>
<section>
<h2>Entropy</h2>
<p>
Since keys must be created from keys generated by a secure random number generator, they are guaranteed
to be unpredictable and globally unique at creation time.</p>
</section>
<section>
<h2>Key Management</h2>
<p>Keys used to control peer DIDs, or keys authorized to communicate and update the DID docs
for peer DIDs, should be managed according to best practices for DKMS, as described in
<a target="aries" href="https://github.com/hyperledger/aries-rfcs/blob/master/concepts/0051-dkms/dkms-v4.md">
the DKMS spec</a>. See the <a href="#static-and-key-rotation">note about key rotation and static-DID-only
support</a> in the <a href="#impl">Implementation section</a>.
</p>
<p><a target="sgl" href="https://evernym.github.io/sgl/docs/reference.html#rules">SGL rules</a> are powerful and
flexible, and should be used to implement best practices.</p>
</section>
<section>
<h2>Handling the trust-on-first-use (TOFU) problem</h2>
<p>
The trust-on-first-use is described in detail in its
<a target="wikipedia"
href="https://en.wikipedia.org/wiki/Trust_on_first_use">Wikipedia
article</a>. In brief, the TOFU problem occurs because it's not possible
to verify on receipt of a public key, who is the owner of the
corresponding private key. This lack of knowledge enables Man in the
Middle (MITM) attacks, where an attempt to establish a connection
between two participants is compromised by a third party. With peer:did,
the interaction most vulnerable to MITM attacks is when an invitation is
sent in plaintext to start the establishment of a connection. Recall
that a plaintext invitation (a URL, a QR code, etc.) is needed when
there is no way for two parties that want to connect to send an
encrypted message. A relatively simple MITM attack using an intercepted
invitation is for the MITM to respond to the invitation and establish a
connection with the inviter, pretending to be the invitee. In a more
sophisticated attack, the MITM sends a second, replacement
MITM-generated invitation to the intended invitee, establishes a
connection with that party, responds to the original invitation, and
establishes a connection with the inviter. That second attack example
could allow the MITM to remain between the two communicating parties,
proxying messages between them, and intervening when it is advantageous.
Since it is such a complex attack, it is viewed as extremely unlikely
(arguably, impossible) to occur in practice.
</p>
<p>
There are two common approaches to handling the TOFU problem with
connections established using the peer DID method specification. One is
to verify the connection using a trusted third party channel, and the second
is through the use of verifiable credentials.
</p>
<p>
Note that in many use cases, an entity might not care who responds to an
invitation. In that case an "intercepted" invitation is OK, and might
even be encouraged as a way to get more connections. For example a
service where users only put in data for their own use (for example, a
time tracking app) would not care who establishes a connection, just
that the service has a reliable way to know whenever an entity returns
to the service. In that case, neither verification method is necessary.
It might only be when the user becomes a paying client that the service
needs stronger credentials from whomever it is that is using the service.
</p>
</section>
<section>
<h3>Verification Using a Trusted Third Party Channel</h3>
<p>
Verifying that the established connection is with the intended party
using a trusted third party channel is done by sending a request by
some means other than the newly established connection, and having
the response returned on (or about) the established connection. For
example, after establishing the connection, the inviter might
telephone the invitee and verbally confirm the public key the
invitee is using for the connection. Of course, such an approach is
neither user friendly, nor does it scale. The challenge is finding
approaches that are reliable, easy and that scale. Another approach
might be to email a message to the invitee and have them respond via
the new connection with a phrase from the email. While that approach
would detect the first example MITM attack (described above), it would
not detect the second.
</p>
<p>
The user experience can be improved as well using a <a target="superuser" href="https://superuser.com/questions/22535/what-is-randomart-produced-by-ssh-keygen">randomart image</a> generated from a public key while being able to detect both the first and second MITM attack examples. This image could be sent in numerous ways such as embedding it in a qr code, sending it over a email, or text message would also work.
</p>
</section>
<section>
<h3>Using Verifiable Credentials</h3>
<p>
The use of <a target="W3C"
href="https://www.w3.org/TR/vc-data-model/">verifiable credentials</a>
is another way to verify a connection. With the connection in place, one
party requests from the other a verifiable presentation of third party
claims made about them. The requested claims should be sufficient to
mitigate the risk for the transactions to be carried out using the
connection, possibly including (but not just) the detection of a MITM
attack. Note that such risk mitigation should be done by both connected
parties. For example, a company might need to know some identity
information about a new client, and the new client might want to be
certain that the company is who they claim to be as attested to by an
authorized entity.
</p>
<p>
The presentation of verifiable claims is sufficient
to handle the first example MITM attack—the presentation
provides sufficient information about the other entity to continue
the relationship. However, because in the second example, the MITM
can proxy the presentation request and presentation between the
parties, a verifiable presentation might not be sufficient to detect
the second MITM example. In that case, we also want proof that the
entity that delivered the presentation is the same entity that
constructed the presentation. Since in the case of did:peer the
delivery is by definition through a did:peer enabled connection,
that extra proof involves linking the construction of the
presentation to the connection through which it will be delivered.
</p>
<p>
This extra proof can be achieved by having the entity constructing the
presentation include a self-attested claim that is the did:peer
public key of the prover. When the presentation is received, the
verifier can compare the signed, self-attested claim with the one
they are holding in the did:peer DIDDoc for the connection. If they
do not match it is possible there has been a MITM attack and the
connection is suspect.
</p>
<p>
Note: In the current (as of July 2019) implementation of Hyperledger
Indy, a self-attested claim in a presentation is not signed, and as
such, this approach is not foolproof. As the probability of this attack
is extremely low, and the signing of self-attested claims will soon be
added to Indy to align with with the (hopefully) soon-to-be-accepted W3C
verifiable presentation standard, this is deemed a low priority update
to the current version of Indy. The priority of the change may be
increased if the practical likelihood of this attack is found to be
significant. With the verifiable credential presentations model still in
flux, other verifiable credential implementations may or may not have
comparable issues.
</p>
</section>