[nanomsg] Re: nanomsg and encryption

  • From: Paul Colomiets <paul@xxxxxxxxxxxxxx>
  • To: Martin Sustrik <sustrik@xxxxxxxxxx>
  • Date: Wed, 6 Mar 2013 22:36:22 +0200

Hi Martin,


On Wed, Mar 6, 2013 at 8:06 AM, Martin Sustrik <sustrik@xxxxxxxxxx> wrote:
>
>
>      Using the encrypted counter, rather that generating a random IV for
>>     each message makes the algorithm viable for scenarios with high
>>     message rate. If the IVs were generated randomly, we would soon run
>>     out of available randomness on the system. If, on the other hand, we
>>     had used pseudo-random IVs, it would make the scheme vulnerable to
>>     chosen plaintext attack.
>>
>>
>> I may be overly paranoid, but I'd change IV encryption key once a while
>> (say a minute or so).
>>
>
> I guess you are too paranoid. Assuming that the counter is encrypted (to
> give a non-predictable IV) using the same encryption algorithm that's used
> later on to encrypt the message itself, there are only two options:
>
> 1. The algorithm is secure => next IV is unpredictable & ecryption itself
> is secure.
> 2. The algortihm is unscure => next IV may be predicted & encryption
> itself may be compromised.
>
> In either case there's nothing to gain from generating new key
> periodicaly. (Except for the limit imposed by the algorithm itself, which
> is pretty high for algorthms like 256 bit AES.)
>
> On the other hand generating new keys requires randomness, which we may
>  quickly run out off if generating keys periodically. That in turn would
> lead to hanged up system.
>
> So, to prevent hang-ups in scenarios with a lot of sockets I would rather
> explore exactly the opposite direction: Generating the key only on library
> initialisation and not requiring more randomness for each nn_socket() call.
>
> Technically, what can be done is using just one key for all sockets,
> however, instead of using a single counter, use a pair of counters: socket
> counter + message counter. If we are using, say, 128 bit block cipher, each
> of the counters can be a 64 bit unsigned int, which is unlikely to
> overflow, ever.
>
>
Agreed.


>  The following options apply for
>> each socket. Options ordered from most secure one to the least secure
>> (IMO)
>>
>> 1. REQ:
>> a) Use public key to encrypt message. All repliers must have same
>> private key. Nor intermediaries, nor other requesters can't read a message
>> b) Use preshared key (use a separate request with asymmetric cipher to
>> establish a shared key): secures from intermediaries and other clients.
>> c) Use shared key: any replier can process request anyway, any client
>> may do this request too, securing only from intermediaries
>>
>> 2. REP:
>> a) Use a public key embedded inside a message to encrypt reply. Nobody
>> except requester can read the message.
>> b) Use preshared key: nobody except requester can decrypt the message
>> (restriction 1b applies too)
>> c) Use symmetric key embedded inside a message to encrypt reply.
>> Everybody who knows replier key, and captured request can also read a
>> reply
>> d) Use shared key (securing intermediaries only)
>>
>
> That leaves the question open of two business entities providing the same
> service. Would they have to share the same private key?
>
>
It's technically possible to do the same thing that's used for encrypting
storage. Let's imagine we have two business entities, having distinct keys
A and B. Let's encrypt each message with a fresh key K, and then prepend
encrypted message with key K encrypted with A, followed by key K encrypted
with B. The decryption algorithm first decrypts a key K by using it's own
key (A or B) and then decrypts a message by that key.

I speculate that's this way it's not practical to have a different key per
worker (too much keys to be embedded in each message), but may be ok if
there are just a few entities with different keys.


>
>  3. SURVEYOR: basically same as for REQ.
>>
>> 4. RESPONDENT: same as for REP, except I'm not sure 2b is at all possible
>>
>> 5. PUSH-PULL, SOURCE-SINK:
>> a) Use a public key, so different sources (or push sockets) can't
>> decrypt each other's data. All PULL sockets must be able do decrypt data
>> anyway
>> b) Use preshared key (same features like 5a, being faster, but with
>> complex connection establishment)
>> c) Use a shared key
>>
>> 6. PUB-SUB is the most complex one. There are all kind of the
>> combinations of the following options:
>> a) Use any of 5a, b, c and disable subscription forwarding
>> b) Separate topic and send plain-text  or using hop-by-hop encryption
>>
>
> I guess the separation of topic would have to be done anyway at some point.
>
>
Wow! You were strictly against that, when designing SP-proto. Did you
changed your mind, or you see it as a necessary evil for encryption? Does
API need to be changed for that?



>
>  In the end it very much depends on what your security definition is. For
>> example I vaguely imagine a practical situation where difference between
>> 2a and 2c is noticeable, but it's theoretically possible.
>>
>
>  Implementing a transport security may be selling feature but has
>> probably no really practical interest, because there are many solutions
>> for tunneling tcp connections (vpn, ssh to name a few), even hardware
>> ones.
>>
>
> Actually, people are asking for it (check ZeroMQ ML) -- I would say the
> feature is of little theorerical interest (it's doesn't really differ from
> a simple tunnelling solution), but in terms of usability it's highly
> desirable for the library to provide it itself.
>
>
Ok, may be I'm mistaken. Or may be people don't know what they need :)


>
>  I think the simple and safe solution is to implement shared keys,
>> disabling subscription forwarding. Public key encryption is useful, but
>> is very slow in a raw way. While I believe that it's technically
>> possible to create a symmetric key at connection establishment (like TLS
>> do), it would create very complex interactions with intermediaries, that
>> I don't think it's worthwhile.
>>
>
> My conclusion so far is that we need to understand the use cases better to
> be able to proceed. Once getting some basic understanding, we can write
> down the actual requirements for individual protocols. That in turn would
> lead to actual algorithms to use.
>

FYI, I don't need encryption myself.

-- 
Paul

Other related posts: