SignedSessionEncrypter

67 views
Skip to first unread message

Jay Tuley

unread,
Dec 28, 2012, 9:32:22 AM12/28/12
to keyczar...@googlegroups.com
I've talked about this before but haven't gotten an answer, there exists in the api SessionCrypter which uses a keypair to encrypt an aes and hmac key for exchange to then encrypt symmetrically and this is very clear and straight forward, however there also exist a more elaborate SignedSessionDecryptor/SignedSessionEncryptor which takes two keypairs, the ssencrypter has a public key for encrypting, and a private key for signing, the ssdecrypter has a private key for decrypting and a public key for verifying. The ssencrypter creates a session material that encrypts an aes key,hmac key and nonce. Then the ssencrypter  will encrypt, hmac tag and then private key sign with a digest that includes the hidden nonce.

What confuses me is what the additional mechanism are adding security wise, because from what i can tell the nonce is used per session rather than per encryption so it won't prevent replay attacks. The signing is done per encryption, but not done with the session material and the encryption is already authenticated and the session is what could benefit. From my perspective both of these mechanism are used in reverse of what I would expect. 

Now there is a request about how to use a SignedSessionEncryptor in .net, but I've avoided implementing it because of my lack of understanding as to why someone should choose to use this feature.

I would like to implement this feature, but I want to know if I should put in as a deprecated interoperability feature, as in just use it when you need to because soneone else already made the choice to do it? Or if these extra security mechanism are important and I'm just missing the reason and this should be a prominent api feature? Or my dissection of the API is missing the boat entirely in which i need clarification to implement it correctly?

Signed Session Encrypter and Decrypter


SignSessionCreateEncrypter(Publickey encrypter, Keypair signer)-> signed-session-enc, encrypted-aes-key-and-nonce
SignSessionCreateDecrypter(Keypair decrypter, Publickey verifier, encrypted-aes-key-and-nonce)-> signed-session-dec 

encrypted-aes-key-and-nonce format:Encrypt(Json(key: aeskeyjson, nonce:nonce))

Signing algorithm will receive [encrypt-header] + [raw-ciphertext]+ [auth-tag] + [nonce length] +[nonce] + [version byte]

signed-session-ciphertext format: [sign-header] + [(encrypt-header and raw-ciphertext and auth-tag) length] + [encrypt-header] + [raw-ciphertext]+ [auth-tag] + [raw-signature]

SignedSessionEncrypt(signed-session-enc, UTF8 plaintext)-> WebBase64 signed-session-ciphertext
SignedSessionEncrypt(signed-session-enc, byte[] plaintext)-> byte[] signed-session-ciphertext

SignedSessionDecrypt(signed-session-dec, WebBase64 signed-session-ciphertext)-> UTF8 plaintext
SignedSessionDecrypt(signed-session-dec, byte[] signed-session-ciphertext)-> byte[] plaintext

Andrew Sacamano

unread,
Jan 2, 2013, 12:02:45 PM1/2/13
to keyczar...@googlegroups.com
Hi Jay,

Ah - here's the start of the discussion. It seems to me like you've correctly understood the details of the operation of SignedSessionEncrypter / Decrypter. And it is indeed is meant for current use - it is not just for interoperability.

As for the motivation, I hope I can help. The core motivation is that RSA encryption / decryption is slow while AES is fast.

So SessionDecrypter will create a shared AES key that is protected by RSA encryption that can then be used to encrypt a lot of data relatively quickly. However, since only the public RSA key is needed to establish the session, the sender could be anybody. SignedSessionEncrypter goes the next step - by including a signature with each piece of data, so you know who encrypted it.

So when you say "the encryption is already authenticated", that is only partly right: it is already authenticated as part of the session, but it is not authenticated as coming from a known party.  One could argue that signing each piece of data is unnecessary, if the session material itself was signed, but signing each piece of data proves authenticity directly, instead of requiring it to be inferred, thus limiting the attack surface.

As for the nonce, it is not there to prevent replay attacks, it is required as part of the signing / verification process.

Neither SessionDecrypter nor SignedSessionDecrypter will prevent replay attacks. Since they only support one-way communication, the receiver gets the data from the sender with no possibility of providing some kind of once-per-transaction salt. Replay prevention has to be handled elsewhere in the protocol (by, for example, asking the sender to create a unique ID and having the receiver store the IDs for comparison.)

