ディスカッション (11件)
データ構造にデジタル署名を付与する際、単純にシリアライズして署名するだけでは不十分な場合があります。正規化(Canonicalization)の欠如や署名対象の範囲の誤りなど、一見正しそうに見えて実は脆弱な「間違った署名のやり方」について、そのリスクと注意点をまとめました。
Putting domain separators in the IDL is interesting but you can also avoid the problem by putting the domain separators in-band (e.g. in some kind of "type" field that is always present).
Tangentially, depending on what your input and data model look like, canonicalisation takes O(nlogn) time (i.e. the cost of sorting your fields).
Here I describe an alternative approach that produces deterministic hashes without a distinct canonicalization step, using multiset hashing: https://www.da.vidbuchanan.co.uk/blog/signing-json.html (https://www.da.vidbuchanan.co.uk/blog/signing-json.html)
Since the example was given in proto, I'll suggest a solution in proto: add a message option.
extend google.protobuf.MessageOptions {
optional uint64 domain_separator = 1234;
}
message TreeRoot {
option (domain_separator) = 4567;
...
}
This article claims that these are somewhat open questions, but they're not and have not been for a long time.
#1 You sign a blob and you don't touch it before verifying the signature (aka "The Cryptographic Doom Principle") #2 Signatures are bound to a context which is not transmitted but used for deriving the key or mixed into the MAC or what have you. This is called the Horton principle. It ensures that signer/verifier must cryptographically agree on which context the message is intended for. You essentially cannot implement this incorrectly because if you do, all signatures will fail to verify.
The article actually proposes to violate principle #2 (by embedding some magic numbers into the protocol headers and presuming that someone will check them), which is an incorrect design and will result in bad things if history is any indication.
Principles #1 and #2 are well-established cryptographic design principles for just a handful of decades each.
So another lesson had been relearned from asn.1. I'm proud of working in this industry again! Next we will figure out to always put versions into the data too
This is a nice explanation of an obvious idea. Both domain separation, and putting the domain signifier into the IDL are fine, but not novel.
Crypto is hard. Do it right. Get help from your tools. 'Nuff said.
Jeeze, I'm getting too old for this crap.
So, isn't this a rather longwinded way to say that a signature only extends to the scope of the message it contains?
It doesn't matter if I sign the word "yes", if you don't know what question is being asked. The signature needs to included the necessary context for the signature to be meaningful.
Lots of ways of doing that, and you definitely need to be thoughtful about redundant data and storage overhead, but the concept isn't tricky.
Why not digest the type as part of the hash? This avoids the problem in the article and keeps the transmission size small.
When my data structures are messages to be sent over a network, I always start with msgId and msgLen, both fixed width fields.
This solves the message differentiation problem explicitly, makes security and memory management easier, and reduces routing to:
switch(msg.msgId):
…
the nominal vs structural typing point is the crux. it is easy to fall into because when writing code, types feel concrete -- the compiler yells if you mix them up -- so it does not occur to you that the serialized form has lost that distincti
DSSE is great for this, if you need more schema use in-toto