49

I have code to encrypt data using a public key and decrypt it using a private key. This is useful when a client wants to send data to a server and know that only the server can decrypt it.

But say I want the server to encrypt data using the private key and decrypt it using the public key, as a way of distributing data that can be verified to have come from the right server. Rather than modify the code to allow this, can I simply publish the private key and keep the public key secret? Does this affect the security of the system?

Graeme Perrow
  • 592
  • 1
  • 4
  • 7
  • The short answer no. Really yes, but functionally no. There are some folks here better suited to describing the internals of crypto than I am, and I'll try and point this question out to them. – Jeff Ferland Dec 21 '11 at 15:47
  • 2
    The feature you are looking for is basically digital signing. – Soumya Kanti May 22 '18 at 05:27

4 Answers4

58

But say I want the server to encrypt data using the private key and decrypt it using the public key, as a way of distributing data that can be verified to have come from the right server.

You can do this - this is, at a very simplistic level, how RSA signing works (note, simplistic - there is a bit more to it).

Rather than modify the code to allow this, can I simply publish the private key and keep the public key secret? Does this affect the security of the system?

You don't need to publish the private key at all - RSA is a trapdoor permutation which means:

  • If you encrypt with a public key, you can decrypt with the private key.
  • If you encrypt with a private key, you can decrypt with a public key.

Thus, RSA supports doing both signing and encryption relying on the end user having only the public key.

In your case, if the client wishes to verify data came from the server, you apply the second case of RSA and decrypt the signature data using the public key you already have.

Furthermore, because it is a permutation, you shouldn't need to modify your code at all. Both keys should work using the same function. I would expect any decent crypto library would have APIs for verifying signatures according to the varying standards that exist - one of these would probably be a good bet.

RSA Labs provide a nice explanation of this.

If you want to extend this between servers, or verify client communication - generate keys for each entity and swap the public ones. The process can then be used at both ends.

Theoretically speaking, e and d are interchangeable (which is why RSA works)(one must be designated secret and kept secret) but p and q must always be kept secret as these allow you to derive d from e and vice versa. However, you need to be extremely careful in your understanding of the private key - does your software store p/q in the private key? If so, you can't publish it as is. Also, when I say interchangeable - once you publish one of that pair (e or d along with your modulus n) you must guard the other with your life. Practically speaking as Graeme linked to in the comments e is often chosed as a small/fixed value. My comment on e/d being interchangeable clearly does not apply when e is easily determined. Doing this sort of thing therefore has the potential for confusion and mis-implementation. Use a third-party library/don't start publishing private keys.

Pablo A
  • 123
  • 5
  • We are using a third-party library to do the crypto, and it does have APIs to do it the "right" way. However, our code as it exists now only uses the "encrypt-with-public" and "decrypt-with-private" APIs. I could change the code to also use the "encrypt-with-private" and "decrypt-with-public" APIs but would like to avoid changing the code if I can. I know I should generally not publish the private key but I want to know if publishing the private key while __keeping the public key secret__ is still secure. – Graeme Perrow Dec 21 '11 at 17:30
  • 4
    The answer to that depends on what you include with your public key. Your public key usually comprises e,n and your private key d,p,q in which case the answer is unequivocally no, it is not secure to publish the private key. However, if you kept e secret, you could publish d and n. So, that's where Jeff Ferland's "sort-of-but-no" comes from. For practical purposes, I'd go with a code change. –  Dec 21 '11 at 17:34
  • 2
    Thanks. Given your answer plus [this stackoverflow answer](http://stackoverflow.com/questions/696472/given-a-private-key-is-it-possible-to-derive-its-public-key) on how easy it is to derive the public key from the private key, it looks like the code change is the better idea. – Graeme Perrow Dec 21 '11 at 17:42
  • That's a good point - my comment on e/d being swapped does not apply to practical examples at all. I'll edit this into the answer too, thanks. –  Dec 21 '11 at 17:48
  • Original page for RSA Labs explanation disappeared, here's the Wayback Machine link: https://web.archive.org/web/20120722014120/http://www.rsa.com/rsalabs/node.asp?id=2182 – StanTastic Jun 12 '17 at 10:16
  • 1
    **WARNING**: Signing is not same as "encrypting with private key". See [this](https://www.gnupg.org/gph/en/manual/x135.html), [this](https://security.stackexchange.com/questions/9260/sha-rsa-and-the-relation-between-them#answer-9265), [this](https://security.stackexchange.com/questions/68822/trying-to-understand-rsa-and-its-terminology/68836#answer-68836), [this](https://cs.stackexchange.com/questions/59675/can-a-public-key-be-used-to-decrypt-a-message-encrypted-by-the-corresponding-pri#answer-59695) – wha7ever Aug 10 '17 at 15:51
10

Yes you can encrypt using a private key and decrypt using a public key, do NOT hand out your private key (private keys can generate public keys, and your entire encryption system is now useless), I'm assuming you want to do something like this:

Server encrypts data, sends it to clients.

Clients have public key, and can decrypt data from the server.

Under this circumstance, it would make sense, if the server is doing both the encryption and decryption, I have no clue why you'd want an asymmetric crypto implementation.

The rule always applies though: private key stays private and doesn't leave the server.

StrangeWill
  • 1,603
  • 8
  • 13
3

But say I want the server to encrypt data using the private key and decrypt it using the public key:

The server can encrypt data using its private key and the receiver can decrypt using the servers public keys, this is possible. However, this scenario is used to digitally sign a document and as you say its "a way of distributing data that can be verified to have come from the right server", as only the corresponding key (public key of the server) could be used to decrypt the data. The public key of the server is verified by the corresponding digital certificate generated and digitally signed by the server.

can I simply publish the private key and keep the public key secret?

You should never publish the private key, as the name suggests.

Does this affect the security of the system?

Yes, also this system is not viable, for example, if you are using Diffie-Hellman (one of the most widely used key exchange protocol), the server and all the clients have to share public values, that are used to calculate session keys. So if you as a user publish your private key, it's very easy to calculate public key, which is not possible or very difficult the other way round.

0

I don't know if you could encrypt with the private key and decrypt with the public key, but if you could, then it wouldn't be very secure, since the decryption key is public - your private key should be kept private.

If you merely wish to verify that the sender of the message, then instead you sign the data using the sender's private key, and the recipient verifies the signature using the sender's public key.

If you wish to both encrypt the data and verify the sender, you encrypt and sign, neither of which requires exposing the private key.

hmallett
  • 193
  • 7
  • 4
    It's not meant for _encryption_ really, it's meant as a form of digital signing. The decryption key is _supposed_ to be public so anyone can decrypt it. The point is that they know that if they can successfully decrypt it, then _only_ the server could have encrypted it. My question is not "can this be done", but can I reverse the values of the private and public keys (i.e. publish the private key and keep the public key secret) and still be secure? – Graeme Perrow Dec 21 '11 at 16:59