21 Securely Authenticating a MAC (Thwarting Capture Replay Attacks)
Tải bản đầy đủ  0trang spc_omac1_init(&c, k, 16);
if (*last_nonce) {
for (i = 0; i < 16; i++)
if (sent_nonce[i] > (*last_nonce)[i]) goto nonce_okay;
return 0; /* Nonce is equal to or less than last nonce. */
}
nonce_okay:
spc_omac_update(&c, sent_nonce, 16);
spc_omac_update(&c, ct, ctlen);
spc_omac_final(&c, calc_tag);
for (i = 0; i < 16; i++)
if (calc_tag[i] != sent_tag[i]) return 0;
if (sent_nonce) {
if (!*last_nonce) *last_nonce = (unsigned char *)malloc(16);
if (!*last_nonce) abort(); /* Consider an exception instead. */
memcpy(*last_nonce, sent_nonce, 16);
}
return 1;
}
This code requires you to pass in a char ** to track the last nonce that was received.
You’re expected to allocate your own char *, set it to NULL, and pass in the address of
that char *. The validate function will update that memory with the last valid nonce
it saw, so that it can check the new nonce against the last nonce to make sure it got
bigger. The function will return 1 if the MAC validates; otherwise, it will return 0.
See Also
Recipes 6.11, 6.12, 6.18
6.22 Parallelizing MACs
Problem
You want to use a MAC, but parallelize the computation.
Solution
Run multiple MACs at the same time, then MAC the resulting tags together (and in
order) to yield one tag.
Discussion
If you want to perform message authentication in parallel, you can do so with a variation of interleaving (which we discussed for block ciphers in Recipes 5.12 through
5.14) Basically, you can run multiple MACs keyed separately at the same time and
304

Chapter 6: Hashes and Message Authentication
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
divide up the data stream between those MACs. For example, you might run two
MACs in parallel and alternate sending 64 bytes to each MAC.
The problem with doing this is that your two MAC’s authentication values need to
be tied together; otherwise, someone could rearrange the two halves of your stream.
For example, if you were to MAC this message:
ABCDEFGHIJKL
where MAC 1 processed the first six characters, yielding tag A, and MAC 2 processed the final six, yielding tag B, an attacker could rearrange the message to be:
GHIJKLABCDEF
and report the tags in the reverse order. Authentication would not detect the change.
To solve this problem, once all the MACs are reported, MAC all the resulting tags to
create a composite MAC. Alternatively, you could take the last MAC context and
add in the MAC values for the other contexts before generating the tag, as illustrated
in Figure 68.
Original message
M1
MAC
M1
MAC
M2
M3
M4
M3
M2
M5
M5
M4
T1
T1
Output
Figure 68. Properly interleaving MACs
If your MAC accepts a nonce, you can use the same key for each context, as long as
you never reuse a {key, nonce} pair.
Here’s a simple sequential example that runs two OMAC1 contexts, alternating
every 512 bytes, that produces a single resulting tag of 16 bytes. It uses the OMAC1
implementation from Recipe 6.11.
#include
#define INTERLEAVE_SIZE 512
unsigned char *spc_double_mac(unsigned char *text, size_t len,
unsigned char key[16]) {
SPC_OMAC_CTX
ctx1, ctx2;
unsigned char *out = (unsigned char *)malloc(16);
unsigned char tmp[16];
if (!out) abort(); /* Consider throwing an exception instead. */
spc_omac1_init(&ctx1, key, 16);
spc_omac1_init(&ctx2, key, 16);
while (len > 2 * INTERLEAVE_SIZE) {
Parallelizing MACs  305
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
spc_omac_update(ctx1, text, INTERLEAVE_SIZE);
spc_omac_update(ctx2, text + INTERLEAVE_SIZE, INTERLEAVE_SIZE);
text += 2 * INTERLEAVE_SIZE;
len = 2 * INTERLEAVE_SIZE;
}
if (len > INTERLEAVE_SIZE) {
spc_omac_update(ctx1, text, INTERLEAVE_SIZE);
spc_omac_update(ctx2, text + INTERLEAVE_SIZE, len  INTERLEAVE_SIZE);
} else spc_omac_update(ctx1, text, len);
spc_omac_final(ctx1, tmp);
spc_omac_update(ctx2, tmp, sizeof(tmp));
spc_omac_final(ctx2, out);
return out;
}
See Also
Recipes 5.11, 6.12 through 6.14
306

