ECDSA 非隨機 k - 檢索私鑰
目前我正在玩 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
和帶有引號,以使其成為稍後處理的字元串。