Tải bản đầy đủ - 0 (trang)
21 Securely Authenticating a MAC (Thwarting Capture Replay Attacks)

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



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


You want to use a MAC, but parallelize the computation.


Run multiple MACs at the same time, then MAC the resulting tags together (and in

order) to yield one tag.


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



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:


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:


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

Original message
















Figure 6-8. 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.



unsigned char *spc_double_mac(unsigned char *text, size_t len,

unsigned char key[16]) {


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;



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



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


Public Key Cryptography

Many of the recipes in this chapter are too low-level for general-purpose 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 higher-level 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 out-of-band 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 non-repudiation). 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.


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


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 code-related recipes in this chapter.



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


Determining When to Use Public Key



You want to know when to use public key cryptography as opposed to symmetric



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 general-purpose encryption). Because public key operations are computationally expensive, limit digital signatures to authentication at connection time and

when you need non-repudiation.

Whenever you use public key encryption, be sure to remember also to

perform proper authentication and message integrity checking.


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 7-1 (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 7-1 (B). Such an attack is known as a man-in-the-middle attack.


Request server credentials

Request server credentials

Send attacker credentials

Send server credentials





Perceived traffic



Actual traffic

Actual traffic


Figure 7-1. A man-in-the-middle 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 128-bit 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,048-bit 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 general-purpose use.



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 non-repudiation. 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 non-repudiation, 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


Selecting a Public Key Algorithm


You want to determine which public key algorithms you should support in your



RSA is a good all-around 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.


Be sure to see the general recommendations for using public key cryptography in Recipe 7.1.

Security-wise, 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 (Diffie-Hellman 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


Selecting Public Key Sizes


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 512-bit RSA or 4,096-bit RSA?



Chapter 7: Public Key Cryptography

This is the Title of the Book, eMatter Edition

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.


There’s some debate on this issue. When using RSA, we recommend a 2,048-bit

instantiation for general-purpose use. Certainly don’t use fewer than 1,024 bits, and

use that few only if you’re not worried about long-term security from attackers with

big budgets. For Diffie-Hellman and DSA, 1,024 bits should be sufficient. Elliptic

curve systems can use far fewer bits.


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 Diffie-Hellman, 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

256-bit AES key probably offers more security than you’ll ever need, whereas the

strength of a 256-bit 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,024-bit RSA” and “1,024-bit Diffie-Hellman,” 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 well-regarded algorithm with 128-bit

key sizes or greater. While there are certainly no proofs, cryptographers tend to be

very comfortable with the security of 128-bit 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 7-1 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 7-1. 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


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,024-bit

keys are very much on the liberal end of the spectrum. They certainly do not provide

adequate secrecy if you’re worried about well-funded attackers such as governments.



Chapter 7: Public Key Cryptography

This is the Title of the Book, eMatter Edition

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

21 Securely Authenticating a MAC (Thwarting Capture Replay Attacks)

Tải bản đầy đủ ngay(0 tr)