Chapter 6: Hashes and Message Authentication
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
Chapter 7
CHAPTER 7
Public Key Cryptography
Many of the recipes in this chapter are too lowlevel for generalpurpose use. We recommend that you first try to find what you need in
Chapter 9 before resorting to building solutions yourself. If you do use
this chapter, please be careful, read all of our warnings, and do consider the higherlevel constructs we suggest.
Public key cryptography offers a number of important advantages over traditional, or
symmetric, cryptography:
Key agreement
Traditional cryptography is done with a single shared key. There are obvious
limitations to that kind of cryptography, though. The biggest one is the key
agreement problem: how do two parties that wish to communicate do so
securely? One option is to use a more secure outofband medium for transport,
such as telephone or postal mail. Such a solution is rarely practical, however,
considering that we might want to do business securely with an online merchant
we’ve never previously encountered. Public key cryptography can help solve the
key agreement problem, although doing so is not as easy as one might hope. We
touch upon this issue throughout this chapter and expand upon it in Chapter 8.
Digital signatures
Another useful service that public key cryptography can provide is digital signatures, which allow for message integrity checks without a shared secret. In a
symmetric environment with message authentication codes (MACs) for message
authentication, a user can determine that someone with the MAC key sent a particular message, but it isn’t possible to provide third parties any assurance as to
who signed a message (this ability is called nonrepudiation). That is, if Alice and
Bob exchange messages using a MAC, and somehow Charlie has been given a
copy of the message and the MAC key, Charlie will be able to determine only
that someone who had the MAC key at some point before him generated the
message. Using only symmetric cryptography, he cannot distinguish between
messages created by Alice and messages created by Bob in a secure manner.
307
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
Establishing identity
A third use of public key cryptography is in authentication schemes for purposes of identity establishment (e.g., login). We’ll largely skip this topic for now,
coming back to it in Chapter 8.
In practice, public key cryptography is a complex field with a lot of infrastructure
built around it. Using it effectively requires a trusted third party, which is usually a
public key infrastructure (PKI).
This entire chapter is effective only in the context of some kind of
working PKI, even if it is an ad hoc PKI. Refer to Chapter 10 for PKI
basics.
In this chapter, we’ll describe the fundamentals of key exchange and digital signatures at a low level. Unfortunately, this area is quite vast, and we’ve had to limit our
discussion to the topics we believe are most relevant to the average developer. We
expect that supplemental recipes for more esoteric topics will gradually become
available on this book’s web site, based on reader contributions.
There are certain interesting topics that we simply don’t have room for in this chapter. For example, elliptic curve cryptography is a type of public key encryption that
can offer security similar to that of the traditional algorithms presented in this chapter, with notable speed gains. While elliptic curve cryptography doesn’t speed things
up so much that you would want to use it in places where traditional public key
cryptography isn’t useful, it does allow you to better scale the number of simultaneous connections you can handle. While elliptic curve cryptography is a fascinating
and useful area, however, it’s not nearly as important as the rest of the material in
this chapter, particularly considering that standards and implementations for this
kind of public key cryptography have emerged only in the last few years, and that the
technology isn’t yet deployed on a wide scale (plus, there are intellectual property
issues when using the standard).
We’ve also limited our examples to OpenSSL whenever it supports the topic under
discussion. While we do cover Microsoft’s CryptoAPI in several other chapters side
by side with OpenSSL, we won’t be discussing it in this chapter. CryptoAPI’s support for public key cryptography is sufficiently crippled that providing solutions that
use it would be incomplete to the point of providing you with little or no utility. In
particular, CryptoAPI provides no means to exchange keys in any kind of recognized
portable format (such as DER or PEM; see Recipes 7.16 and 7.17) and no means by
which keys other than randomly generated ones can generate digital signatures.
These limitations effectively rule out a large portion of public key cryptography’s
common uses, which make up the majority of coderelated recipes in this chapter.
308

