# How is a public key actually used to encrypt something?

One thing cryptography articles never seem to explain is how the message actually gets encrypted. You get this long-winded lecture on number theory which ends with, Ta Da! and we have a public and private key. Then, they never explain the process of exactly how some 100,000 byte word document gets encrypted using the public key.

Other times the explanations seem downright misleading. For example, in my book Cryptography (by Meyer and Matyas) it says for RSA the ciphertext is the plain text to the power of key. How do you exponentiate a word document? I don't get it.

• – user991 Mar 12 '14 at 1:18
• How do you exponentiate a word document? A word document is but a series of bytes. When doing encryption you don't care about the underlying format, you treat it as a big number, like the letter A is the number 65 in ASCII. Go grab the nearest Word doc in your system and look for file size in bytes in the properties: You'll get the number $n$. If you decide to encrypt it with textbook RSA, you will have a $8n$-bits long number in your hands. – rath Mar 12 '14 at 1:23
• How do you exponentiate a word document? You don't! – fgrieu Mar 13 '14 at 15:40

Rick Demer already wrote the answer in the very first comment, but without explanation: Hybrid encryption.

But since you asked for a real practical example to encrypt your word document, this is how: Your file is on your disc, and it is 100,000 byte large. You can then do:

• First, you start up a random number generator. Preferably you should either have true randomness or at least a cryptographically secure RNG.
• Let the RNG generate a random 256 bit number.
• Start up your AES 256 engine/program/hardware module, and choose the appropriate mode of operation like CBC. Use the random number as key.
• Use AES to encrypt the entire content of the file.
• Get your public key or generate private/public key, depending on what you want to do.
• Encrypt the random number (used as symmetric key) with your asymmetric encryption scheme. In the case of RSA, do not just use the textbook variant but RSA-OAEP or a similar padding scheme.
• Create a new file: Put relevant information in the file header (whatever you want to be accessible without decryption). In the data of the file, write down the encrypted random number (it was encrypted with the public key), and then you just add the entire encrypted file-content (encrypted with AES).
• Optional: You can add delimeters inside your file to make it easier to see where the key ends and where the ciphertext starts. If you want you can also note down which algorithms you actually used to encrypt this specific file.

AES can obviously be replaced with any other symmetric cipher, you can also pick a different mode of operation or use a specific asymmetic encryption scheme to encrypt the random key. If you do so, putting it into the file might help if you ever forget which file was encrypted with which algorithm.

Note on using asymmetric encryption directly

It is also possible to use for instance RSA directly on your $100,000$ byte document. If your RSA key is $1240$ bit long, then you can split your document into $800$ blocks with each block having $1000$ bit (or e.g. $650$ blocks of $\approx 1231$ bits, whatever suits you). Then you can apply RSA directly to each block and be done with it. The problem is that this is extremely slow. The ratio of processed bits per second is magnitudes lower for asymmetric encryption than for symmetric encryption. And then you have the problem, that RSA shouldn't be used in the textbook variant and RSA-OAEP increases the length.

• Thank you. I don't understand why other people have this mental block about actually explaining how this works. I think its because they don't know themselves in many cases. – Tyler Durden Mar 12 '14 at 16:52
• I've added a comment about padding at that point. – tylo Mar 13 '14 at 12:42
• This is great recipe to make... insecure implementation. Don't roll your own or you will end up with mistakes like here: malleable encryption. – axapaxa Dec 7 '16 at 23:27
• @axapaxa There are a lot of possible things that can go wrong. But with straight hybrid encryption using AES and RSA-OAEP malleable encryption is not one of them. And the "don't implement it yourself" usually refers to implementing encryption methods or designing entirely new protocols. Implementing a generally accepted protocol by utilizing proper cryptographic implementations and abiding their assumptions is quite different. – tylo Dec 8 '16 at 11:29
• @tylo please do explain how AES-CBC (which is proposed in this answer) is not malleable in this case. Implementing generally accepted protocol is usually subject to side-channel attacks, therefore one shouldn't implement it on his own. Especially RSA and AES which are both very prone to side-channels. – axapaxa Dec 8 '16 at 12:44

Well, exponentiating a word document is rather easy. As you've said, it's $100,000$ bytes, or $800,000$ bits. This word document can thus be interpreted as a number between $0$ and $2^{800,000}$. Sure this number may be large, but it can be exponentiated.

However, more commonly symmetric encryption is used with a $128$ or $256$ bit key to encrypt the word document, and then public-key encryption is used on that key, as number between $0$ and $2^{256}$. This approach is much faster.

