Open yilunzhang opened 5 years ago
Why do you want to sign after encryption? Wouldn't it be better to sign plaintext and then encrypt both plaintext and signature? This adds plausible deniability to the client that sent a message. No one else (but the intended recipient) can proof or deny the authenticity of that message.
I think this depends on what attack model we have. Encrypt first allows node to verify the msg and thus prevent client from sending spam message with other people's pk. These spam message will of course be rejected anyway by the receiver client, but being able to verify it by anyone allows us to drop those msg in advance and prevent them from consuming resources.
Other than this reason I think sign and encrypt is generally safer. It prevents someone from changing the msg sender and signature together.
Ideally we sign-encrypt-sign is probably safest but that seems to be too heavy.
Oh I forget to consider signature chain here. Considering that we have the signature chain, just doing encryption on the client level protocol should be enough, because sigchain contains msg hash and client signature, which can guarantee the msg integrity.
If given that we don't want to change sigchain scheme and want to prevent anyone from changing the msg sender and signature together, we can add the sender's pk (not signature) to the msg itself before doing encryption.
How exactly does sig chain work? I thought that it is a special transaction that you commit to blockchain for mining/useful proof of work purposes.
Anyway, how does the receiving client get the sigchain of that message? And how/where does the sending client signs the message? I don't think there is even a field present right now for client's signature
Sigchain is not part of the client protocol, but it's sent together with the packet. Basically it contains the signature of all nodes along the route, and the signature of sender (first sigchain element) and receiver client (last sigchain element). Currently clients are not required to sign yet but that will be needed. The current proto definition is here: https://github.com/nknorg/nkn/blob/master/por/sigchain.proto
The current design is, the signature in first sigchain element should sign against the sigchain header (data hash, data size, sender pk, receiver pk, etc) as well as the content of the first sigchain element. The rest sigchain element sign against the signature of previous sigchain element as well as the content of the current sigchain element. Such design guarantees that any changes to any part of the sigchain will cause the sigchain to be invalid, unless all the signatures are regenerated since the changed element.
I was thinking about adding some fields in NodeToClient msg: sigchain header, first element (these 2 are needed to verify data integrity and sender's signature); last node's signature (needed to generate receiver's signature).
I think it’s very important that we have some encryption protocol implemented in SDK so that developers can just use it very conveniently. Here are some proposals I have in mind:
If we decide to make encryption optional, we need to decide:
Encryption only guarantees that only the correct receiver will be able to see the content of the msg, but it doesn’t help validating the sender’s identity. One can send msg on anyone’s behalf, which will be very insecure and can be used to perform DDOS attack. I order to verify sender’s identity, we need to enforce the sender digital signature sent together with the msg. My proposals are: