![]() |
Show Changes |
![]() |
Edit |
![]() |
|
![]() |
Recent Changes |
![]() |
Subscriptions |
![]() |
Lost and Found |
![]() |
Find References |
![]() |
Rename |
| Search |
History
| 5/4/2005 9:13:24 AM |
![]() |
List all versions |
In security circles, we often talk about an acronym called CIA, which is normally taken to mean confidentiality, integrity, and availability. But when talking about securing application communications on a network, I prefer to think of the A as authentication because not enough people understand how important it is. For example, when was the last time you paid attention to your browser when purchasing something online? Did you check to make sure you were running over SSL? I find it interesting that when I hover my mouse over the lock in Internet Explorer, I'm told that it's using "128-bit encryption." Sadly, that information is of little use. What I really need to know is who is on the other end of the pipe, anyway? I can use the strongest encryption known to man, but if the guy on the other end of the wire is my enemy, what's the point? I can double-click that little lock icon to view the server's certificate and find out the name of the server that my browser just authenticated using SSL, but it would sure be nice if my browser would put more emphasis on the identity of the server as opposed to the length of the encryption key.
We place way too much emphasis on the C in CIA. Sure, encryption is important, but isn't integrity protection and authentication even more important? For example, if an attacker is able to modify packets from an authenticated user or, worse yet, inject his own packets and make us think they come from an authenticated user, isn't that more ominous? In most threat models, this is a much more dangerous attack. Given the choice between the two evils, I'd guess that your bank would much prefer an attacker to be able to eavesdrop on your money transfers than to be able to change the account numbers on the wire. Oh, and let me dispel the common myth that if you're encrypting data, you're automatically integrity-protecting it. Not so. Depending on the cipher and the way it's used (the "mode"), an attacker may be able to easily make predictable modifications to the plaintext by modifying the ciphertext. And these changes won't be detected by the decryption algorithm. In many cases, the attacker can flip individual bits in the ciphertext, and the corresponding bits in the plaintext stream will be flipped. This can be used to change account numbers or amounts in a banking transaction, for example!
Let's talk about the I in CIA for a moment. We need to be able to integrity-protect each packet. What this means is that we want to ensure that it's not modified in transit or fabricated out of thin air by an attacker. Looking at the overall network conversation, we don't want packets being reordered, reflected back to their source, or otherwise replayed without our being able to detect it. We also prefer not to have packets deleted, although if our networking peer is utterly silent it may be tough to know whether this is because of a denial-of-service attack or because she stepped out for coffee.
A key technique used for ensuring packet integrity is called a message authentication code, or MAC for short. There are lots of ways of constructing a MAC, but the idea is always the same. We want Alice and Bob (our network peers) to be able to compute a secure checksum of the message that nobody else can compute. Take a cryptographic hash, such as SHA1. Alone, it can't be used as a MAC because anyone can compute it. Alice can hash her message and send the message and the resulting hash code to Bob, and Bob can hash the message he receives and compare it with the hash value he received on the wire. If the hash values match, what does he know? Pretty much nothing because anyone can compute the hash of a set of bits. An attacker could have modified Alice's message and recomputed the hash, or simply sent his own message with a hash. No secret is required for this computation.
On the other hand, we could have Alice run a block encryption algorithm over the message. Block ciphers operate on small chunks of plaintext (16 bytes per block in most modern ciphers), so nontrivial plaintext messages are first broken up into blocks; then each block is encrypted individually. This is known as Electronic Codebook mode (ECB). Each block of ciphertext is calculated independently of the others. But other, more interesting modes exist. For example, in Cipher Block Chaining mode (CBC), before encrypting a block of plaintext we XOR the previous block of ciphertext into it, thus creating something like a feedback loop. For our purposes (constructing a MAC), we really don't care about any of the ciphertext except for the last block, which ends up being a unique residue1 formed from all the bits of the message plus the encryption key (that we assume the attacker doesn't know). So the last block of ciphertext, typically 16 bytes, becomes the MAC that can be sent with the message (see Figure 58.1). If we assume that Alice and Bob share the secret key used to form the MAC, when Bob receives the plaintext message and the MAC he can perform the same operation Alice did, using the message he received and the key he already knows. He can then compare the MAC that he computed with the MAC that arrived with the message. This technique is known as CBC-MAC. You see, an attacker who doesn't know the key can't compute the MAC, so if she modifies a packet or tries to inject her own, she won't be able to compute a MAC that's acceptable to Bob because she doesn't know the key. And with a 16-byte block size (128 bits), it would take the attacker an enormous number of guesses to find the correct MAC.2