• What do you mean by "symmetric encryption"? Spell it out for me, how is the document encrypted? – Tyler Durden Mar 12 '14 at 2:38
• @TylerDurden A form of encryption where you have a small shared secret (the private key - there is no public key), and use that small shared secret to encrypt any amount of data. Examples of such algorithms include AES, Salsa20, and more historic examples are Blowfish and (3)DES. – orlp Mar 12 '14 at 3:04
• The details of symmetric algorithms are much more complicated than something like RSA, where encryption is "simply" exponentiation. For instance, the ChaCha20 paper describes a function (in section 2) that gets repeatedly applied to the plaintext. – Stephen Touset Mar 12 '14 at 6:33
• What is described in the first paragraph of the answer A) is never done; B) would not work at all with common RSA key size, it would require special ones with at least a 800,001-bit modulus; C) slows decryption (making it about a million times slower than for common RSA key size, assuming 2-primes RSA and classical algorithms); D) would not be secure unless random padding is thrown in (without it, knowing a reference plaintext, it would be possible to guess a plaintext with only a small change). – fgrieu Mar 13 '14 at 12:05
• @fgrieu I was only explaining to the asker how it would be possible to exponentiate a word document, I did not mean to suggest that it's either secure or practical. – orlp Mar 14 '14 at 12:21

This post covers RSA, other algorithsm will likely have similar considerations but the details may be different.

For textbook RSA the "message" is a number. Due to the use of modular arithmetic this number must be smaller than the modulus.

We can obviously take a sufficiently short sequence of bytes and encode it as a number. However textbook RSA has a number of security concerns, most obviously that since it's determinitic an attacker can guess the message and validate wheher their guess was correct but also some more subtule cases.

To avoid these issues a randomised padding scheme is used. There are several such schemes but I belive OEAP is considered the modern standard. OEAP combines the message with a random number and then subjects the combination to an all-or-nothing transform.

That doesn't work for large messages though, a typical RSA key has a 1024-4096 bit modulus. Add some overhead for padding and even with a 4096 bit key you are talking about a message length limit of arround 5000 bytes.

You could split a large mesage into chunks, encrypt them seperately and then chain together the result but this would be space-inefficient due to seperate randomised padding for each chunk. It would also be slow.

So in practice we encrypt the message with a symetric encryption algorithm and a randomly generated key. We then apply the random padding to the key and encrypt the padded key using RSA with they public key.

One thing cryptography articles never seem to explain is how the message actually gets encrypted.

Then, they never explain the process of exactly how some 100,000 byte word document gets encrypted using the public key.

You break up the document into blocks of a particular byte size. Treat each block as a series of bits. That's a number. Feed the number into the crypto algorithm, get a number back out. That's also a series of bits. Now you have turned a series of plaintext blocks into a series of encrypted blocks.

Other times the explanations seem downright misleading. For example, in my book Cryptography (by Meyer and Matyas) it says for RSA the ciphertext is the plain text to the power of key. How do you exponentiate a word document?

If you really want to see how it works in practice then I encourage you to read the source code. For example, download the source code for BouncyCastle and take a look at the GetInputBlockSize, GetOutputBlockSize, ConvertInput, ConvertOutput and ProcessBlock methods in the RSACoreEngine.cs file. This is only 150 lines of pretty easy-to-follow code but it answers all your questions.

As others have mentioned, it is often impractical to use public key crypto on large documents because the math is slow. Usually what you do is choose a symmetric cryptosystem, choose a random key in that cryptosystem, encrypt the document in that cryptosystem, encrypt the symmetric key using the public key. Now the document cannot be decrypted without the symmetric key, and the symmetric key cannot be decryped without the private key.

• This answer is wrong. It suggest to apply the asymmetric algorithm to blocks of plaintext small enough to make the interpretation of that as a number suitable for computation. A) That's practically never done in serious systems. B) That's unsafe unless random padding is added (which goes against this description, because with usual padding schemes, plaintext blocks only become a number after padding); in particular, knowing one plaintext, it becomes trivial to recognize that another plaintext is identical in the first block. C) We have more efficient methods based on hybrid encryption. – fgrieu Mar 13 '14 at 12:18
• @fgrieu: Perhaps you stopped reading before my last paragraph? – Eric Lippert Mar 13 '14 at 14:00
• The last paragraph says of the part that I criticize " it is often impractical ", citing a performance reason; that's very different from saying: doing it is never done in standard applications, including for security reason, which would be more accurate. I criticize: " You break up the document into blocks of a particular byte size. Treat each block as a series of bits. That's a number. Feed the number into the crypto algorithm, get a number back out. That's also a series of bits. Now you have turned a series of plaintext blocks into a series of encrypted blocks. " – fgrieu Mar 13 '14 at 14:37
• @fgrieu: Of course you are right that in practice, no one uses asymmetric crypto for large documents. But let's not forget that the original poster's question shows that they do not understand even how the document can be made into numbers in the first place. We have a beginner here; let's concentrate on the basics rather than getting off into the weeds of all the pragmatic defenses against real-world attacks. That can come later. – Eric Lippert Mar 13 '14 at 14:41
• BouncyCastle and others unify all cryptographic methods into a single do-it-all API capable of enciphering arbitrary data with any algorithm, including unsuitable for that purpose. That's over-engineering in my opinion, for it becomes all too easy to misuse the API to do non-standard, unsafe and inefficient things, including just what I criticize in your answer. A different example occurred in a recent question where Java's API allowed use of a private RSA key with encryption padding, which is unsafe. – fgrieu Mar 13 '14 at 15:07