‘‘secure’’ communication
mostly talk about on network
between principals \(\approx\) people/servers/programs
but same ideas apply to, e.g., messages on disk
running example: A talking with B
attacker E — eavesdropper
attacker M — machine-in-the-middle
intercept radio signal?
control local wifi router?
compromise network equipment?
send packets with ‘wrong’ source address
fool DNS servers to ‘steal’ name?
fool routers to send you other’s data?
important ones we won’t talk about…:
repudiation — if A sends message to B, B can’t prove to C it came from A
forward-secrecy — if A compromised now, E can’t use that to decode past conversations with B
anonymity — A can talk to B without B knowing who it is
…
if A is talking to B are communicating,
what stops M (machine-in-the-middle) from pretending to be B?
assumption: B knows some secret information that M does not
start: assume A and B have a shared secret they both know
(later: easier to setup assumptions)
A \(\rightarrow\) B: What’s the password?
B \(\rightarrow\) A: It’s ‘Abc$xyM$e’.
A \(\rightarrow\) B: That’s right! Here’s my confidential information.
well, this doesn’t really help:
some magic math!
we’ll be given two functions by expert:
key = shared secret
our functions:
knowing \(E\) and \(D\), it should be hard to
learn anything about the message from the ciphertext without key
‘‘hard’’ \(\approx\) would have to try every possible key
in this class, (symmetric) encryption means confidentiality but not authenticity
key.matches most common thing a library calls encryption
but, sometimes encryption will be ‘‘authenticated encryption’’
goal: use shared secret key to verify message origin
one function: \(MAC(\text{key}, \text{message}) = \text{tag}\)
knowing \(MAC\) and the message and the tag, it should be hard to:
message authentication code acts like checksum, but…
checksum can be recomputed without any key
checksum meant to protect against accidents, not malicious attacks
in advance: choose + share MAC key
A prepares message:
A \(\rightarrow\) B: Please pay $100 to M. @@@
B processes message:
in advance: choose + share encryption key and MAC key
A prepares message:
A \(\rightarrow\) B: *** @@@
B processes message:
suppose A, B have shared keys \(K_1,K_2\)
E/D = encrypt/decrypt function
A asks B to pay Sue $100 by sending message with these parts:
problem: shared secrets usually aren’t practical
need secure communication before I can do secure communication?
scaling problems
want to avoid needing to pre-share secret keys
but, ok making some sacrifices:
confidentiality in only one direction
slower performance
we’ll have two functions:
(public key, private key) = ‘‘key pair’’
‘private key’ = kept secret
‘public key’ = safe to give to everyone
functions:
should have:
not going to be able to make things as hard as ‘‘try every possible private key’’
but going to make it impractical
like with symmetric encryption want to prevent recovery of any info about message
also have some other attacks to worry about:
both:
asymmetric (AKA public-key) encryption
symmetric encryption
symmetric encryption : asymmetric encryption ::
message authentication codes : digital signatures
pair of functions:
(public key, private key) = key pair
have building blocks, but less than straightforward to use
lots of issues from using building blocks poorly
start of art solution: formal proof sytems
(we aren’t going to be that formal…)
A\(\rightarrow\)B: Did you order lunch? [signature 1 by A]
B\(\rightarrow\)A: Yes. [signature 1 by B]
A\(\rightarrow\)B: Vegetarian? [signature 2 by A]
B\(\rightarrow\)A: No, not this time. [signature 2 by B]
…
A\(\rightarrow\)B: There’s a guy at the door, says he’s here to repair the AC. Should I let him in? [signature \(N\) by A]
since attacker can’t forge signed messages, everything’s okay?
A\(\rightarrow\)B: Did you order lunch? [signature 1 by A]
B\(\rightarrow\)A: Yes. [signature 1 by B]
A\(\rightarrow\)B: Vegetarian? [signature 2 by A]
B\(\rightarrow\)A: No, not this time. [signature 2 by B]
…
A\(\rightarrow\)B: There’s a guy at the door, says he’s here to repair the AC. Should I let him in? [signature \(N\) by A]
how can attacker hijack the reponse to A’s inquiry?
as an attacker, I can copy/paste B’s earlier message!
one solution to replay attacks:
A\(\rightarrow\)B: #1 Did you order lunch? [signature 1 from A]
B\(\rightarrow\)A: #1 Yes. [signature 1 from B]
A\(\rightarrow\)B: #2 Vegetarian? [signature 2 from A]
B\(\rightarrow\)A: #2 No, not this time. [signature 2 from B]
…
A\(\rightarrow\)B: #54 There’s a guy at the door, says he’s here to repair the AC. Should I let him in? [signature \(N\) from A]
(assuming A actually checks the numbers)
M\(\rightarrow\)B: #54 Did you order lunch? [signature by M]
B\(\rightarrow\)M: #54 Yes. [signature intended for M by B]
A\(\rightarrow\)B: #54 There’s a guy at the door, says he’s here to repair the AC. Should I let him in? [signature \(N\) by A]
how can M hijack the response to A’s inquiry?
as an attacker, I can copy/paste B’s earlier message!
protocol:
attack:
if A asks B for B’s public key, M could send M’s key instead
could try to verify somehow
let’s say A has B’s public key already.
if C wants B’s public key and knows A’s already:
A can generate a ‘‘certificate’’ certifying B’s public key:
B sends a copy of this ‘‘certificate’’ to C
if C trusts A, now C has B’s public key
websites (and others) go to certificates authorities (CA) with their public key
certificate authorities sign messages like:
‘‘The public key for foo.com is XXX.’’
signed message called certificate
browsers use the certificates to verify website identity
Version: 3 (0x2)
Serial Number: 7b:df:f6:ae:2e:d7:db:74:d3:c5:77:ac:bc:44:bf:1b
Signature Algorithm: sha256WithRSAEncryption
Issuer:
countryName = US
stateOrProvinceName = MI
localityName = Ann Arbor
organizationName = Internet2
organizationalUnitName = InCommon
commonName = InCommon RSA Server CA
Validity
Not Before: Apr 25 00:00:00 2023 GMT
Not After : Apr 24 23:59:59 2024 GMT
Subject:
countryName = US
stateOrProvinceName = Virginia
organizationName = University of Virginia
commonName = canvas.its.virginia.edu
....
X509v3 extensions:
....
X509v3 Subject Alternative Name: DNS:canvas.its.virginia.edu
....
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:a2:fb:5a:fb:2d:d2:a7:75:7e:eb:f4:e4:d4:6c:
94:be:91:a8:6a:21:43:b2:d5:9a:48:b0:64:d9:f7:
f1:88:fa:50:cf:d0:f3:3d:8b:cc:95:f6:46:4b:42:
....
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
24:3a:67:c8:0d:ef:eb:8c:eb:ba:8f:d5:11:d2:1e:ea:44:eb:
fe:af:93:7d:d9:4a:2b:44:a3:7f:47:50:aa:d1:b3:9c:a8:a8:
....
canvas.its.virginia.edu has a valid certificate
but, why do we trust that certificate?
well, their certificate is signed by ‘‘USERTrust RSA Certification Authority’’
ok, but why do we trust their certificate?
trusted public keys hardcoded in OS/browser
Mozilla Firefox (as of 27 Feb 2023)
Microsoft Windows (as of 27 Feb 2023)
Google Chrome (as of 02 Apr 2025)
ecosystem with certificate authorities
and certificates for everyone
called ‘‘public-key infrastructure’’
several of these:
for web sites, set by CA/Browser Forum
organization of:
everyone who ships code with list of valid certificate authorities
certificate authorities
decide on rules (‘‘baseline requirements’’) for what CAs do
keep their private keys in tamper-resistant hardware
maintain publicly-accessible database of revoked certificates
certificate transparency
‘CAA’ records in the domain name system
digital signatures typically have size limit
… but we want to sign very large messages
solution: get secure ‘‘summary’’ of message
hash(M) = X
given X: hard to find message other than by guessing
given X, M: hard to find second message so that hash(second message) = X
example uses:
substitute for original message in digital signature
building message authentication codes
building tools for storing passwords/generating keys from passwords
example algorithm: SHA256
cryptographic hash functions need (basically) guessing to ‘reverse’
idea: store cryptographic hash of password instead of password
problem: with fast hash function, can try lots of guesses fast
fix: special slow/resource-intensive cryptograph hash functions
Linux kernel random number generator
collects ‘‘entropy’’ from hard-to-predict events
turned into as many random bytes as you want
problem: A has B’s public encryption key
wants to choose shared secret
some ideas:
TLS, SSH use special key agreement primitive instead
public/private-key-like:
key share = GenerateKeyShare(private value)
KeyGen(A’s private value, B’s key share) = new shared secret
KeyGen(B’s private value, A’s key share) = same shared secret
math providers gaurentee:
use key shares results to get several symmetric keys
separate keys for each direction (server \(\rightarrow\) client and vice-versa)
often separate keys for encryption and MAC
later messages use encryption + MAC + nonces
(not all these properties provided by all TLS versions and modes)
confidentiality/authenticity
forward secrecy
fast
communicating securely with math
protocol attacks — repurposing encrypt/signed/etc. messages
certificates — verifiable forwarded public keys
key agreement — for generated shared-secret ‘‘in public’’
have building blocks, but less than straightforward to use
lots of issues from using building blocks poorly
start of art solution: formal proof sytems
(we aren’t going to be that formal…)
protocol:
attack:
for web sites, set by CA/Browser Forum
organization of:
everyone who ships code with list of valid certificate authorities
certificate authorities
decide on rules (‘‘baseline requirements’’) for what CAs do
keep their private keys in tamper-resistant hardware
maintain publicly-accessible database of revoked certificates
certificate transparency
‘CAA’ records in the domain name system
cryptographic hash functions need (basically) guessing to ‘reverse’
idea: store cryptographic hash of password instead of password
problem: with fast hash function, can try lots of guesses fast
fix: special slow/resource-intensive cryptograph hash functions
can construct public-key encryption from key agreeement
private key: generated random value Y
public key: key share generated from that Y
PE(public key, message) =
PD(private key, message) =
work for attacker > work for defender
how much computation per message?
how much sent back per message?
resources for attacker > resources of defender
how many machines can attacker use?
instead of sending messages directly… attacker can send messages ‘‘from’’ you to third-party
third-party sends back replies that overwhelm network
example: short DNS query with lots of things in response
‘‘amplification’’ =
don’t want to expose network service to everyone?
solutions:
later two called ‘‘firewalls’’
find shorter ‘summary’ to substitute for data
deal with message limits in signatures/etc.
password hashing — but be careful! [next slide]
constructing message authentication codes
in addition to nonces, either
with symmetric encryption, also ‘‘reflection attacks’’
one example from https://nebuchadnezzar-megolm.github.io/static/paper.pdf
system for confidential multi-user chat
protocol + goals:
bug:
can construct public-key encryption from key agreeement
private key: generated random value Y
public key: key share generated from that Y
PE(public key, message) =
PD(private key, message) =
actually that’s not secret enough, usually want to resist
recovery of info about message or key even given…
partial info about the message, or
lots of other (message, ciphertext) pairs, or
lots of (message, ciphertext) pairs for other messages the attacker chooses, or
lots of (message, ciphertext) pairs encrypted under similar keys, or
…
suppose encrypting message
one possible idea: generate unique number N (e.g. counter)
combine N and key to produce message size-bit bitstring Y
say Y=f(X, key) where \(f\) is some ‘secure’ function:
use Y XOR message as encrypted value
E(K, message) = (N, f(N, key) XOR message) = (N, C)
If we know (N, C) and don’t know key, can we figure out anything about message?
If we know (N, C) and message, can we find out about key
If we know (N, C) and message, can we decrypt (N’, C’)?
as an active attacker
if we know part of plaintext
can sometimes make it read anything else by flipping bits
we can sometimes shorten
we can sometimes corrupt selected parts of message and check what the response is
these XOR-based constructions are very common
there are other ideas, but…
but can still generate meaningful manipulated messages
actual solution: additional message authentication code
A and B want to agree on shared secret
A chooses random value Y
A sends public value derived from Y (‘‘key share’’)
B chooses random value Z
B sends public value derived from Z (‘‘key share’’)
A combines Y with public value from B to get number
B combines Z with public value from A to get number
math requirement:
| A randomly chooses \(Y\) | B randomly chooses \(Z\) |
| A sends \(f(X, Y)\) to B | B sends \(f(X, Z)\) to A |
| A computes \(f(f(X, Z), Y)\) | B computes \(f(f(X, Y), Z)\) |