The Basics Generating Keys

200 the clients private key. If both parties can verify the signature on the public key theyve received, they can be sure that there is no man-in-the-middle. What weve just described is known as two- way authentication, because each party independently verifies the other.

8.4 RSA

Invented in 1977, RSA was the first public key algorithm capable of both digitally signing and encrypting data. Despite the fact that it was patented, it became the de facto public key algorithm. Almost any company that used public key cryptography in their products licensed the technology. It was patented only in the United States, and the patent expired on September 20, 2000. Like other public key algorithms, RSA employs a public and private key pair. Although the mathematics behind the algorithm are easy to understand, we wont discuss them here. Many other texts explain the algorithm in detail. For our purposes, it is sufficient to say that the algorithms strength lies in the infeasibility of factoring extremely big numbers, and after 25 years of extensive cryptanalysis, it remains unbroken.

8.4.1 The Basics

Just like the low-level interfaces to Diffie-Hellman and DSA, the low-level interface to RSA provided by OpenSSL consists of an RSA structure and a set of functions that operate on that structure. The RSA structure and functions are made accessible by including the opensslrsa.h header file. The RSA structure itself contains many data members that are of little or no interest to us, but five members are important, as shown in the following abbreviated RSA structure definition: typedef struct rsa_st { BIGNUM p; BIGNUM q; BIGNUM n; BIGNUM e; BIGNUM d; } RSA; The p and q members are both randomly chosen large prime numbers. These two numbers are multiplied together to obtain n , which is known as the public modulus. References to the strength of RSA actually refer to the bit length of the public modulus. Once the private key has been computed, p and q may be discarded, but they should never be disclosed. However, keeping the values for p and q around is a good idea; having them available increases the efficiency with which private key operations are performed. The e member, also known as the public exponent, should be a randomly chosen integer such that it and p-1q-1 are relatively prime. Two numbers are relatively prime if they share no factors other than one; they may or may not actually be prime. The public exponent is usually a small number, and in practice, is usually either 3 or 65,537 also referred to as Fermats F4 number. Using e , p , and q , the value of d is computed. Together, the n and e members are the public key, and the d member is the private key.

8.4.2 Generating Keys

201 The RSA algorithm does not require parameters to generate keys, which makes key generation a much simpler affair. OpenSSL provides a single function to create a new RSA key pair, which will create a new RSA object that is initialized with a fresh key pair. RSA RSA_generate_keyint num, unsigned long e, void callbackint, int, void , void cb_arg; num Specifies the number of bits in the public modulus. The minimum this should be to ensure proper security is 1,024 bits, though we recommend 2,048 bits. e The value to use for the public exponent. OpenSSL does not attempt to generate this value randomly, but instead requires you to specify it. You may specify any number you like, but we recommend that you use one of the two constants, RSA_3 or RSA_F4 . callback A pointer to a function that will be called during the prime generation process to report the status of the prime generation. The callback is the same as the callback used by BN_generate_prime , which we discussed in Chapter 4 . This argument may be specified as NULL if no callbacks are desired. cb_arg A pointer to application-specific data. OpenSSL does not use this value for anything itself. It is used only when passed as an argument to the specified callback function. Once keys are generated, it is a good idea to call RSA_check_key to verify that the keys generated by RSA_generate_key are actually usable. The function requires an RSA object as its only argument. The RSA object should be completely filled in, including values for its p , q , n , e , and d members. If the return value from the function is 0, it indicates that there is a problem with the keys, and that they should be regenerated. If the return value from the function is 1, it indicates that all tests passed, and that the keys are suitable for use. If the return value from the function is - 1, an error occurred in performing the tests. When the RSA key is no longer needed, it should be freed by calling RSA_free and passing the RSA object as its only argument.

8.4.3 Data Encryption, Key Agreement, and Key Transport