Happy to discuss more, particularly if I've misunderstood something myself.

Cheers,

Andrew







Jay Tuley

unread,
Jan 2, 2013, 3:30:37 PM1/2/13
to keyczar...@googlegroups.com
On Wed, Jan 2, 2013 at 11:02 AM, Andrew Sacamano <at...@google.com> wrote:
Hi Jay,

Ah - here's the start of the discussion. It seems to me like you've correctly understood the details of the operation of SignedSessionEncrypter / Decrypter. And it is indeed is meant for current use - it is not just for interoperability.

That's good to know.
 

As for the motivation, I hope I can help. The core motivation is that RSA encryption / decryption is slow while AES is fast.

So SessionDecrypter will create a shared AES key that is protected by RSA encryption that can then be used to encrypt a lot of data relatively quickly. However, since only the public RSA key is needed to establish the session, the sender could be anybody. SignedSessionEncrypter goes the next step - by including a signature with each piece of data, so you know who encrypted it.

So when you say "the encryption is already authenticated", that is only partly right: it is already authenticated as part of the session, but it is not authenticated as coming from a known party.  One could argue that signing each piece of data is unnecessary, if the session material itself was signed, but signing each piece of data proves authenticity directly, instead of requiring it to be inferred, thus limiting the attack surface.

Okay, I can see that if the session material were signed, that only relying on the MAC could allow forging from the sender if the recipient's private crypt key was compromised. However, the session material is not signed, so even though you can't forge encrypted messages from the sender, an attacker can forge session material without any secrets compromised, which seems kind of arbitrary and unexpected. But I guess when thinking of it this way, I can think of not signing the SessionMaterial as a bug, rather than a design choice.  Thoughts?
 
As for the nonce, it is not there to prevent replay attacks, it is required as part of the signing / verification process.

Neither SessionDecrypter nor SignedSessionDecrypter will prevent replay attacks. Since they only support one-way communication, the receiver gets the data from the sender with no possibility of providing some kind of once-per-transaction salt. Replay prevention has to be handled elsewhere in the protocol (by, for example, asking the sender to create a unique ID and having the receiver store the IDs for comparison.)

Well I'd really like to know, what the intended purpose of the nonce is. It's used in the signing, but is it to keep signed data from one session from being verified in a different session?  The MAC is going to do that too. Maybe the design of this api is just ignoring the fact that there is a MAC? It seems pretty wasteful, but I guess i can understand that. I just want to make sure I have a clear understanding, so i can convey appropriately in the API.
 

Happy to discuss more, particularly if I've misunderstood something myself.

Thanks for responding, discussing this is helpful.  

-Jay

Andrew Sacamano

unread,
Jan 2, 2013, 4:33:36 PM1/2/13
to keyczar...@googlegroups.com
On Wed, Jan 2, 2013 at 1:30 PM, Jay Tuley <j...@tuley.name> wrote:

As for the motivation, I hope I can help. The core motivation is that RSA encryption / decryption is slow while AES is fast.

So SessionDecrypter will create a shared AES key that is protected by RSA encryption that can then be used to encrypt a lot of data relatively quickly. However, since only the public RSA key is needed to establish the session, the sender could be anybody. SignedSessionEncrypter goes the next step - by including a signature with each piece of data, so you know who encrypted it.

So when you say "the encryption is already authenticated", that is only partly right: it is already authenticated as part of the session, but it is not authenticated as coming from a known party.  One could argue that signing each piece of data is unnecessary, if the session material itself was signed, but signing each piece of data proves authenticity directly, instead of requiring it to be inferred, thus limiting the attack surface.

Okay, I can see that if the session material were signed, that only relying on the MAC could allow forging from the sender if the recipient's private crypt key was compromised. However, the session material is not signed, so even though you can't forge encrypted messages from the sender, an attacker can forge session material without any secrets compromised, which seems kind of arbitrary and unexpected. But I guess when thinking of it this way, I can think of not signing the SessionMaterial as a bug, rather than a design choice.  Thoughts?

Hmm.  I wasn't in on the design process, so I'm just speculating.  I would imagine the thinking was that the authenticity of the payload was the important part, and that given that the payload signature could be verified, signing the session material also felt redundant. But like I said, I'm speculation now.

 
As for the nonce, it is not there to prevent replay attacks, it is required as part of the signing / verification process.

