對散列目標的部分進行散列是否有意義?
TL;博士;
假設我正在為 ECDSA 計算 SHA256,這樣做是否有意義
SHA256(item1 + SHA256(item1') + item2 + SHA256(item2') + itemN + SHA256(itemN'))
或與(安全方面)相同SHA256(item1 + item1' + item2 + item2' + itemN + itemN')
?(以下+
稱為二進制格式的操作數內容的二進制串聯)細節
我有一個類似於下面的資料結構(為了便於閱讀,以 JSON 格式呈現)
{ "Lorem": 123, "Ipsum": "qwerty", "Items": [ { "Id": 4321, "Data": "SOME_DATA_HERE", "ItemSig": "A_RELATIVELY_BIG_BINARY_STRUCTURE_AND_ECDSA_SIGNATURE_OF_HELLO_FIELD_CONTENT" }, { "Id": 8765, "Data": "SOME_DATA_HERE", "ItemSig": "A_RELATIVELY_BIG_BINARY_STRUCTURE_AND_ECDSA_SIGNATURE_OF_HELLO_FIELD_CONTENT" } ], "Sig": "A_PLACE_FOR_ECDSA_SIGNATURE" }
我還有一個 ECC 密鑰對。現在,我需要對“items”數組中的每個元素進行簽名,然後對整個結構本身進行簽名。
在簽署整個結構時,我正在證明該結構中的一些數據(和的內容
Lorem
)Ipsum
,並且對於每個Item
,我證明該項目在該結構中(通過包含Id
在簽名中)並證明該項目的內容(通過包括ItemSig
which 包括內容)。我認為值得注意的是,我
ItemSig
在結構的簽名中包含而不是項目的內容,以證明該項目是由與結構本身相同的 ECC 密鑰簽名的。這是因為有多個 ECC 密鑰對簽名有效,但使用一個 ECC 密鑰對項目進行簽名而用另一個 ECC 密鑰對結構進行簽名被認為是無效的。所以問題是,結構的 Sig 欄位有什麼更好的選擇(為什麼?),
ECDSA(SHA256(Content))
在哪裡
- 內容 =
Lorem + Ipsum + Items[0].Id + SHA256(Items[0].ItemSig) + Items[1].Id + SHA256(Items[1].ItemSig) + Items[n].Id + SHA256(Items[n].ItemSig)
, 或- 內容 =
Lorem + Ipsum + Items[0].Id + Items[0].ItemSig + Items[1].Id + Items[1].ItemSig + Items[n].Id + Items[n].ItemSig
。
從實踐的角度來看,這兩種方法都對暴力破解具有相似的抵抗力。從實現的角度來看,只應用一次散列可能更簡單,而不需要對每個部分進行散列。
不過,我建議您審查您的設計並考慮其他選擇。假設有人收到了您的消息並且驗證顯示,
Items[0].ItemSig
並且Items[0].Data
不匹配。這可能有兩個原因:
- 要麼在您簽名之前
Items[0].ItemSig
無效(然後簽名者偽造了簽名)。- 或者簽名是正確的,但是您在簽名之前已經更換
Items[0].Data
了。- 或者
Items[0].Data
在從您到接收方的途中被修改。因此,很難找出問題發生在哪裡。
這就是為什麼我會建議其他方法。想想關注點分離。不要考慮您簽署的內容的結構。簽署整個元素
Items
。然後,如果有人收到您的消息並且某些內容不是 containsnet,則很容易檢查:應該只檢查您的簽名是否與該Items
元素匹配。如果匹配,則表示從您到接收方的過程中沒有修改,並且問題發生在您簽名Items[0].Data
之前的簽名者身上。**TLDR:**我建議散列整個元素
Items
,而不是它的部分,並且不對它的每個部分進行散列。