Chapter 7: Public Key Cryptography
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
The code presented in this chapter should otherwise translate easily to most other
functionally complete libraries. Again, in situations where this is not the case, we
expect that reader contributions will eventually mend this problem.
We expect that for most purposes, the generalpurpose networking
recipes provided in Chapter 9 are likely to be more applicable to the
average developer. Unless you really know what you’re doing, there is
significant risk of needing a prosthetic foot when using this chapter.
7.1
Determining When to Use Public Key
Cryptography
Problem
You want to know when to use public key cryptography as opposed to symmetric
cryptography.
Solution
Use public key cryptography only for key exchange or digital signatures. Otherwise,
there are a lot of disadvantages and things that can go wrong (particularly when
using it for generalpurpose encryption). Because public key operations are computationally expensive, limit digital signatures to authentication at connection time and
when you need nonrepudiation.
Whenever you use public key encryption, be sure to remember also to
perform proper authentication and message integrity checking.
Discussion
Public key cryptography allows parties to communicate securely without having to
establish a key through a secure channel in advance of communication, as long as a
trusted third party is involved. Therein lies the first rub. Generally, if you use public
key cryptography, you need to determine explicitly with whom you’re communicating, and you need to check with a trusted third party in a secure manner. To do that,
you will need to have identification data that is bound to your trusted third party,
which you’ll probably need to authenticate over some secure channel.
Figure 71 (A) illustrates why public key cryptography on its own does not provide
secure communication. Suppose the server has a {public key, private key} pair, and
the client wishes to communicate with the server. If the client hasn’t already securely
Determining When to Use Public Key Cryptography  309
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
obtained the public key of the server, it will need to request those credentials, generally over an insecure channel (e.g., over the Internet). What is to stop an attacker
from replacing the server’s credentials with its own credentials?
Then, when the client tries to establish a secure connection, it could actually be talking to an attacker, who may choose to either masquerade as the server or just sit in
the middle, communicating with the server on the client’s behalf, as shown in
Figure 71 (B). Such an attack is known as a maninthemiddle attack.
A
Request server credentials
Request server credentials
Send attacker credentials
Send server credentials
Attacker
Client
Server
B
Perceived traffic
Client
Server
Actual traffic
Actual traffic
Attacker
Figure 71. A maninthemiddle attack
Getting a server’s key over an insecure channel is okay as long as there is some way
of determining whether the key the client gets back is actually the right one. The
most common way of establishing trust is by using a PKI, a concept we explain in
Recipe 10.1.
Another issue when it comes to public key cryptography is speed. Even the fastest
public key cryptography that’s believed to be secure is orders of magnitude slower
than traditional symmetric encryption. For example, a Pentium class machine may
encrypt data using RC4 with 128bit keys at about 11 cycles per byte (the key size
isn’t actually a factor in RC4’s speed). The same machine can process data at only
about 2,500 cycles per byte when using an optimized version of vanilla RSA and
2,048bit keys (the decrypt speed is the limiting factor—encryption is usually about
20 times faster). True, versions of RSA based on elliptic curves can perform better,
but they still don’t perform well for generalpurpose use.
310

