0
$\begingroup$

I'm protecting communication between some microservices using public/private key encryption, where the sending container has a public key and the receiving container has a private key. This both verifies the sender (only sender has the public key via a credential manager), and protects the data in case it may be buffered, e.g. in a Redis.

But for transient communication, I'm wondering if signing is really what I should be doing instead of encrypting. I only need to verify the source container, the data isn't potentially stored anywhere, and I trust the AWS VPC network traffic to not be intercepted.

So the question is, are signing and encrypting computationally equivalent? If signing costs the same as encrypting the data, I'd just encrypt it. But if signing is much cheaper than encrypting, I might choose to just sign for some communication.

For reference, this is in Go, and encryption is done with ParsePKIXPublicKey() and EncryptPKCS1v15(), and decryption is done with ParsePKCS8PrivateKey() and DecryptPKCS1v15().

$\endgroup$
8
  • 2
    $\begingroup$ "only [some smurf] has the public key": This is a contradiction in terms! If something is public, attackers should be assumed to know it! $\endgroup$
    – fgrieu
    Nov 29, 2022 at 17:04
  • $\begingroup$ Maybe this question should be move to security.SE? $\endgroup$
    – A. Hersean
    Nov 29, 2022 at 17:09
  • 2
    $\begingroup$ @A.Hersean: I only migrate questions that have matured to the point of being consistent. Here we have that public key which is not; use of "signing" when the primitives used and the text suggest asymmetric encryption; no indication of the direction of the data to protect; no definition of "protect" in the first place (authentication and/or confidentiality); no indication of if the context allows to negotiate a key using asymmetric cryptography and reuse it with symmetric crypto, e.g. AES-GCM. Also, the title suggest something on-topic, so no urge to migrate. $\endgroup$
    – fgrieu
    Nov 29, 2022 at 17:17
  • 4
    $\begingroup$ @ Per: it's extremely un-academic, and possibly dangerous, to have a design relying on the assumption that "The public key isn't public". Beside the contradiction in terms, it's not a design goal of cryptographic protocols and implementations to keep public keys confidential, and there sometime are ways to deduce a public key by observing exchanges (e.g. that's easy when observing PKCS1-v1_5 signatures of two known messages). There are several other issues with the question, including not defining if "protect" has goals authentication and/or confidentiality; and if that's in both directions. $\endgroup$
    – fgrieu
    Nov 29, 2022 at 17:47
  • 1
    $\begingroup$ @fgrieu But it's stated clearly that it's in one direction, between exactly two services. And keep in mind that any signing key or API key would be equally vulnerable to a compromise of microservice A, which in ANY world reveals the necessary codes to communicate with microservice B. Please accept the assertion that the public key is only known to microservice A, delivered by a VPC key manager based on container IAM roles. Only microservice A running in the correct environment can obtain the public key. Please realize that if we doubt the key manager and IAM, we have another kind of problem. $\endgroup$
    – Per
    Nov 29, 2022 at 18:08

1 Answer 1

3
$\begingroup$

Signing and encrypting are not interchangeable: they have different purposes.

If you need authentication of a user or a service, then sign. If you need authentication of data, you can sign it or use a MAC (message authentication code).

If you need confidentiality, then encrypt the data.

If you need both authenticity and confidentiality, you have to encrypt the data then sign (or mac) the encrypted data.


Performance-wise, symmetric encryption usually use the AES-NI instructions of the server's CPU, which makes this operation extremely fast, oftentimes it's not even noticeable over the transmission delay.

Asymmetric encryption/decryption needs to first encrypt/decrypt the symmetric key, before encrypting/decrypting the data. This encryption/decryption of the symmetric is roughly equivalent to a signature operation.

Signature and asymmetric encryption are comparatively much slower than symmetric encryption. Depending on the algorithm used, its impact can be quite noticeable. Depending on the algorithm used, MACs computation can be hardly noticeable, for example in the AES-GCM algorithm, or they can necessitate a second pass on the data and double the encryption time.

$\endgroup$
4
  • $\begingroup$ Not completely answering the question, but closer. You have to imagine a public key only held by microservice A and a private key only held by microservice B and unidirectional traffic. In this scenario, the possession of the public key verifies the identify of the sender. But so does signing with reversed keys. This is why the question is straight-up whether the signing operation or the encryption operation is more expensive. "Public" key doesn't mean everyone has it, it only means that one microservice has it, beamed into it by a credential manager. $\endgroup$
    – Per
    Nov 29, 2022 at 17:34
  • 1
    $\begingroup$ @Per: "whether the signing operation or the encryption operation is more expensive" depends enormously on if you are considering symmetric or asymmetric encryption. Cost of DecryptPKCS1v15 is comparable to the cost of RSA signature. Cost of EncryptPKCS1v15 is typically 10 to 500 times lower, and comparable to RSA signature verification. Symmetric encryption/decryption/authentication is much faster, and does not have the message size limitation of EncryptPKCS1v15 (245 bytes with 2048-bit RSA, or like 240 bytes if we want a modern security level). $\endgroup$
    – fgrieu
    Nov 29, 2022 at 18:07
  • $\begingroup$ Asymmetric. If we accept the assertion that only two services have half a key, then the question is the comparative cost of encryption with a public key and decrypting with a private key, versus reversing the keys, signing with a private key and verifying with a public key. The point is that if microservice G is compromised, it doesn't yield the tools to send to microservice B as microservice A. $\endgroup$
    – Per
    Nov 29, 2022 at 18:13
  • $\begingroup$ But truly, I might not be gaining anything over symmetric. If the public key on service A is compromised, you can send to service B. And if the private key on service B is compromised, you can make a new public key and send as that. In at least that way, the point is moot. $\endgroup$
    – Per
    Nov 29, 2022 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.