Public-Key

ECDSA 非隨機 k - 檢索私鑰

  • June 3, 2016

目前我正在玩 ECDSA。我知道如果使用相同的 K 來簽署兩條消息,我可以檢索私鑰。

我嘗試使用這個腳本:Ruby Script to crack the private key。但我總是收到一個錯誤:

signature_der_string.rb:14:in `decode’: null 長度錯誤(OpenSSL::ASN1::ASN1Error)

我的簽名以 0 開頭。如果我省略了 0,我會得到一個不同的錯誤

“解碼”:太長(OpenSSL::ASN1::ASN1Error)

你能幫我做錯什麼嗎?

msgash1_hex = ‘4992c90022d12b85555493d3dcca55671b4047c1’

msgash2_hex = ‘fced62bb70b5af004e8720342d036da02009e5e8’

sig1_hex = ‘436c79af2252b161af0b74e3eeb4064af334c483e8708fe709c46b1aa480fa49b017fb020fbc9717c6bf50ada23a820’

sig2_hex = ‘436c79af2252b161af0b74e3eeb4064af334c483e8708fe734065fe380b95c601f118c047976b3007831690806e10f4’

我已將此 Ruby 腳本修改為不需要公鑰並允許直接 (r,s) 輸入。有趣的是,我在Google搜尋完全相同的問題時偶然發現了這個執行緒(在撰寫本文時兩小時前創建)。請注意,我使用的是 Secp192r1(由於 CTF 挑戰),因此請隨意根據自己的喜好對其進行修改:

require 'ecdsa'

msghash1_hex = '000000000000000000000000000000000000000000000000'
msghash2_hex = '000000000000000000000000000000000000000000000000'

sig1 = ECDSA::Signature.new(0x000000000000000000000000000000000000000000000000, 0x222222222222222222222222222222222222222222222222)
sig2 = ECDSA::Signature.new(0x000000000000000000000000000000000000000000000000, 0x333333333333333333333333333333333333333333333333)

group = ECDSA::Group::Secp192r1

def hex_to_binary(str)
 str.scan(/../).map(&:hex).pack('C*')
end

msghash1 = hex_to_binary(msghash1_hex)
msghash2 = hex_to_binary(msghash2_hex)

r = sig1.r
puts 'sig r: %#x' % r
puts 'sig1 s: %#x' % sig1.s
puts 'sig2 s: %#x' % sig2.s

# Step 1: k = (z1 - z2)/(s1 - s2)
field = ECDSA::PrimeField.new(group.order)
z1 = ECDSA::Format::IntegerOctetString.decode(msghash1)
z2 = ECDSA::Format::IntegerOctetString.decode(msghash2)

k_candidates = [
 field.mod((z1 - z2) * field.inverse(sig1.s - sig2.s)),
 field.mod((z1 - z2) * field.inverse(sig1.s + sig2.s)),
 field.mod((z1 - z2) * field.inverse(-sig1.s - sig2.s)),
 field.mod((z1 - z2) * field.inverse(-sig1.s + sig2.s)),
]

private_key = nil
k_candidates.each do |k|
 private_key_maybe = field.mod(field.mod(sig1.s * k - z1) * field.inverse(r))
 puts 'Private key maybe: %#x' % private_key_maybe
 next
end

Signature.new(r,s)是上面的參數。msghash_hex基本上是您的 HASH(message) 的十六進製版本,它周圍沒有0x和帶有引號,以使其成為稍後處理的字元串。

引用自:https://crypto.stackexchange.com/questions/35791