Chapter 7: Public Key Cryptography
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
Because public key encryption is so expensive, it is only really useful for processing
small pieces of data. As a result, there are two ways in which public key cryptography
is widely used: key exchange (done by encrypting a symmetric encryption key) and digital signatures (done by encrypting a hash of the data to sign; see Recipes 7.12, 7.13
and 7.15).
When using digital signatures for authentication, a valid signature on a piece of data
proves that the signer has the correct secret key that corresponds to the public key
we have (of course, we then need to ensure that the public key really does belong to
the entity we want to authenticate). The signature also validates that the message
arrived without modification. However, it’s not a good idea to use digital signatures
for all of our message integrity needs because it is incredibly slow. You essentially
need public key cryptography to provide message integrity for a key exchange, and
while you’re doing that, you might as well use it to authenticate (the authentication
is often free). However, once you have a symmetric key to use, you should use MACs
to provide message integrity because they’re far more efficient.
The only time it makes sense to use a digital signature outside the context of initial
connection establishment is when there is a need for nonrepudiation. That is, if you
wish to be able to demonstrate that a particular user “signed” a piece of data to a
third party, you must use public key–based algorithms. Symmetric key integrity
checks are not sufficient for implementing nonrepudiation, because anyone who has
the shared secret can create valid message integrity values. There’s no way to bind
the output of the integrity check algorithm to a particular entity in the system. Public key cryptography allows you to demonstrate that someone who has the private
key associated with a particular public key “signed” the data, and that the data
hasn’t changed since it was signed.
See Also
Recipes 7.12, 7.13, 7.15, 10.1
7.2
Selecting a Public Key Algorithm
Problem
You want to determine which public key algorithms you should support in your
application.
Solution
RSA is a good allaround solution. There is also nothing wrong with using DiffieHellman for key exchange and DSA for digital signatures.
Selecting a Public Key Algorithm  311
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
Elliptic curve cryptography can provide the same levels of security with much smaller
key sizes and with faster algorithms, but this type of cryptography is not yet in widespread use.
Discussion
Be sure to see the general recommendations for using public key cryptography in Recipe 7.1.
Securitywise, there’s no real reason to choose any one of the common algorithms
over the others. There are also no intellectual property restrictions on any of these
algorithms (though there may be on some elliptic curve variants). RSA definitely sees
the most widespread use.
RSA private key operations can be made much faster than operations in other algorithms, which is a major reason it’s preferred in many circumstances. Public key
operations across RSA and the two other major algorithms (DiffieHellman and
DSA) tend to be about the same speed.
When signing messages, RSA tends to be about the same speed or perhaps a bit
slower than DSA, but it is about 10 times faster for verification, if implemented properly. RSA is generally much preferable for key establishment, because some protocols can minimize server load better if they’re based on RSA.
Elliptic curve cryptography is appealing in terms of efficiency, but there is a practical
downside in that the standard in this space (IEEE P1363) requires licensing patents
from Certicom. We believe you can probably implement nonstandard yet still secure
elliptic curve cryptosystems that completely avoid any patent restrictions, but we
would never pursue such a thing without first obtaining legal counsel.
See Also
Recipe 7.1
7.3
Selecting Public Key Sizes
Problem
You’ve decided to use public key cryptography, and you need to know what size
numbers you should use in your system. For example, if you want to use RSA,
should you use 512bit RSA or 4,096bit RSA?
312