Neither SessionDecrypter nor SignedSessionDecrypter will prevent replay attacks. Since they only support one-way communication, the receiver gets the data from the sender with no possibility of providing some kind of once-per-transaction salt. Replay prevention has to be handled elsewhere in the protocol (by, for example, asking the sender to create a unique ID and having the receiver store the IDs for comparison.)

Well I'd really like to know, what the intended purpose of the nonce is. It's used in the signing, but is it to keep signed data from one session from being verified in a different session?  The MAC is going to do that too. Maybe the design of this api is just ignoring the fact that there is a MAC? It seems pretty wasteful, but I guess i can understand that. I just want to make sure I have a clear understanding, so i can convey appropriately in the API.

You've moved beyond the limits of what I know - but my suspicion is that this would provide some protection against attacks on the sender's signing key (particularly chosen-plaintext attacks ) by the recipient.


Andrew Sacamano

unread,
Jan 2, 2013, 4:37:28 PM1/2/13
to keyczar...@googlegroups.com
On second thought - that doesn't make much sense - the recipient gets the nonce. Hmm...

James Tuley

unread,
Jan 2, 2013, 10:45:29 PM1/2/13
to keyczar...@googlegroups.com
On Jan 2, 2013, at 3:33 PM, Andrew Sacamano <at...@google.com> wrote:

On Wed, Jan 2, 2013 at 1:30 PM, Jay Tuley <j...@tuley.name> wrote:

As for the motivation, I hope I can help. The core motivation is that RSA encryption / decryption is slow while AES is fast.

So SessionDecrypter will create a shared AES key that is protected by RSA encryption that can then be used to encrypt a lot of data relatively quickly. However, since only the public RSA key is needed to establish the session, the sender could be anybody. SignedSessionEncrypter goes the next step - by including a signature with each piece of data, so you know who encrypted it.

So when you say "the encryption is already authenticated", that is only partly right: it is already authenticated as part of the session, but it is not authenticated as coming from a known party.  One could argue that signing each piece of data is unnecessary, if the session material itself was signed, but signing each piece of data proves authenticity directly, instead of requiring it to be inferred, thus limiting the attack surface.

Okay, I can see that if the session material were signed, that only relying on the MAC could allow forging from the sender if the recipient's private crypt key was compromised. However, the session material is not signed, so even though you can't forge encrypted messages from the sender, an attacker can forge session material without any secrets compromised, which seems kind of arbitrary and unexpected. But I guess when thinking of it this way, I can think of not signing the SessionMaterial as a bug, rather than a design choice.  Thoughts?

Hmm.  I wasn't in on the design process, so I'm just speculating.  I would imagine the thinking was that the authenticity of the payload was the important part, and that given that the payload signature could be verified, signing the session material also felt redundant. But like I said, I'm speculation now.

Might feel redundant, but an attacker creating session materials to interfere with an authenticated sender's messages decrypting is more direct threat than an attacker having access to the  recipient's private key thus compromising the HMAC key.  But this helped me see the usefulness of signing each message and thus i was able to add compatible signing to the to the C# SessionCrypter class while allowing the session material to be signed as well when using the unofficial bison keypacker with minimal changes.


 
As for the nonce, it is not there to prevent replay attacks, it is required as part of the signing / verification process.

Neither SessionDecrypter nor SignedSessionDecrypter will prevent replay attacks. Since they only support one-way communication, the receiver gets the data from the sender with no possibility of providing some kind of once-per-transaction salt. Replay prevention has to be handled elsewhere in the protocol (by, for example, asking the sender to create a unique ID and having the receiver store the IDs for comparison.)

Well I'd really like to know, what the intended purpose of the nonce is. It's used in the signing, but is it to keep signed data from one session from being verified in a different session?  The MAC is going to do that too. Maybe the design of this api is just ignoring the fact that there is a MAC? It seems pretty wasteful, but I guess i can understand that. I just want to make sure I have a clear understanding, so i can convey appropriately in the API.

You've moved beyond the limits of what I know - but my suspicion is that this would provide some protection against attacks on the sender's signing key (particularly chosen-plaintext attacks ) by the recipient.

I'm pretty much special casing the nonce for compatibility in my initial implementation at this point, but I'd like a solid idea of its purpose before stabilizing it though, if anyone has any ideas?
Reply all
Reply to author
Forward
0 new messages