Figure 58.1 CBC-MAC using AES encryption
A totally different approach to forming a MAC is to use a hash algorithm instead of an encryption algorithm. This is known as an HMAC. In a nutshell, Alice hashes a secret key concatenated with the message she wants to send to Bob. She then concatenates her key with the resulting hash and hashes again to avoid what is known as a length extension attack (Ferguson and Schneier 2003). Figure 58.2 illustrates the idea with the SHA-256 hash algorithm, which results in a 256 bit MAC. When used properly, this is a highly secure way to integrity-protect data. The .NET Framework supports HMAC-SHA1, which provides a 128-bit MAC via the HMACSHA1 class.

Figure 58.2 HMAC-SHA-256 in action
So, in order to provide C and I over a network connection between Alice and Bob, they need to share some secrets. Generally, sharing four secrets is a good idea (Ferguson and Schneier 2003):
* MAC key for messages sent from Alice to Bob
* MAC key for messages sent from Bob to Alice
* Encryption key for messages sent from Alice to Bob
* Encryption key for messages sent from Bob to Alice
All four secrets can be derived from a single secret that Alice and Bob share, which is typically known as the "session key" for their connection. But how do they discover this magical session key? This is where the A comes in! A network authentication protocol is really about two things. First, it allows Alice and Bob to develop trust in each other's identity (Alice gets cryptographic proof that her network peer is actually Bob, and vice versa). Second, it allows Alice and Bob to exchange a session key that can be used to provide the properties of CIA for their ensuing conversation. With these properties in place, we say that Alice and Bob have established a secure channel.
How does authentication work? That's the tricky part. Except in the unlikely event that Alice and Bob have met in some private place and exchanged a master key (for example, a passphrase), they'll need help from a third party who can vouch for the other's identity. This third party is known as an authority. WhatIsKerberos talks about one type of authority, known as a Kerberos key distribution center, or KDC. Another type is a certificate authority, or CA, that issues digital certificates to parties who need to authenticate with each other.
The most natural form of authenticated key exchange on Windows is Kerberos, and each domain controller running Windows 2000 or greater hosts a Kerberos authority. Support for Kerberos is also provided by most of the built-in Windows networking substrates, including named pipes, RPC, and DCOM. These subsystems use an abstraction layer known as the Security Support Provider Interface (SSPI, WhatIsSSPI) to authenticate and implement a secure channel. SSPI can also be used directly by third parties building their own networking plumbing.
To summarize, in order to provide the properties of confidentiality, integrity, and authentication for a network connection, we first must perform an authenticated key exchange using a protocol such as Kerberos. Then, for each message we must calculate a MAC over the plaintext, appending it to the message. Finally we must encrypt the message. The receiver should decrypt the message and verify the attached MAC. The MAC and encryption keys should be derived from the session key that was exchanged during authentication.
The goal of this item isn't to make you think you can run off and implement your own secure channel from scratch. There's not nearly enough detail here for that (for example, I didn't discuss any protections against replay attacks). My goal instead is to give you a basic introduction to the ideas behind secure network communication. I want you to know what it means to integrity protect a message. Once you have an inkling of how this works, you might feel more comfortable actually using these features when they're available. For an example, look at the COM authentication levels in WhatIsTheCOMAuthenticationLevel. If you're really on fire for this stuff and want to learn more about what it takes to implement a real secure channel, refer to Ferguson and Schneier (2003).
1 Whereas collisions are technically possible, they're highly unlikely (and computationally infeasible to force) if the block size of the algorithm is large enough.
2 The .NET Framework does have an implementation of CBC-MAC based on TripleDES, named MACTripleDES, but please don't use it because of the small block size that both DES and TripleDES use (only 8 bytes, or 64 bits). You don't want a MAC that small!
Keith's first book-in-a-wiki. If you would like to read the book online or order a physical copy to throw at annoying coworkers, surf to the HomePage. Please note that due to overwhelming wikispam, this particular wiki is no longer editable.
About FlexWiki.
Recent Topics