Chapter 7: Public Key Cryptography
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
Solution
There’s some debate on this issue. When using RSA, we recommend a 2,048bit
instantiation for generalpurpose use. Certainly don’t use fewer than 1,024 bits, and
use that few only if you’re not worried about longterm security from attackers with
big budgets. For DiffieHellman and DSA, 1,024 bits should be sufficient. Elliptic
curve systems can use far fewer bits.
Discussion
The commonly discussed “bit size” of an algorithm should be an indication of the
algorithm’s strength, but it measures different things for different algorithms. For
example, with RSA, the bit size really refers to the bit length of a public value that is
a part of the public key. It just so happens that the combined bit length of the two
secret primes tends to be about the same size. With DiffieHellman, the bit length
refers to a public value, as it does with DSA.* In elliptic curve cryptosystems, bit
length does roughly map to key size, but there’s a lot you need to understand to give
an accurate depiction of exactly what is being measured (and it’s not worth understanding for the sake of this discussion—“key size” will do!).
Obviously, we can’t always compare numbers directly, even across public key algorithms, never mind trying to make a direct comparison to symmetric algorithms. A
256bit AES key probably offers more security than you’ll ever need, whereas the
strength of a 256bit key in a public key cryptosystem can be incredibly weak (as
with vanilla RSA) or quite strong (as is believed to be the case for standard elliptic
variants of RSA). Nonetheless, relative strengths in the public key world tend to be
about equal for all elliptic algorithms and for all nonelliptic algorithms. That is, if
you were to talk about “1,024bit RSA” and “1,024bit DiffieHellman,” you’d be
talking about two things that are believed to be about as strong as each other.
In addition, in the block cipher world, there’s an assumption that the highly favored
ciphers do their job well enough that the best practical attack won’t be much better
than brute force. Such an assumption seems quite reasonable because recent ciphers
such as AES were developed to resist all known attacks. It’s been quite a long time
since cryptographers have found a new methodology for attacking block ciphers that
turns into a practical attack when applied to a wellregarded algorithm with 128bit
key sizes or greater. While there are certainly no proofs, cryptographers tend to be
very comfortable with the security of 128bit AES for the long term, even if quantum
computing becomes a reality.
* With DSA, there is another parameter that’s important to the security of the algorithm, which few people
ever mention, let alone understand (though the second parameter tends not to be a worry in practice). See
any good cryptography book, such as Applied Cryptography, or the Handbook of Applied Cryptography, for
more information.
Selecting Public Key Sizes  313
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.
In the public key world, the future impact of number theory and other interesting
approaches such as quantum computing is a much bigger unknown. Cryptographers
have a much harder time predicting how far out in time a particular key size is going
to be secure. For example, in 1990, Ron Rivest, the “R” in RSA, believed that a 677bit modulus would provide average security, and 2,017 bits would provide high security, at least through the year 2020. Ten years later, 512 bits was clearly weak, and
1,024 was the minimum size anyone was recommending (though few people have
recommended anything higher until more recently, when 2,048 bits is looking like
the conservative bet).
Cryptographers try to relate the bit strength of public key primitives to the key
strength of symmetric key cryptosystems. That way, you can figure out what sort of
protection you’d like in a symmetric world and pick public key sizes to match. Usually, the numbers you will see are guesses, but they should be as educated as possible if they come from a reputable source. Table 71 lists our recommendations. Note
that not everyone agrees what numbers should be in each of these boxes (for example, the biggest proponents of elliptic curve cryptography will suggest larger numbers in the nonelliptic curve public key boxes). Nonetheless, these recommendations
shouldn’t get you into trouble, as long as you check current literature in four or five
years to make sure that there haven’t been any drastic changes.
Table 71. Recommended key strengths for public key cryptography
Desired security level
Symmetric length
“Regular” public key lengths
Elliptic curve sizes
Acceptable (probably secure 5
years out, perhaps 10)
80 bits
2048 bits (1024 bits in some cases;
see below)
160 bits
Good (may even last forever)
128 bits
2048 bits
224 bits
Paranoid
192 bits
4096 bits
384 bits
Very paranoid
256 bits
8192 bits
512 bits
Remember that “acceptable” is usually good enough; cryptography is
rarely the weakest link in a system!
Until recently, 1,024 bits was the public key size people were recommending. Then,
in 2003, Adi Shamir (the “S” in RSA) and Eran Tromer demonstrated that a $10 million machine could be used to break RSA keys in under a year. That means 1,024bit
keys are very much on the liberal end of the spectrum. They certainly do not provide
adequate secrecy if you’re worried about wellfunded attackers such as governments.
314

Chapter 7: Public Key Cryptography
This is the Title of the Book, eMatter Edition
Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.