Signature

簽名消息和簽名交易的區別

  • October 9, 2019

使用*“簽名消息”*可以證明地址的所有權。

這是通過使用屬於該地址的私鑰對人類可讀的字元串進行簽名來實現的。

然後所有者提供地址、消息和簽名,任何人都可以驗證他們確實持有地址的私鑰。

ECDSA 簽名通常以 65 字節格式 ( Recovery byte + 32-byte R + 32-byte S) 和 base64 編碼提供。

但是,還有另一種類型的簽名,用於*“簽名交易”*。

對於交易的每個輸入,都有一些數據需要簽名。該數據是二進制數據,通常以十六進制格式提供。

相應的簽名以 70、71 或 72 字節的 DER 格式提供。

在這兩種情況下,消息(第一種情況下的消息字元串,第二種情況下的二進制每個輸入數據)都被轉換為字節數組,並且私鑰用於為該消息字節數組生成 ECDSA 簽名。

輸出格式不同,但 65 字節的格式可以很容易地轉換為 DER。

因此,我認為我可以只使用*“簽名消息”*(稍作修改,以便它使用十六進製字元串而不是 ASCII/UTF-8 字元串)來簽署交易的十六進制編碼的二進制每個輸入數據。

我這樣做了,將簽名轉換為 DER 格式並嘗試發送交易,但它不起作用,因為簽名錯誤。

*所以我的問題是, “簽名消息”“簽名交易”*如何生成簽名有什麼區別,為什麼它們不兼容?

區別在於*“簽名消息”,首先創建一個摘要,然後對其進行簽名,而對於“簽名交易”*(在上面寫的含義),輸入已經是一個摘要,所以不應該再次散列?

謝謝!

*@andrew 提供了有用的資訊, “簽名消息”“簽名交易”之間的主要區別在於“簽名消息”*在內部將自定義字元串添加到正在簽名的文本消息中。

此外,他的回答解決了您執行 TX 創建和簽名的所有步驟時的情況。

我試圖讓我最初的問題保持通用,但現在我看到我應該提到我要簽名的每個輸入 TX 數據是 BlockCypher 的toSign數組。

在他們的文件中還不是很清楚,但是經過一些調查,我發現提供的toSign十六進製字元串已經使用 SHA256 進行了兩次散列,因此它們確實只需要簽名。

可能還有其他系統提供此類簽名摘要。

因此,總而言之,如果您使用外部系統創建 TX,它為您提供數據以使用您的私鑰簽名,則該數據可能已經被散列。這種摘要的一個很好的指標是它有 32 個字節長。

有多種原因導致*“簽名消息”*無法開箱即用地對此類 TX 數據進行簽名:

  • TX 數據是二進制數據(通常是十六進制格式),*“Sign Message”*需要 ASCII/UTF-8 字元串。
  • *“簽名消息”*在內部為正在簽名的消息添加自定義前綴。
  • TX 數據已經過雜湊處理,因此不應再次進行雜湊處理。
  • *“Sign Message”*的輸出是一個 65 字節的 ECDSA 簽名,它不是 DER 格式(可以很容易地轉換)。

*但是, “Sign Message”“Sign Transaction”*的實際簽名是相同的。

希望這將為具有類似案例的其他人節省一些研究時間。

區別在於對於“簽名消息”,首先創建一個摘要,然後對其進行簽名,而對於“簽名交易”(在上面寫的含義),輸入已經是一個摘要,所以它不應該再次被散列?

不,它與散列無關。此外,輸入還不是摘要,必須在簽名之前對其進行雜湊處理。消息和輸入數據都使用 SHA256 進行兩次雜湊處理。

消息簽名和事務輸入簽名之間的區別在於,消息簽名在對消息進行散列之前將字元串Bitcoin Signed Message:\n\n作為換行符,而不是字面意思)預先添加到消息中。\n

此外,消息簽名生成的 65 字節簽名在開頭有一個字節,該字節不是加密簽名本身的一部分。相反,它是一個恢復 ID,以便在簽名消息驗證期間可以從簽名中恢復正確的公鑰。在交易簽名中,簽名末尾附加了一個不同的字節,它是 sighash 類型,通常是 byte 0x01

引用自:https://bitcoin.stackexchange.com/questions/90799