RSA Algorithm
来源:互联网 发布:ubuntu 卸载gdm 编辑:程序博客网 时间:2024/04/30 06:35
RSA Algorithm
The RSA algorithm is named after Ron Rivest, Adi Shamir and Len Adleman, who invented it in 1977[RIVE78]. The basic technique was first discovered in 1973 by Clifford Cocks [COCK73]of CESG (part of the British GCHQ) but this was a secret until 1997.The patent taken out by RSA Labs has expired.
The RSA cryptosystem is the most widely-used public key cryptography algorithm in the world.It can be used to encrypt a message without the need to exchange a secret key separately.
The RSA algorithm can be used for both public key encryption and digital signatures. Its security is based on the difficulty of factoring large integers.
Party A can send an encrypted message to party B without any prior exchange of secret keys.A just uses B's public key to encrypt the message and B decrypts it using the private key, which only he knows.RSA can also be used to sign a message, so A can sign a message using their private key and B can verify it using A's public key.
We look into the mathematics behind the algorithm on our RSA Theory page.
[2013-08-25]Our pages onpublic key cryptography using discrete logarithmslook at a different kind of public key cryptography which relies on the difficulty of solving the discrete logarithm problem.
Contents
Recommended reading
- Cryptography Engineeringby Niels Ferguson, Bruce Schneier and Tadayoshi Kohno.LookInside
- Handbook of Applied Cryptographyby Alfred J. Menezes, Paul C. van Oorschot and Scott A. Vanstone
- Cryptanalysis of RSA and Its Variantsby M. Jason Hinek
Join Amazon Student FREE Two-Day Shipping for College Students
Affiliate disclosure: we get a small commission for purchases made through the above links
- Key generation algorithm
- A practical key generation algorithm
- Encryption
- Decryption
- Digital signing
- Signature verification
- Notes on practical application
- Summary of RSA
- Theory and proof of the RSA algorithm
- Key length
- Computational efficiency and the Chinese Remainder Theorem
- A very simple example
- A slightly less simple example
- A real example
- PKCS#1 Schemes
- Encryption using PKCS#1v1.5
- Signing using PKCS#1v1.5
- Weaknesses in RSA
- More Advanced Schemes
- RSAES-OAEP
- RSASSA-PSS
- ANSI X9.31 Signature Scheme
- ISO/IEC 9796
- RSA-KEM
- Ferguson-Schneier Encryption
- Notation and Conventions
- What is the difference between a bit string and an integer?
- Implementation in C and VB
- References
- Author
- Contact
- Comments
Key Generation Algorithm
This is the original algorithm.
- Generate two large random primes, p and q, of approximately equal size such thattheir productn = pq is of the required bit length, e.g. 1024 bits. [Seenote 1].
- Compute n = pq and (phi) φ = (p-1)(q-1).[Seenote 6].
- Choose an integer e, 1 < e < phi, such thatgcd(e, phi) = 1. [See note 2].
- Compute the secret exponent d, 1 < d < phi, such thated ≡ 1 (mod phi). [Seenote 3].
- The public key is (n, e) and the private key (d, p, q). Keep all the values d, p, q and phi secret.[We prefer sometimes to write the private key as (n, d) because you need the value of n when using d.Other times we might write the key pair as ((N, e), d).]
- n is known as the modulus.
- e is known as the public exponent or encryption exponent or just theexponent.
- d is known as the secret exponent or decryption exponent.
A practical key generation algorithm
Incorporating the advice given in the notes below, a practical algorithm to generate an RSA key pair is given below.Typical bit lengths arek = 1024, 2048, 3072, 4096,..., with increasing computational expense for larger values.You will not go far wrong if you choosee as 65537 (=0x10001) in step (1).
Algorithm: Generate an RSA key pair.
INPUT: Required modulus bit length, k.
OUTPUT: An RSA key pair ((N,e), d) where N is the modulus, the product of two primes (N=pq) not exceedingk bits in length; e is the public exponent, a number less than and coprime to (p-1)(q-1); and d is the private exponent such thated ≡ 1 (mod (p-1)(q-1)).
- Select a value of e from {3, 5, 17, 257, 65537}
- repeat
- p ← genprime(k/2)
- until (p mod e) ≠ 1
- repeat
- q ← genprime(k - k/2)
- until (q mod e) ≠ 1
- N ← pq
- L ← (p-1)(q-1)
- d ← modinv(e, L)
- return (N, e, d)
The function genprime(b)
returns a prime of exactly b bits, with thebth bit set to 1.Note that the operation k/2 is integer division giving the integer quotient with no fraction.
If you've chosen e = 65537 then the chances are that the first prime returned in steps (3) and (6) will pass the tests in steps (4) and (7), so each repeat-until loop will most likely just take one iteration. The final value of N may have a bit length slightly short of the target k. This actually does not matter too much (providing the message m is always < N), but some schemes require a modulus of exact length.If this is the case, then just repeat the entire algorithm until you get one.It should not take too many goes. Alternatively, use the trick setting the two highest bits in the prime candidates described innote 1.
Encryption
Sender A does the following:-
- Obtains the recipient B's public key (n, e).
- Represents the plaintext message as a positive integer m, 1 < m < n [see note 4].
- Computes the ciphertext c = me mod n.
- Sends the ciphertext c to B.
Decryption
Recipient B does the following:-
- Uses his private key (n, d) to compute m = cd mod n.
- Extracts the plaintext from the message representative m.
Digital signing
Sender A does the following:-
- Creates a message digest of the information to be sent.
- Represents this digest as an integer m between 1 and n-1. [Seenote 5].
- Uses her private key (n, d) to compute the signature s = md mod n.
- Sends this signature s to the recipient, B.
Signature verification
Recipient B does the following:-
- Uses sender A's public key (n, e) to compute integer v = se mod n.
- Extracts the message digest from this integer.
- Independently computes the message digest of the information that has been signed.
- If both message digests are identical, the signature is valid.
Notes on practical applications
- To generate the primes p andq, generate a random number of bit length k/2 wherek is the required bit length of the modulusn; set the low bit (this ensures the number is odd) and set the two highest bits (this ensures that the high bit ofn is also set); check if prime (use the Rabin-Miller test); if not, increment the numberby two and check again until you find a prime. This isp. Repeat for q starting with a random integer of length k-k/2.If p<q, swopp and q (this only matters if you intend using the CRT form of the private key).In the extremely unlikely event that p = q, check your random number generator. Alternatively, instead of incrementing by 2, just generate another random number each time.
There are stricter rules in ANSI X9.31 to producestrong primesand other restrictions on p and q to minimise the possibility of known techniques beingused against the algorithm. There is much argument about this topic. It is probably better just to use a longer key length.
- In practice, common choices for e are 3, 5, 17, 257 and 65537 (216+1). These particular values are chosen because they are primes and make the modular exponentiation operation faster, having only two bits of value 1.Aside: These five numbers are the first five Fermat numbers, referred to as F0 to F4, where.Just be careful, these first five Fermat numbers are prime ("Fermat primes"), but the numbers F5 and above are not prime.For example, F5 = 4294967297 = 641 × 6700417.The usual choice for e is F4 = 65537 = 0x10001. Also, having chosen e, it is simpler to test whether gcd(e, p-1)=1 and gcd(e, q-1)=1 while generatingand testing the primes in step 1. Values ofp or q that fail this test can be rejected there and then.Even better: if e is an odd prime then you can do the less-expensive test(p mod e) ≠ 1 instead of gcd(p-1,e) = 1.Why is that? If e is prime then gcd(p-1, e) > 1 if and only if p-1 is a multiple of e.That is, ifp - 1 ≡ 0 (mod e) or p ≡ 1 (mod e). Hence gcd(p-1, e) = 1 ⇔ p mod e ≠ 1.
- To compute the value for d, use theExtended Euclidean Algorithm to calculated = e-1 mod phi, also writtend = (1/e) mod phi. This is known as modular inversion. Note that this is not integer division. The modular inversed is defined as the integer value such that ed = 1 mod phi. It only exists ife and phi have no common factors.2010-08-14: For more details of the extended Euclidean algorithm, see our new pageThe Euclidean Algorithm and the Extended Euclidean Algorithmwhich shows how to use the Euclidean algorithm, answer exam questions on it, and gives source code for an implementation.
- When representing the plaintext octets as the representative integerm, it is important to add random padding charactersto make the size of the integerm large and less susceptible to certain types of attack. If m = 0 or 1 or n-1 there is no security as the ciphertext has the same value.For more details on how to represent the plaintext octets as a suitable representative integerm, see PKCS#1 Schemes below or the reference itself [PKCS1]. It is important to make sure that m < n otherwise the algorithm will fail. This is usually done by making sure the first octet of m is equal to 0x00.
- Decryption and signing are identical as far as the mathematics is concerned as both use the private key. Similarly, encryption and verification both use the same mathematical operation with the public key.That is, mathematically, for m < n,
m = (me mod n)d mod n = (md mod n)e mod n
However, note these important differences in implementation:-
- The signature is derived from a message digest of the original information. The recipient will need to follow exactly the same process to derive themessage digest, using an identical set of data.
- The recommended methods for deriving the representative integers are differentfor encryption and signing (encryption involves random padding, but signing uses the same padding each time).
- The original definition of RSA uses the Euler totient functionφ(n) = (p-1)(q-1). More recent standards use theCharmichael function λ(n) = lcm(p-1, q-1) instead.λ(n) is smaller than φ(n) and divides it. The value of d' computed by d' = e-1 mod λ(n)is usually different from that derived by d = e-1 mod φ(n), but the end result is the same.Both d and d' will decrypt a message me mod n and both will give the same signature value s = md mod n = md' mod n. To compute λ(n), use the relation
λ(n) = (p-1)(q-1) / gcd(p-1, q-1).
- You might ask if there is a way to find the factors ofn given just d and e. This is possible.2012-12-01: For more details, see our pageRSA: how to factorize N given d.
Summary of RSA
- n = pq, where p and q are distinct primes.
- phi, φ = (p-1)(q-1)
- e < n such that gcd(e, phi)=1
- d = e-1 mod phi.
- c = me mod n, 1<m<n.
- m = cd mod n.
For more on the theory and mathematics behind the algorithm, see the RSA Theory page.
Key length
When we talk about the key length of an RSA key, we are referring to the length of the modulus,n, in bits.The minimum recommended key length for a secure RSA transmission is currently 1024 bits. A key length of 512 bits is now no longer considered secure, although cracking it is still not a trivial task for the likes of you and me. The longer your information is needed to be kept secure, the longer the key you should use.Keep up to date with the latest recommendations in the security journals.
There is one small area of confusion in defining the key length.One convention is that the key length is the position of the most significant bit inn that has value '1', where the least significant bit is at position 1. Equivalently, key length =ceiling(log2(n+1)).The other convention, sometimes used, is that the key length is the number of bytes needed to storen multiplied by eight, i.e. ceiling(log256(n+1))*8.
The key used in the RSA Example paper [KALI93] is an example. In hex form the modulus is0A 66 79 1D C6 98 81 68 DE 7A B7 74 19 BB 7F B0C0 01 C6 27 10 27 00 75 14 29 42 E1 9A 8D 8C 51D0 53 B3 E3 78 2A 1D E5 DC 5A F4 EB E9 94 68 1701 14 A1 DF E6 7C DC 9A 9A F5 5D 65 56 20 BB AB
The most significant byte 0x0A in binary is 00001010'B
. The most significant bit is at position 508, so its key length is 508 bits.On the other hand, this value needs 64 bytes to store it, so the key length could also be referred to by some as 64 x 8 = 512 bits.We prefer the former method. You can get into difficulties with the X9.31 method for signatures if you use the latter convention.
Minimum key lengths
The following table is taken from NIST's Recommendation for Key Management [NIST-80057].It shows the recommended comparable key sizes for symmetrical block ciphers (AES and Triple DES) and the RSA algorithm. That is, the key length you would need to use to have comparable security.
Note just how huge (and impractical) an RSA key needs to be for comparable security with AES-192 or AES-256 (although these two algorithms have had someweaknesses exposed recently; AES-128 is unaffected).
The above table is a few years old now and may be out of date. Existing cryptographic algorithms only get weaker as attacks get better.
Computational Efficiency and the Chinese Remainder Theorem (CRT)
Key generation is only carried out occasionally and so computational efficiency is less of an issue.
The calculation a = be mod n is known as modularexponentiation and one efficient method to carry this out on a computeris thebinary left-to-right method. To solve y = x^e mod n let e be represented in base 2 as
e = e(k-1)e(k-2)...e(1)e(0)
where e(k-1) is the most significant non-zero bit and bit e(0) the least.
set y = xfor bit j = k - 2 downto 0 begin y = y * y mod n /* square */ if e(j) == 1 then y = y * x mod n /* multiply */endreturn y
The time to carry out modular exponentation increases with the number of bits set to one in the exponente. For encryption, an appropriate choice of e can reduce the computational effort required to carry out the computation ofc = me mod n. Popularchoices like 3, 17 and 65537 are all primes with only two bits set:3 = 0011'B, 17 = 0x11, 65537 = 0x10001.
The bits in the decryption exponent d, however, will not be so convenient and so decryption using the standard method of modular exponentiation will take longer than encryption. Don't make the mistake of trying to contrive a small value ford; it is not secure.
An alternative method of representing the private key uses the The Chinese Remainder Theorem (CRT).
The private key is represented as a quintuple (p, q, dP, dQ, and qInv), where p and q areprime factors of n, dP and dQ are known as theCRT exponents,and qInv is the CRT coefficient. The CRT method of decryption is about four timesfaster overall than calculating m = cd mod n. The extra values for the private key are:-
dP = (1/e) mod (p-1)dQ = (1/e) mod (q-1)qInv = (1/q) mod p where p > q
where the (1/e)
notation means the modular inverse (seenote 3 above). These values are pre-computed and saved along withp and q as the private key.To compute the message m given c do the following:-
m1 = c^dP mod pm2 = c^dQ mod qh = qInv(m1 - m2) mod pm = m2 + hq
Even though there are more steps in this procedure, the modular exponentation to be carried out uses muchshorter exponents and so it is less expensive overall.
[2008-09-02] Chris Becke has pointed out that most large integer packages will fail when computingh
if m1 < m2
.This can be easily fixed by computing
h = qInv(m1 + p - m2) mod p
or, alternatively, as we do it in our BigDigitsimplementation of RSA,
if (bdCompare(m1, m2) < 0) bdAdd(m1, m1, p); bdSubtract(m1, m1, m2); /* Let h = qInv ( m_1 - m_2 ) mod p. */ bdModMult(h, qInv, m1, p);
A very simple example of RSA encryption
This is an extremely simple example using numbers you can work out on a pocket calculator(those of you over the age of35 45 can probably even do it by hand).
- Select primes p=11, q=3.
- n = pq = 11.3 = 33
phi = (p-1)(q-1) = 10.2 = 20 - Choose e=3
Check gcd(e, p-1) = gcd(3, 10) = 1 (i.e. 3 and 10 have no common factors except 1),
and check gcd(e, q-1) = gcd(3, 2) = 1
therefore gcd(e, phi) = gcd(e, (p-1)(q-1)) = gcd(3, 20) = 1 - Compute d such that ed ≡ 1 (mod phi)
i.e. compute d = e-1 mod phi = 3-1 mod 20
i.e. find a value for d such that phi divides (ed-1)
i.e. find d such that 20 divides 3d-1.
Simple testing (d = 1, 2, ...) gives d = 7
Check: ed-1 = 3.7 - 1 = 20, which is divisible by phi. - Public key = (n, e) = (33, 3)
Private key = (n, d) = (33, 7).
Now say we want to encrypt the message m = 7,
c = me mod n = 73 mod 33 = 343 mod 33 = 13.
Hence the ciphertext c = 13.
To check decryption we compute
m' = cd mod n = 137 mod 33 = 7.
Note that we don't have to calculate the full value of 13 to the power 7 here. We can make use of the fact that
a = bc mod n = (b mod n).(c mod n) mod n
so we can break down a potentially large number into its components and combine the results of easier, smaller calculations to calculate the final value.
One way of calculating m' is as follows:-
Note that any number can be expressed as a sum of powers of 2. So first compute values of 132, 134, 138, ... by repeatedly squaring successive values modulo 33.
132 = 169 ≡ 4, 134 = 4.4 = 16, 138 = 16.16 = 256 ≡ 25.
Then, since 7 = 4 + 2 + 1, we havem' = 137 = 13(4+2+1) = 134.132.131
≡ 16 x 4 x 13 = 832 ≡ 7 mod 33
Now if we calculate the ciphertext c for all the possible values of m (0 to 32), we get
m 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16c 0 1 8 27 31 26 18 13 17 3 10 11 12 19 5 9 4m 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32c 29 24 28 14 21 22 23 30 16 20 15 7 2 6 25 32
Note that all 33 values of m (0 to 32) map to a unique code c in the same range ina sort of random manner. In this case we have nine values of m that map to the same value of c- these are known asunconcealed messages. m = 0, 1 and n-1 will always do this for any n, no matter how large. But in practice, these shouldn't be a problem when we use largevalues forn in the order of several hundred bits.
If we wanted to use this system to keep secrets, we could let A=2, B=3, ..., Z=27.(We specifically avoid 0 and 1 here for the reason given above).Thus the plaintext message "HELLOWORLD" would be represented by the set of integers m1, m2, ...
(9,6,13,13,16,24,16,19,13,5)Using our table above, we obtain ciphertext integers c1, c2, ...
(3,18,19,19,4,30,4,28,19,26)Note that this example is no more secure than using a simple Caesar substitution cipher, but it servesto illustrate a simple example of the mechanics of RSA encryption.
Remember that calculating me mod n is easy, but calculating the inversec-e mod n is very difficult, well, for large n's anyway. However, if we can factor n into its prime factors p and q, the solution becomes easy again, even for large n's. Obviously, if we can get hold of the secret exponent d, the solution is easy, too.
A slightly less simple example of the RSA algorithm
[Updated 25 November 2012] This time, to make life slightly less easy for those who can crack simple Caesar substitution codes, we will group the characters into blocks of three and compute a message representative integer for each block.Please note that this method is not secure in any way. It just shows another example of the mechanism of RSA with small numbers.
For this example, to keep things simple, we'll limit our characters to the letters A to Z and the space character.
ATTACK AT SEVEN = ATT ACK _AT _SE VEN
In the same way that any decimal number can be represented uniquely as the sum of powers of ten, e.g.
135 = 1 x 102 + 3 x 101 + 5,
we can represent our blocks of three characters as the sum of powers of 27 using SPACE=0, A=1, B=2, C=3, .. E=5, .. K=11, .. N=14, .. S=19, T=20, .. V=22, ..., Z=26.
ATT ⇒ 1 x 272 + 20 x 271 + 20 = 1289
ACK ⇒ 1 x 272 + 3 x 271 + 11 = 821
_AT ⇒ 0 x 272 + 1 x 271 + 20 = 47
_SE ⇒ 0 x 272 + 19 x 271 + 5 = 518
VEN ⇒ 22 x 272 + 5 x 271 + 14 = 16187
Using this system of integer representation, the maximum value of a block (ZZZ) is 273-1 = 19682, so we requirea modulus n greater than this value.
- We choose e = 3
- We select primes p=173 and q=149 and check
- gcd(e, p-1) = gcd(3, 172) = 1 ⇒ OK
- gcd(e, q-1) = gcd(3, 148) = 1 ⇒ OK.
- Thus we have n = pq = 173 × 149 = 25777, and
phi = (p-1)(q-1) = 172 × 148 = 25456. - We compute d = e-1 mod phi = 3-1 mod 25456 = 16971.
- Note that ed = 3 × 16971 = 50913 = 2 × 25456 + 1
- That is, ed ≡ 1 mod 25456 ≡ 1 mod phi
- Hence our public key is (n, e) = (25777, 3) and our private key is (n, d) = (25777, 16971).We keep the values of p, q, d and phi secret.
To encrypt the first integer that represents "ATT", we have
c = me mod n = 12893 mod 25777 = 18524.
Overall, our plaintext ATTACK AT SEVEN
is represented by the sequence of five integers m1, m2, m3, m4, m5:
m_i = (1289, 821, 47, 518, 16187)
We compute corresponding ciphertext integers ci = mie mod n, (which is still possible by using a calculator, honest):
c1 = 12893 mod 25777 = 18524
c2 = 8213 mod 25777 = 7025
c3 = 473 mod 25777 = 715
c4 = 5183 mod 25777 = 2248
c5 = 161873 mod 25777 = 24465
We can send this sequence of integers, ci, to the person who has the private key.
c_i = (18524, 7025, 715, 2248, 24465)
We can compute the inverse of these ciphertext integers usingm = cd mod n to verify that the RSA algorithm still holds. However, this is nowoutside the realm of hand calculations.
To help you carry out these modular arithmetic calculations, download ourfree modular arithmetic command line programs.
For example, to compute 1852416971 mod 25777
, use thebd_modexp
command:
bd_modexp 18524 16971 2577718524^16971 mod 25777 = 1289
m1 = 1852416971 mod 25777 = 1289
m2 = 702516971 mod 25777 = 821
m3 = 71516971 mod 25777 = 47
m4 = 224816971 mod 25777 = 518
m5 = 2446516971 mod 25777 = 16187
16187 ÷ 272 = 16187 ÷ 729 = 22 rem 149, 22 → 'V'
149 ÷ 271 = 149 ÷ 27 = 5 rem 14, 5 → 'E'
14 ÷ 270 = 14 ÷ 1 = 14 rem 0, 14 → 'N'
Similarly, m = 47 is encoded as follows: 47 ÷ 272 = 0 rem 47, 0 → SPACE; 47 ÷ 271 = 1 rem 20, 1 → 'A';20 ÷ 270 = 20 rem 0, 20 → 'T'
giving the string "_AT".
Question: Why can't we use this method of encoding integers into blocks of three letters to encode the ciphertext?
A caution about this example
Note that this example is a very insecure method of encryption and should not be used in practice.We can easily factorize the modulus and hence break the cipher.
Factorising a small RSA modulus
Starting with the knowledge that the modulus 25777 is the product of exactly two distinct primenumbers, and that one of these must be less than its integer square root (why?), a little testing of suitable candidatesfrom atable of prime numbers will get you the answer pretty quickly.
Given n = 25777, compute √25777 = 160.55, and then work downwards through the prime numbers < 160, i.e. (157, 151, 149, 139, ...),and try to divide inton in turn:
157: 25777 / 157 = 164 remainder 29, so not a factor;
151: 25777 / 151 = 170 remainder 107, so not a factor;
149: 25777 / 149 = 173 exactly, so we have it.
You could also write a simple computer program to factor n that just divides it byevery odd number starting from 3 until it either finds an exact factor or stops when it reaches a number greater than the squareroot of n.
A real example
In practice, we use a modulus of size in the order of 1024 bits. That is a number over 300 decimal digits long.One example is
n = 119294134840169509055527211331255649644606569661527638012067481954943056851150333806315957037715620297305000118628770846689969112892212245457118060574995989517080042105263427376322274266393116193517839570773505632231596681121927337473973220312512599061231322250945506260066557538238517575390621262940383913963
This is composed of the two primes
p = 10933766183632575817611517034730668287155799984632223454138745671121273456287670008290843302875521274970245314593222946129064538358581018615539828479146469q = 10910616967349110231723734078614922645337060882141748968209834225138976011179993394299810159736904468554021708289824396553412180514827996444845438176099727
With a number this large, we can encode all the information we need in one big integer.We put our message into an octet string and then convert to a large integer.
Also, rather than trying to represent the plaintext as an integer directly, we generate a randomsession key and use that to encrypt the plaintext witha conventional, much faster symmetrical algorithm like Triple DES or AES-128. We then use the much slower public key encryption algorithm to encrypt just the session key.
The sender A then transmits a message to the recipient B in a format something like this:-
Session key encrypted with RSA = xxxx
Plaintext encrypted with session key = xxxxxxxxxxxxxxxxx
The recipient B would extract the encrypted session key and use his private key (n,d) todecrypt it. He would then use this session key with a conventional symmetrical decryptionalgorithm to decrypt the actual message. Typically the transmission would include in plaintext details of the encryption algorithms used,padding and encoding methods, initialisation vectors and other details required by the recipient. The only secret required to be kept, as always, should be the private key.
If Mallory intercepts the transmission, he can either try and crack the conventionally-encryptedplaintext directly, or he can try and decrypt the encryped session key and then use that in turn. Obviously, this systemis as strong as its weakest link.
When signing, it is usual to use RSA to sign the message digest of the message rather than the message itself. A one-way hash function like SHA-1 or SHA-256 is used. The sender A then sends the signed message to B in a format like this
Hash algorithm = hh
Message content = xxxxxxxxx...xxx
Signature = digest signed with RSA = xxxx
The recipient will decrypt the signature to extract the signed message digest,m; independently compute the message digest, m',of the actual message content; and check thatm and m' are equal.Putting the message digest algorithm at the beginning of the message enables the recipient to compute the message digest on the fly while reading the message.
PKCS#1 Schemes
The most common scheme using RSA is PKCS#1 version 1.5 [PKCS1]. This standard describes schemes for both encryption and signing.The encryption scheme PKCS#1v1.5 has some known weaknesses, but these can easily be avoided.SeeWeaknesses in RSA below.
There is an excellent paper by Burt Kalinski of RSA Laboratories written in the early 1990s[KALI93] that describes in great detail everything you need to know about encoding and signing using RSA. There are full examples right down to listing out the bytes. OK, it uses MD2 and a small 508-bitmodulus and obviously doesn't deal with refinements built up over the last decade to deal withmore subtle security threats, but it's an excellent introduction.
The conventions we use here are explained below in Notation and Conventions.
Encryption using PKCS#1v1.5
Algorithm: Encryption using PKCS#1v1.5
INPUT: Recipient's RSA public key, (n, e) of length
k = |n|
bytes; dataD (typically a session key) of length |D|
bytes with |D|<=k-11
.OUTPUT: Encrypted data block of length k bytes
- Form the k-byte encoded message block, EB,
EB = 00 || 02 || PS || 00 || D
where||
denotes concatenation andPS is a string ofk-|D|-3
non-zero randomly-generated bytes (i.e. at least eight random bytes). - Convert the byte string, EB, to an integer, m, most significant byte first,
m = StringToInteger(EB)
- Encrypt with the RSA algorithm
c = m^e mod n
- Convert the resulting ciphertext, c, to a k-byte output block,OB‡
OB = IntegerToString(c, k)
- Output OB.
The conversions in steps (2) and (4) from byte string to large integer representative and back again may not be immediately obvious.Large integers and byte (bit) strings are conceptually different even though they may both be stored as arrays of bytes in your computer.See What is the difference between a bit string and an integer?
‡2012-05-23: Thanks to "dani torwS" for pointing out a typo in the formula.
Worked Example
Bob's 1024-bit RSA encryption key in hex format:
n=A9E167983F39D55FF2A093415EA6798985C8355D9A915BFB1D01DA197026170FBDA522D035856D7A986614415CCFB7B7083B09C991B81969376DF9651E7BD9A93324A37F3BBBAF460186363432CB07035952FC858B3104B8CC18081448E64F1CFB5D60C4E05C1F53D37F53D86901F105F87A70D1BE83C65F38CF1C2CAA6AA7EBe=010001d=67CD484C9A0D8F98C21B65FF22839C6DF0A6061DBCEDA7038894F21C6B0F8B35DE0E827830CBE7BA6A56AD77C6EB517970790AA0F4FE45E0A9B2F419DA8798D6308474E4FC596CC1C677DCA991D07C30A0A2C5085E217143FC0D073DF0FA6D149E4E63F01758791C4B981C3D3DB01BDFFA253BA3C02C9805F61009D887DB0319A randomly-generated one-off session key for AES-128 might be
D=4E636AF98E40F3ADCFCCB698F4E80B9F
The encoded message block, EB, after encoding but before encryption, with random padding bytes shown in green,0002257F48FD1F1793B7E5E02306F2D3228F5C95ADF5F31566729F132AA12009E3FC9B2B475CD6944EF191E3F59545E671E474B555799FE3756099F044964038B16B2148E9A2F9C6F44BB5C52E3C6C8061CF694145FAFDB24402AD1819EACEDF4A36C6E4D2CD8FC1D62E5A1268F496004E636AF98E40F3ADCFCCB698F4E80B9FAfter RSA encryption, the output is
3D2AB25B1EB667A40F504CC4D778EC399A899C8790EDECEF062CD739492C9CE58B92B9ECF32AF4AAC7A61EAEC346449891F49A722378E008EFF0B0A8DBC6E621EDC90CEC64CF34C640F5B36C48EE9322808AF8F4A0212B28715C76F3CB99AC7E609787ADCE055839829E0142C44B676D218111FFE69F9D41424E177CBA3A435B
The above hex data in C format.
Note that the output for encryption will be different each time (or should be!) because of the random padding used.
Encrypting a message
For a plaintext message, say,PT="Hello world!"that is, the 12 bytes in hex format,
PT=48656C6C6F20776F726C6421Then, using the 128-bit session key from above,
KY=4E636AF98E40F3ADCFCCB698F4E80B9Fand the uniquely-generated 128-bit initialization vector (IV)
IV=5732164B3ABB6C4969ABA381C1CA75BAthe ciphertext using AES-128 in CBC mode with PKCS padding is,
CT=67290EF00818827C777929A56BC3305B
The sender would then send a transmission to the recipient (in this case, Bob) including the following information in some agreed format
Recipient: BobKey Encryption Algorithm: rsaEncryptionEncrypted Key:3D2AB25B1EB667A40F504CC4D778EC399A899C8790EDECEF062CD739492C9CE58B92B9ECF32AF4AAC7A61EAEC346449891F49A722378E008EFF0B0A8DBC6E621EDC90CEC64CF34C640F5B36C48EE9322808AF8F4A0212B28715C76F3CB99AC7E609787ADCE055839829E0142C44B676D218111FFE69F9D41424E177CBA3A435BContent Encryption Algorithm: aes128-cbcIV: 5732164B3ABB6C4969ABA381C1CA75BAEncrypted Content:67290EF00818827C777929A56BC3305B
The usual formats used for such a message are either a CMS enveloped-data object or XML, but the above summary includesall the necessary info (well, perhaps "Bob" might be defined a bit more accurately).
Cryptographic Message Syntax (CMS) [CMS] is a less-ambiguous version of the earlier PKCS#7 standard (also of the same name)and is designed to be used in S/MIME messages.CMS enveloped-data objects (yes, that'senveloped not encrypted) use ASN.1 and are encoded using either DER- or BER-encoding.(DER-encoding is a stricter subset of BER).
The terminology for CMS and ASN.1 may sound messy, but the end results are well-defined and universally-accepted. On the other hand, the XML cryptographic standards are, to be honest, a complete mess: seeXML is xhite.Pretty Good Privacy (PGP) also has a format for RSA messages, although PGP stopped using RSA because of patent issues back in the 1990s.
Nothing, of course, stops you and your recipient from agreeing on your own format and using that. But be careful, even the experts get these things wrong and accidentally give away more than they realise.
Signing using PKCS#1v1.5
Algorithm: Signing using PKCS#1v1.5
INPUT: Sender's RSA private key, (n, d) of length
k = |n|
bytes; message,M, to be signed; message digest algorithm, Hash.OUTPUT: Signed data block of length k bytes
- Compute the message digest H of the message,
H = Hash(M)
- Form the byte string, T, from the message digest, H, according to the message digest algorithm, Hash, as follows
Hash T MD530 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H
SHA-130 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H
SHA-22430 2d 30 0d 06 09 60 86 48 01 65 03 04 02 04 05 00 04 1c || H
SHA-25630 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H
SHA-38430 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30 || H
SHA-51230 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H
where T is an ASN.1 value of type DigestInfo encoded using the Distinguished Encoding Rules (DER). - Form the k-byte encoded message block, EB,
EB = 00 || 01 || PS || 00 || T
where||
denotes concatenation andPS is a string of bytes all of value 0xFF of such length so that|EB|=k
. - Convert the byte string, EB, to an integer m, most significant byte first,
m = StringToInteger(EB)
- Sign with the RSA algorithm
s = m^d mod n
- Convert the resulting signature value, s, to a k-byte output block,OB
OB = IntegerToString(s, k)
- Output OB.
Worked Example
Alice's 1024-bit RSA signing key in hex format:
n=E08973398DD8F5F5E88776397F4EB005BB5383DE0FB7ABDC7DC775290D052E6D 12DFA68626D4D26FAA5829FC97ECFA82510F3080BEB1509E4644F12CBBD832CF C6686F07D9B060ACBEEE34096A13F5F7050593DF5EBA3556D961FF197FC981E6 F86CEA874070EFAC6D2C749F2DFA553AB9997702A648528C4EF357385774575F e=010001d=00A403C327477634346CA686B57949014B2E8AD2C862B2C7D748096A8B91F736F275D6E8CD15906027314735644D95CD6763CEB49F56AC2F376E1CEE0EBF282DF439906F34D86E085BD5656AD841F313D72D395EFE33CBFF29E4030B3D05A28FB7F18EA27637B07957D32F2BDE8706227D04665EC91BAF8B1AC3EC9144AB7F21The message to be signed is, of course,
M="abc"that is, the 3 bytes in hex format,
PT=616263The message digest algorithm is SHA-1, so
H = Hash("abc") = A9993E364706816ABA3E25717850C26C9CD0D89D
The DigestInfo value for SHA-1 isT=3021300906052B0E03021A05000414A9993E364706816ABA3E25717850C26C9CD0D89DThe encoded message block, EB, after encoding but before signing is
0001FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF003021300906052B0E03021A05000414A9993E364706816ABA3E25717850C26C9CD0D89DAfter RSA signing, the output is
60AD5A78FB4A4030EC542C8974CD15F55384E836554CEDD9A322D5F4135C6267A9D20970C54E6651070B0144D43844C899320DD8FA7819F7EBC6A7715287332EC8675C136183B3F8A1F81EF969418267130A756FDBB2C71D9A667446E34E0EAD9CF31BFB66F816F319D0B7E430A5F2891553986E003720261C7E9022C0D9F11F
The above hex data in C format.
Weaknesses in RSA
- Small encryption exponent
- If you use a small exponent like
e=3
and send the same message to different recipientsand just use the RSA algorithm without adding random padding to the message, then an eavesdropper could recover the plaintext.2010-10-23: For an example of this, seeCracking RSA on our page on theThe Chinese Remainder Theorem. - Small encryption exponent and small message
- If you use
e=3
and just encrypt a small message m without padding wherem3 < n
then your ciphertext c can easily be broken by simply computing its real cube root.For example, if we have the public key(n, e) = (25777, 3)
and just encrypt the small messagem = 10
then the ciphertext isc = 1000
. The secure properties of RSA encryption only work ifme > n
. - Using the same key for encryption and signing
- Given that the underlying mathematics is the same for encryption andsigning, only in reverse, if an attacker can convince a key holder to sign an unformatted encrypted message using the same keythen she gets the original.
- Using a common modulus for different users
- Do not use the same modulus n with different (ei, di) pairs for different users in a group.Given his own pair(e1, d1), user 1 can factorize the common n intop and q and hence compute the private exponents di of all the other users.2012-12-01: For more details, see our pageRSA: how to factorize N given d.
- Acting as an oracle
- There are techniques to recover the plaintext if a user just blindly returns the RSA transformation of the input.So don't do that.
Solutions
- Don't use the same RSA key for encryption and signing.
- Don't encrypt or sign a blind message.
- If using PKCS#v1.5 encoding, use
e=0x10001
for your public exponent. - Always format your input before encrypting or signing.
- Always add fresh random padding - at least 8 bytes - to your message before encrypting.
- When decrypting, check the format of the decrypted block. If it is not as expected, return an error message,not the decrypted string.
- Similarly, when verifying a signature, if there is any error whatsoever, just respond with "Invalid Signature".
More Advanced Schemes
The underlying RSA computations
c = me mod n, m' = cd mod n; s = md mod n, m' = se mod n
are always the same, but there are many variants of how these can be used inside an encryption or digital signaturescheme.Here are some of them.
RSAES-OAEP
The OAEP encoding technique for encryption is described in PKCS#1 version 2 and in IEEE P136.It is more secure than the PKCS#1v1.5 encoding method described above, perhaps provably secure. The encoding technique involves a mask generation function (MGF) based on a hash function and there is no obvious structure in the encodedblock, unlike the PKCS#1v1.5 encoding method.Despite being the recommended method for the last decade, OAEP is not used in practice as much as you'd expect. In fact, hardly at all.That said, if you have a choice in the matter, we recommend that you should use OAEP if you can.
RSASSA-PSS
The PSS encoding method is used to encode before creating a signature. The technique is described in PKCS#1v2.1 and is similar in design to the OAEP encoding used forencryption involving an MGF based on a hash function. However, there are active patents associated with this method, so sensible implementors avoid it like the plague.Since there are currently no known weaknesses with the PKCS#1v1.5 signature scheme and the nasty smell of patents still lingers,PSS is also not used in practice very much.
X9.31 Signature Scheme
ANSI standard X9.31 [AX931] requires usingstrong primes derived in a way to avoid particular attacks that are probably no longer relevant.X9.31 uses a method of encoding the message digest specific to the hash algorithm. It expects a key with length an exact multiple of 256 bits.The same algorithm is also specified in P1363 [P1363] where it is called IFSP-RSA2.The scheme allows for the public exponent to be an even value, but we do not consider that case here; all our values ofe are assumed to be odd.The message digest hash, H, is encapsulated to form a byte string as follows
EB = 06 || PS || 0xBA || H || 0x33 || 0xCC
where PS is a string of bytes all of value 0xBB of length such that|EB|=|n|
, and 0x33 is the ISO/IEC 10118 part number† for SHA-1.The byte string,EB, is converted to an integer value, the message representative, f.
† ISO/IEC 10118 part numbers for other hash functions are:SHA-1=0x33, SHA-256=0x34, SHA-384=0x36, SHA-512=0x35, RIPEMD=0x31.
Algorithm: Forming an X9.31/RSA2 signature value from the message representative (for odde).
INPUT: Signer's RSA private key, (n, d); integer, f, where 0 <= f < n and f ≡ 12 (mod 16).
OUTPUT: Signature, an integer s, 0 <= s < n/2,i.e. a value at least one bit shorter thann.
- t = fd mod n
- s = min{t, n-t}
- Output s.
The integer, s, is converted to a byte string of length
|n|
bytes.Algorithm: Extracting the message representative from an X9.31/RSA2 signature value (for odde).
INPUT: Signer's RSA public key, (n, e); signature, s.
OUTPUT: Message representative, f, such that t ≡ 12 (mod 16), or "invalid signature".
- If s is not in [0,(n-1)/2], output "invalid signature" and stop.
- Computet = se mod n
- If t ≡ 12 (mod 16) then let f = t.
- Else let f = n-t. If NOT f ≡ 12 (mod 16), output "invalid signature" and stop.
- Output f.
The integer f is converted to a byte string of length
|n|
bytes and then parsed to confirm thatall bytes match the required formatEB = 06 || PS || 0xBA || H || 0x33 || 0xCCIf not, output "invalid signature" and stop; otherwise output the extracted message digest hash,H.
ISO/IEC 9796
IOS/IEC 9796 is an old standard devised before there was a recognised message digest function like MD5 or SHA-1.It allows the entire message to be recovered. Unfortunately, it is considered broken for signing plain text messages, but is still OKfor signing message digest values. It is used in the AUTACK scheme described in [EDIFACT].
The encapsulation mechanism weaves the input bytes into a format exactly one bit shorter than the RSA key.The signing mechanism is similar to that in ANSI X9.31 described above, but the message representative,f, is required to bef ≡ 6 (mod 16), instead of modulo 12. In other words, make sure the last 4 bits are equal to 0x6 instead of 0xC.
RSA-KEM
The RSA-KEM Key Transport Algorithm encrypts a random integer with the recipient's public key, and then uses a symmetric key-wrapping scheme to encrypt the keying data. KEM stands forKey Encapsulation Mechanism. The general algorithm is as follows
- Generate a random integer z between 0 and n-1.
- Encrypt the integer z with the recipient's RSA public key:c = ze mod n.
- Derive a key-encrypting key KEK from the integer z.
- Wrap the keying data using KEK to obtain wrapped keying data WK.
- Output c and WK as the encrypted keying data.
This method has a higher security assurance than PKCS#1v1.5because the input to the underlying RSA operation is random and independent of the message, and the key-encrypting key KEK is derived from it in a strong way.The downside is that you need to implement a key derivation method (of which there are many varieties - see How many KDFs are there?)and a key wrapping algorithm.The encoding of the final data into the recommended ASN.1 format is messy, too.For more details, see the latest version of [CMSRSAKEM].
Ferguson-Schneier Encryption
In their book [FERG03], Niels Ferguson and Bruce Schneier suggest a much simpler method of encryption.They suggest using the same modulusn for both encryption and signatures but to use e=3 for signaturesande=5 for encryption (you need to make sure that the modulusn = pq satisfies both gcd(3,(p-1)(q-1))=1andgcd(5,(p-1)(q-1))=1).
Their method uses RSA to encrypt a random integer and use a hash function to derive the actual content encryption key,thus removing any structural similarities between the actual CEK and the data encrypted by the RSA.They recommend using the function,Hash(x):=SHA256(SHA256(x)), for hashing data.
Algorithm: Ferguson-Schneier Encrypt Random Key with RSA.
INPUT: Recipient's RSA public key, (n, e).
OUTPUT: Content encryption key, CEK; RSA-encrypted CEK, c.
- Compute the exact bit length of the RSA key,k = ceiling(log2(n+1)).
- Choose a random r in the interval [0, 2k-1].
- Compute the content encryption key by hashing r, CEK=Hash(r).
- c = re mod n.
- Output CEK and c.
For a plaintext message, m, the transmission sent to the recipient isIntegerToString(c) || ECEK(m), whereECEK(m) is the result of encrypting m with a symmetricalencryption algorithm using key, CEK. Given that the recipient knows the size of the RSA key and hence the exact number of bytes needed to encodec, it is a simple matter to parse the input received from the sender.
For example code of this algorithm in Visual Basic (both VB6 and VB.NET) using ourCryptoSys PKI Toolkit, seeFerguson-Schneier RSA Encryption.
Notation and Conventions
We use the following notation and conventions in this page.
- A || B denotes concatenation of byte (or bit) stringsA and B.
- |B| denotes the length of the byte (or bit) stringB in bytes.
- |n| denotes the length** of the non-negative integern in bytes,|n| = ceiling(log256(n+1)).
- IntegerToString(i, n) is an n-byte encoding of the integeri with the most significantbyte first (i.e. in "big-endian" order). So, for example,
IntegerToString(1, 4)="00000001",IntegerToString(7658, 3)="001DEA"
- StringToInteger(S) is the integer represented by the byte stringS with the most significant byte first.
- ceiling(x) is the smallest integer, n, such thatn ≥ x.This is also written as ⌈x⌉.
** Strictly speaking, this is the length of the shortest byte string that can encode the integer.
What is the difference between a bit string and an integer?
A string is a contiguous sequence of symbols, so the string "cat" is a sequence of the letters 'c', 'a' and 't'. Abit string is sequence of binary digits (bits) '0' and '1'. A byte string is similar exceptit consists of bytes, which are in turn sequences of 8 bits. So abit string and a byte string are the same thing, except the latter is restricted to multiples of 8 bits.For example, using hexadecimal representation, the byte string "8002EA" is a sequence of 3 bytes, 0x80, 0x02 and 0xEA;and is equal to the bit string "100000000000001011101010".
A string can be split into sub-strings (e.g. "8002" and "EA") and two strings can be concatenated (joined up) to make another string.The order of symbols is important. The usual convention is to write byte strings with the most significant byte first ("big-endian" or network byte order).
An integer is a whole number that obeys the usual rules of integer arithmetic (1+1=2, 5-2=3, 3x2=6, 6/3=2)and modular arithmetic (10+6≡4 (mod 12)). There is no limit in theory as to how large an integer can be: you can always add one to any integer. The integer 8,389,354 in decimal is the same as the number 0x8002EA in hexadecimal notation, but is not the same as the byte string"8002EA", even though it looks the same and may well be stored in your computer in the same form.
You can increment the integer 8389354 to get 8389354+1=8389355 (0x8002EB); but you cannot "increment" the byte string "8002EA".On the other hand, you can concatenate the byte strings "8002" and "EA" to make "8002EA"; but the integers 8389 and 354 do not add to make 8389354.The byte string "00008002EA" is strictly not the same as "8002EA"; but the integers 0x008002EA and 0x8002EA are equal.
With RSA encryption, we typically want to encrypt a session key which is a bit string, but the RSA arithmetic c = m^e mod n is donewithintegers, so we need to represent the bit string as an integer first (in practice, we usually add some random bytes and other padding, but we'll ignore that for the time being).Once the RSA operation has been completed, we have another integer, c, but we need to store the result as a bit string, so we encode the integer as a bit (byte) string and passthat string onto our recipient.
Example: Suppose we wish to encrypt the 3-byte/24-bit key bit string "8002EA" using the RSA public key(n=25009997=0x017D9F4D, e=5)†. For simplicity in this insecure example, we will use the basic RSA algorithm with no padding.
- The message block is the byte string "8002EA".
- Compute the message representative
m = StringToInteger("8002EA") = 8389354
- Encrypt with the RSA algorithm
c = 8389354^5 mod 25009997 = 2242555
- Encode the result as a byte string
OB = IntegerToString(2242555, 4) = 002237FB
Note that the maximum length of the output block is 4 bytes, because the largest possible integer result is 0x017D9F4C (= n-1),which requires 4 bytes to store in encoded form.
† Thanks to "doctorjay" for pointing out that e=3 did not work for the earlier version of this example.
Implementation in C and VB
We show an example implementation of the RSA algorithm in C in our BigDigits library. It's not necessarily the most efficient way, and could be improved in its security, but it shows the maths involved. Look in theBigDigits Test Functions.
There is an example in VB6/VBA code at RSA and Diffie-Hellman in Visual Basic.
For a professional implementation, see our commercial CryptoSys PKI Toolkitwhich can be used with Visual Basic, VB6, VBA, VB2005+, C/C++ and C# applications. There are examples using the `raw' RSA functionsto carry outRSA Encryption andRSA Signing.
References
- [AX931]ANSI X9.31-1998Digital Signatures using ReversiblePublic Key Cryptography for the Financial Services Industry (rDSA),Appendix A,American National Standards Institute,1998.
- [CMS]RFC 5652.Cryptographic Message Syntax (CMS),R. Housley, September 2009 (obsoletes RFC3852, RFC3369, RFC2630).
- [CMSRSAKEM]RFC 5990Use of the RSA-KEM Key Transport Algorithm in the Cryptographic Message Syntax (CMS),J. Randall, B.Kaliski, J. Brainard, S. Turner.September 2010.
- [COCK73]Clifford Cocks. A Note on 'Non-Secret Encryption', CESG Research Report,20 November 1973.
- [EDIFACT]UN/EDIFACT Finance Group D6 SWG-F.Recommended Practice For Message Flow And Security For EDIFACT Payments, Version 2v03,1 October 2000.
- [FERG03]Niels Ferguson and Bruce Schneier,Practical Cryptography, Wiley, 2003.Note that this book has since been re-issued in 2010 almost unchanged asCryptography Engineeringby Niels Ferguson, Bruce Schneier and Tadayoshi Kohno.
- [KALI93]Burton Kalinski. Some Examples of the PKCS Standards, RSA Laboratories, 1999,<link>.
- [NIST-80057]NIST Special Publication 800-57,Recommendation for Key Management - Part 1: General (Revised),Elaine Barker et al,National Institute of Standards and Technology, March 2007.
- [P1363]IEEE P1363 Standard Specifications for Public Key Cryptography, IEEE,November 1993.
- [PKCS1]RSA Laboratories. PKCS #1 v2.1: RSA Encryption Standard. June 2002.Republished as RFC 3447.
- [RIVE78]R. Rivest, A. Shamir and L. Adleman.A Method for Obtaining Digital Signaturesand Public-Key Cryptosystems. Communications of the ACM, 21 (2), pp. 120-126,February 1978, <link>.
Author
The content of this page is all original work written by David Ireland,who reserves all intellectual rights.You may freely link to this page. You may use parts of the work for fair dealing for the purposes of research or private study as permitted undercopyright law,but you may not post any part of this content on another web site without the explicit permission in writing of the author.
Feedback
Contact us to give feedback or ask a question.To comment on this page,send us a message with rsa_alg
in the message and we'll add it to the comments.Please note we are not an oracle for college assignment questions. Your tutors read this page, too!
This page last updated 22 May 2014
Comments
123 comments so far