Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
python-ecdsa — firma/verifica ECDSA in pure-python e accordo di chiave ECDH | Kitploit
Strumenti/GitHubGitHub/tlsfuzzer/python-ecdsa
Strumenti di Crittografia/DecrittografiaCrittografiaUtilità e FrameworkAutenticazioneApprendimento e Formazione
GitHubtlsfuzzer/python-ecdsa

python-ecdsa

firma/verifica ECDSA in pure-python e accordo di chiave ECDH

Vedi Repository
9753422 mesi faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

ECDSA ed ECDH in puro Python

GitHub CI Documentation Status Coverage Status condition coverage mutation score CodeQL Latest Version Code style: black

Questa è un'implementazione facile da usare di ECC (Elliptic Curve Cryptography) con supporto per ECDSA (Elliptic Curve Digital Signature Algorithm), EdDSA (Edwards-curve Digital Signature Algorithm) ed ECDH (Elliptic Curve Diffie-Hellman), implementata interamente in Python, rilasciata sotto la licenza MIT. Con questa libreria puoi creare rapidamente coppie di chiavi (chiave di firma e chiave di verifica), firmare messaggi e verificare le firme. Puoi anche concordare una chiave segreta condivisa basata su chiavi pubbliche scambiate. Le chiavi e le firme sono molto brevi, il che le rende facili da gestire e integrare in altri protocolli.

NOTA: questa libreria non dovrebbe essere usata in contesti di produzione; vedere Sicurezza per maggiori dettagli.

Funzionalità

Questa libreria fornisce generazione di chiavi, firma, verifica e derivazione di segreti condivisi per cinque curve NIST "Suite B" GF(p) (campo primo) molto diffuse, con lunghezze di chiave di 192, 224, 256, 384 e 521 bit. I "nomi brevi" di queste curve, come noti allo strumento OpenSSL (openssl ecparam -list_curves), sono: prime192v1, secp224r1, prime256v1, secp384r1 e secp521r1. Include la curva a 256 bit secp256k1 usata da Bitcoin. C'è anche il supporto per le varianti regolari (non twistate) delle curve Brainpool da 160 a 512 bit. I "nomi brevi" di queste curve sono: brainpoolP160r1, brainpoolP192r1, brainpoolP224r1, brainpoolP256r1, brainpoolP320r1, brainpoolP384r1, . Sono incluse anche alcune curve piccole dello standard SEC (principalmente per velocizzare i test della libreria), e cioè: , , e . La generazione delle chiavi, la firma e la verifica sono supportate anche per le curve Ed25519 e Ed448. Non sono incluse altre curve, ma non è troppo difficile aggiungere il supporto per ulteriori curve su campi primi.

Dipendenze

Questa libreria usa solo Python e il pacchetto 'six'. È compatibile con Python 2.6, 2.7 e 3.6+. Supporta inoltre l'esecuzione su implementazioni alternative come pypy e pypy3.

Se gmpy2 o gmpy è installato, verranno usati per un'aritmetica più veloce. Uno dei due può essere installato dopo l'installazione di questa libreria, python-ecdsa ne rileverà la presenza all'avvio e li userà automaticamente. Su Python3 è preferibile usare gmpy2 per prestazioni ottimali.

Per eseguire i test di compatibilità con OpenSSL, lo strumento 'openssl' deve trovarsi nel tuo PATH. Questa versione è stata testata con successo con OpenSSL 0.9.8o, 1.0.0a, 1.0.2f, 1.1.1d e 3.0.1 (tra gli altri).

Installazione

Questa libreria è disponibile su PyPI; si consiglia di installarla usando pip:``` pip install ecdsa

root@kitploit:~
Nel caso si desideri una maggiore performance e l'uso di codice nativo non sia un problema, è possibile specificare l'installazione insieme a `gmpy2`:```
pip install ecdsa[gmpy2]

oppure (opzione più lenta, legacy):``` pip install ecdsa[gmpy]

root@kitploit:~
## Velocità

La tabella seguente mostra quanto tempo impiega questa libreria a generare coppie di chiavi
(`keygen`), a firmare dati (`sign`), a verificare tali firme (`verify`),
a derivare un segreto condiviso (`ecdh`), e
a verificare le firme senza precalcolo specifico della chiave (`no PC verify`).
Tutti questi valori sono in secondi.
Per comodità, vengono forniti anche gli inversi di tali valori:
quante chiavi al secondo possono essere generate (`keygen/s`), quante firme
possono essere create al secondo (`sign/s`), quante firme possono essere verificate
al secondo (`verify/s`), quanti segreti condivisi possono essere derivati al secondo
(`ecdh/s`), e quante firme senza precalcolo specifico della chiave
possono essere verificate al secondo (`no PC verify/s`). La dimensione della firma
grezza (generalmente il modo più piccolo
in cui una firma può essere codificata) è fornita anche nella colonna `siglen`.
Usa `tox -e speed` per generare questa tabella sul tuo computer.
Su un Intel Core i7 4790K @ 4.0GHz ottengo le seguenti prestazioni:```
                  siglen    keygen   keygen/s      sign     sign/s    verify   verify/s  no PC verify  no PC verify/s
        NIST192p:     48   0.00032s   3134.06   0.00033s   2985.53   0.00063s   1598.36       0.00129s         774.43
        NIST224p:     56   0.00040s   2469.24   0.00042s   2367.88   0.00081s   1233.41       0.00170s         586.66
        NIST256p:     64   0.00051s   1952.73   0.00054s   1867.80   0.00098s   1021.86       0.00212s         471.27
        NIST384p:     96   0.00107s    935.92   0.00111s    904.23   0.00203s    491.77       0.00446s         224.00
        NIST521p:    132   0.00210s    475.52   0.00215s    464.16   0.00398s    251.28       0.00874s         114.39
       SECP256k1:     64   0.00052s   1921.54   0.00054s   1847.49   0.00105s    948.68       0.00210s         477.01
 BRAINPOOLP160r1:     40   0.00025s   4003.88   0.00026s   3845.12   0.00053s   1893.93       0.00105s         949.92
 BRAINPOOLP192r1:     48   0.00033s   3043.97   0.00034s   2975.98   0.00063s   1581.50       0.00135s         742.29
 BRAINPOOLP224r1:     56   0.00041s   2436.44   0.00043s   2315.51   0.00078s   1278.49       0.00180s         556.16
 BRAINPOOLP256r1:     64   0.00053s   1892.49   0.00054s   1846.24   0.00114s    875.64       0.00229s         437.25
 BRAINPOOLP320r1:     80   0.00073s   1361.26   0.00076s   1309.25   0.00143s    699.29       0.00322s         310.49
 BRAINPOOLP384r1:     96   0.00107s    931.29   0.00111s    901.80   0.00230s    434.19       0.00476s         210.20
 BRAINPOOLP512r1:    128   0.00207s    483.41   0.00212s    471.42   0.00425s    235.43       0.00912s         109.61
       SECP112r1:     28   0.00015s   6672.53   0.00016s   6440.34   0.00031s   3265.41       0.00056s        1774.20
       SECP112r2:     28   0.00015s   6697.11   0.00015s   6479.98   0.00028s   3524.72       0.00058s        1716.16
       SECP128r1:     32   0.00018s   5497.65   0.00019s   5272.89   0.00036s   2747.39       0.00072s        1396.16
       SECP160r1:     42   0.00025s   3949.32   0.00026s   3894.45   0.00046s   2153.85       0.00102s         985.07
         Ed25519:     64   0.00076s   1324.48   0.00042s   2405.01   0.00109s    918.05       0.00344s         290.50
           Ed448:    114   0.00176s    569.53   0.00115s    870.94   0.00282s    355.04       0.01024s          97.69

                       ecdh     ecdh/s
        NIST192p:   0.00104s    964.89
        NIST224p:   0.00134s    748.63
        NIST256p:   0.00170s    587.08
        NIST384p:   0.00352s    283.90
        NIST521p:   0.00717s    139.51
       SECP256k1:   0.00154s    648.40
 BRAINPOOLP160r1:   0.00082s   1220.70
 BRAINPOOLP192r1:   0.00105s    956.75
 BRAINPOOLP224r1:   0.00136s    734.52
 BRAINPOOLP256r1:   0.00178s    563.32
 BRAINPOOLP320r1:   0.00252s    397.23
 BRAINPOOLP384r1:   0.00376s    266.27
 BRAINPOOLP512r1:   0.00733s    136.35
       SECP112r1:   0.00046s   2180.40
       SECP112r2:   0.00045s   2229.14
       SECP128r1:   0.00054s   1868.15
       SECP160r1:   0.00080s   1243.98

Per testare le prestazioni con gmpy2 caricato, usa tox -e speedgmpy2. Sulla stessa macchina ottengo le seguenti prestazioni con gmpy2:``` siglen keygen keygen/s sign sign/s verify verify/s no PC verify no PC verify/s NIST192p: 48 0.00017s 5933.40 0.00017s 5751.70 0.00032s 3125.28 0.00067s 1502.41 NIST224p: 56 0.00021s 4782.87 0.00022s 4610.05 0.00040s 2487.04 0.00089s 1126.90 NIST256p: 64 0.00023s 4263.98 0.00024s 4125.16 0.00045s 2200.88 0.00098s 1016.82 NIST384p: 96 0.00041s 2449.54 0.00042s 2399.96 0.00083s 1210.57 0.00172s 581.43 NIST521p: 132 0.00071s 1416.07 0.00072s 1389.81 0.00144s 692.93 0.00312s 320.40 SECP256k1: 64 0.00024s 4245.05 0.00024s 4122.09 0.00045s 2206.40 0.00094s 1068.32 BRAINPOOLP160r1: 40 0.00014s 6939.17 0.00015s 6681.55 0.00029s 3452.43 0.00057s 1769.81 BRAINPOOLP192r1: 48 0.00017s 5920.05 0.00017s 5774.36 0.00034s 2979.00 0.00069s 1453.19 BRAINPOOLP224r1: 56 0.00021s 4732.12 0.00022s 4622.65 0.00041s 2422.47 0.00087s 1149.87 BRAINPOOLP256r1: 64 0.00024s 4233.02 0.00024s 4115.20 0.00047s 2143.27 0.00098s 1015.60 BRAINPOOLP320r1: 80 0.00032s 3162.38 0.00032s 3077.62 0.00063s 1598.83 0.00136s 737.34 BRAINPOOLP384r1: 96 0.00041s 2436.88 0.00042s 2395.62 0.00083s 1202.68 0.00178s 562.85 BRAINPOOLP512r1: 128 0.00063s 1587.60 0.00064s 1558.83 0.00125s 799.96 0.00281s 355.83 SECP112r1: 28 0.00009s 11118.66 0.00009s 10775.48 0.00018s 5456.00 0.00033s 3020.83 SECP112r2: 28 0.00009s 11322.97 0.00009s 10857.71 0.00017s 5748.77 0.00032s 3094.28 SECP128r1: 32 0.00010s 10078.39 0.00010s 9665.27 0.00019s 5200.58 0.00036s 2760.88 SECP160r1: 42 0.00015s 6875.51 0.00015s 6647.35 0.00029s 3422.41 0.00057s 1768.35 Ed25519: 64 0.00030s 3322.56 0.00018s 5568.63 0.00046s 2165.35 0.00153s 654.02 Ed448: 114 0.00060s 1680.53 0.00039s 2567.40 0.00096s 1036.67 0.00350s 285.62

root@kitploit:~
                   ecdh     ecdh/s
    NIST192p:   0.00050s   1985.70
    NIST224p:   0.00066s   1524.16
    NIST256p:   0.00071s   1413.07
    NIST384p:   0.00127s    788.89
    NIST521p:   0.00230s    434.85
   SECP256k1:   0.00071s   1409.95

BRAINPOOLP160r1: 0.00042s 2374.65 BRAINPOOLP192r1: 0.00051s 1960.01 BRAINPOOLP224r1: 0.00066s 1518.37 BRAINPOOLP256r1: 0.00071s 1399.90 BRAINPOOLP320r1: 0.00100s 997.21 BRAINPOOLP384r1: 0.00129s 777.51 BRAINPOOLP512r1: 0.00210s 475.99 SECP112r1: 0.00022s 4457.70 SECP112r2: 0.00024s 4252.33 SECP128r1: 0.00028s 3589.31 SECP160r1: 0.00043s 2305.02

root@kitploit:~
(c'è anche la versione `gmpy`, eseguila usando `tox -e speedgmpy`)

Per confronto, un'implementazione altamente ottimizzata (che include
assembly specifico per alcune curve), come quella in OpenSSL 1.1.1d, fornisce i
seguenti valori di prestazione sulla stessa macchina.
Esegui `openssl speed ecdsa` e `openssl speed ecdh` per riprodurre i risultati:```
                              sign    verify    sign/s verify/s
 192 bits ecdsa (nistp192)   0.0002s   0.0002s   4785.6   5380.7
 224 bits ecdsa (nistp224)   0.0000s   0.0001s  22475.6   9822.0
 256 bits ecdsa (nistp256)   0.0000s   0.0001s  45069.6  14166.6
 384 bits ecdsa (nistp384)   0.0008s   0.0006s   1265.6   1648.1
 521 bits ecdsa (nistp521)   0.0003s   0.0005s   3753.1   1819.5
 256 bits ecdsa (brainpoolP256r1)   0.0003s   0.0003s   2983.5   3333.2
 384 bits ecdsa (brainpoolP384r1)   0.0008s   0.0007s   1258.8   1528.1
 512 bits ecdsa (brainpoolP512r1)   0.0015s   0.0012s    675.1    860.1

                              sign    verify    sign/s verify/s
 253 bits EdDSA (Ed25519)   0.0000s   0.0001s  28217.9  10897.7
 456 bits EdDSA (Ed448)     0.0003s   0.0005s   3926.5   2147.7

                               op      op/s
 192 bits ecdh (nistp192)   0.0002s   4853.4
 224 bits ecdh (nistp224)   0.0001s  15252.1
 256 bits ecdh (nistp256)   0.0001s  18436.3
 384 bits ecdh (nistp384)   0.0008s   1292.7
 521 bits ecdh (nistp521)   0.0003s   2884.7
 256 bits ecdh (brainpoolP256r1)   0.0003s   3066.5
 384 bits ecdh (brainpoolP384r1)   0.0008s   1298.0
 512 bits ecdh (brainpoolP512r1)   0.0014s    694.8

Keys and signature can be serialized in different ways (see Usage, below). For a NIST192p key, the three basic representations require strings of the following lengths (in bytes):

root@kitploit:~
to_string:  signkey= 24, verifykey= 48, signature=48
compressed: signkey=n/a, verifykey= 25, signature=n/a
DER:        signkey=106, verifykey= 80, signature=55
PEM:        signkey=278, verifykey=162, (no support for PEM signatures)

Storia

Nel 2006, Peter Pearson annunciò la sua implementazione in puro Python di ECDSA in un messaggio su sci.crypt, disponibile dal suo sito di download. Nel 2010, Brian Warner scrisse un wrapper attorno a questo codice, per renderlo un po' più facile e sicuro da usare. Nel 2020, Hubert Kario incluse un'implementazione di crittografia a curve ellittiche che usa internamente coordinate di Jacobi, migliorando le prestazioni di circa 20 volte. Stai guardando il README di questo wrapper.

Test

Per eseguire l'intera suite di test, fare così:

root@kitploit:~
tox -e coverage

Su un Intel Core i7 4790K @ 4.0GHz, i test richiedono circa 18 secondi per essere eseguiti. La suite di test usa hypothesis quindi c'è una certa variabilità intrinseca nei tempi di esecuzione della suite di test.

Una parte di test_pyecdsa.py e test_ecdh.py verifica la compatibilità con OpenSSL, eseguendo lo strumento CLI "openssl"; assicurati che sia nel tuo PATH se vuoi testare la compatibilità con esso (se OpenSSL manca, è troppo vecchio o non supporta tutte le curve supportate nelle release a monte, vedrai dei test saltati nell'esecuzione di coverage di cui sopra).

Sicurezza

Questa libreria non è stata progettata pensando alla sicurezza. Se stai elaborando dati che devono essere protetti, ti suggeriamo di usare un wrapper di qualità attorno a OpenSSL. pyca/cryptography è un esempio di tale wrapper. Il caso d'uso principale di questa libreria è come libreria portabile per test di interoperabilità e come strumento didattico.

Questa libreria non protegge dagli attacchi side-channel.

Non consentire agli attaccanti di misurare quanto tempo impieghi a generare una coppia di chiavi o a firmare un messaggio. Non consentire agli attaccanti di eseguire codice sulla stessa macchina fisica mentre è in corso la generazione della coppia di chiavi o la firma (questo include le macchine virtuali). Non consentire agli attaccanti di misurare quanta energia consuma il tuo computer durante la generazione della coppia di chiavi o la firma di un messaggio. Non consentire agli attaccanti di misurare le interferenze RF provenienti dal tuo computer durante la generazione di una coppia di chiavi o la firma di un messaggio. Nota: il semplice caricamento della chiave privata causerà la generazione della coppia di chiavi. Anche altre operazioni o vettori di attacco possono essere vulnerabili ad attacchi. Per un attaccante sofisticato, osservare una sola operazione con una chiave privata sarà sufficiente per ricostruire completamente la chiave privata.

Si noti inoltre che qualsiasi libreria crittografica in puro Python sarà vulnerabile agli stessi attacchi side-channel. Questo perché Python non fornisce primitive sicure contro i side-channel (con l'eccezione di hmac.compare_digest()), rendendo impossibile una programmazione sicura contro i side-channel.

Questa libreria dipende da una solida fonte di numeri casuali. Non usarla su un sistema in cui os.urandom() non fornisce numeri casuali crittograficamente sicuri.

Uso

Si inizia creando una SigningKey. Puoi usarla per firmare dati, passando i dati come stringa di byte e ottenendo indietro la firma (anch'essa una stringa di byte). Puoi anche chiedere a una SigningKey di darti la corrispondente VerifyingKey. La VerifyingKey può essere usata per verificare una firma, passandole sia la stringa di dati sia la stringa di byte della firma: restituisce True oppure solleva BadSignatureError.```python from ecdsa import SigningKey sk = SigningKey.generate() # uses NIST192p vk = sk.verifying_key signature = sk.sign(b"message") assert vk.verify(signature, b"message")

root@kitploit:~
Ogni `SigningKey`/`VerifyingKey` è associata a una curva specifica, come
NIST192p (quella predefinita). Le curve più lunghe sono più sicure, ma richiedono più tempo per
essere utilizzate e producono chiavi e firme più lunghe.```python
from ecdsa import SigningKey, NIST384p
sk = SigningKey.generate(curve=NIST384p)
vk = sk.verifying_key
signature = sk.sign(b"message")
assert vk.verify(signature, b"message")

La SigningKey può essere serializzata in diversi formati: la forma più breve consiste nel chiamare s=sk.to_string(), e poi ricrearla con SigningKey.from_string(s, curve). Questa forma breve non registra la curva, quindi devi assicurarti di passare a from_string() la stessa curva che hai usato per la chiave originale. La forma breve di una chiave di firma basata su NIST192p è lunga solo 24 byte. Se una codifica di punto non è valida o non giace sulla curva specificata, from_string() solleverà MalformedPointError.```python from ecdsa import SigningKey, NIST384p sk = SigningKey.generate(curve=NIST384p) sk_string = sk.to_string() sk2 = SigningKey.from_string(sk_string, curve=NIST384p) print(sk_string.hex()) print(sk2.to_string().hex())

root@kitploit:~
Nota: sebbene i metodi siano chiamati `to_string()`, il tipo che restituiscono è in
realtà `bytes`; la parte "string" è un residuo di Python 2.

`sk.to_pem()` e `sk.to_der()` serializzano la chiave di firma negli stessi
formati usati da OpenSSL. Il file PEM ha il familiare formato ASCII-armored
`"-----BEGIN EC PRIVATE KEY-----"` codificato in base64, mentre il formato DER
è una forma binaria più corta degli stessi dati.
`SigningKey.from_pem()/.from_der()` annullano questa serializzazione. Questi
formati includono il nome della curva, quindi non è necessario passare un
identificatore di curva al deserializzatore. Nel caso in cui il file sia
malformato, `from_der()` e `from_pem()` solleveranno `UnexpectedDER` o
`MalformedPointError`.```python
from ecdsa import SigningKey, NIST384p
sk = SigningKey.generate(curve=NIST384p)
sk_pem = sk.to_pem()
sk2 = SigningKey.from_pem(sk_pem)
# sk and sk2 are the same key

Analogamente, la VerifyingKey può essere serializzata allo stesso modo: vk.to_string()/VerifyingKey.from_string(), to_pem()/from_pem(), e to_der()/from_der(). Lo stesso argomento curve= è necessario per VerifyingKey.from_string().```python from ecdsa import SigningKey, VerifyingKey, NIST384p sk = SigningKey.generate(curve=NIST384p) vk = sk.verifying_key vk_string = vk.to_string() vk2 = VerifyingKey.from_string(vk_string, curve=NIST384p)

vk and vk2 are the same key

from ecdsa import SigningKey, VerifyingKey, NIST384p sk = SigningKey.generate(curve=NIST384p) vk = sk.verifying_key vk_pem = vk.to_pem() vk2 = VerifyingKey.from_pem(vk_pem)

vk and vk2 are the same key

root@kitploit:~
Esistono un paio di modi diversi per calcolare una firma. In sostanza,
ECDSA prende un numero che rappresenta i dati da firmare e restituisce una
coppia di numeri che rappresenta la firma. L'argomento `hashfunc=` di
`sk.sign()` e `vk.verify()` viene usato per trasformare una stringa arbitraria in un
digest a lunghezza fissa, che viene poi convertito in un numero che ECDSA può firmare,
e sia la firma che la verifica devono usare lo stesso approccio. Il valore predefinito è
`hashlib.sha1`, ma se usi NIST256p o una curva più lunga, puoi usare
`hashlib.sha256` invece.

Ci sono anche diversi modi per rappresentare una firma. I metodi predefiniti
`sk.sign()` e `vk.verify()` la presentano come una stringa breve, per
semplicità e overhead minimo. Per usare uno schema diverso, utilizza gli
argomenti `sk.sign(sigencode=)` e `vk.verify(sigdecode=)`. Ci sono funzioni di supporto
nel modulo `ecdsa.util` che possono essere utili in questo caso.

È anche possibile creare una `SigningKey` da un "seed", che è
deterministico. Questo può essere usato in protocolli in cui si vogliono derivare
chiavi di firma coerenti da un altro segreto, ad esempio quando si vogliono
tre chiavi separate e si vuole memorizzare un unico segreto master. Si dovrebbe
iniziare con un seed non indovinabile e distribuito uniformemente con circa `curve.baselen`
byte di entropia, quindi usare una delle funzioni di supporto in `ecdsa.util` per
convertirlo in un intero nell'intervallo corretto, e infine passarlo
a `SigningKey.from_secret_exponent()`, in questo modo:```python
import os
from ecdsa import NIST384p, SigningKey
from ecdsa.util import randrange_from_seed__trytryagain

def make_key(seed):
  secexp = randrange_from_seed__trytryagain(seed, NIST384p.order)
  return SigningKey.from_secret_exponent(secexp, curve=NIST384p)

seed = os.urandom(NIST384p.baselen) # or other starting point
sk1a = make_key(seed)
sk1b = make_key(seed)
# note: sk1a and sk1b are the same key
assert sk1a.to_string() == sk1b.to_string()
sk2 = make_key(b"2-"+seed)  # different key
assert sk1a.to_string() != sk2.to_string()

Nel caso in cui l'applicazione debba verificare molte firme realizzate con una singola chiave, è possibile precalcolare alcuni dei valori interni per rendere la verifica delle firme significativamente più veloce. Il punto di pareggio si verifica a circa 100 firme verificate.

Per eseguire il precalcolo, è possibile chiamare il metodo precompute() su un'istanza di VerifyingKey:```python from ecdsa import SigningKey, NIST384p sk = SigningKey.generate(curve=NIST384p) vk = sk.verifying_key vk.precompute() signature = sk.sign(b"message") assert vk.verify(signature, b"message")

root@kitploit:~
Una volta chiamato `precompute()`, tutte le verifiche delle firme con questa chiave
verranno eseguite più rapidamente.

## Compatibilità con OpenSSL

Per produrre firme che possano essere verificate dagli strumenti OpenSSL, o per verificare
firme prodotte da tali strumenti, usa:```python
# openssl ecparam -name prime256v1 -genkey -out sk.pem
# openssl ec -in sk.pem -pubout -out vk.pem
# echo "data for signing" > data
# openssl dgst -sha256 -sign sk.pem -out data.sig data
# openssl dgst -sha256 -verify vk.pem -signature data.sig data
# openssl dgst -sha256 -prverify sk.pem -signature data.sig data

import hashlib
from ecdsa import SigningKey, VerifyingKey
from ecdsa.util import sigencode_der, sigdecode_der

with open("vk.pem") as f:
   vk = VerifyingKey.from_pem(f.read())

with open("data", "rb") as f:
   data = f.read()

with open("data.sig", "rb") as f:
   signature = f.read()

assert vk.verify(signature, data, hashlib.sha256, sigdecode=sigdecode_der)

with open("sk.pem") as f:
   sk = SigningKey.from_pem(f.read(), hashlib.sha256)

new_signature = sk.sign_deterministic(data, sigencode=sigencode_der)

with open("data.sig2", "wb") as f:
   f.write(new_signature)

# openssl dgst -sha256 -verify vk.pem -signature data.sig2 data

Nota: se è necessaria la compatibilità con OpenSSL 1.0.0 o versioni precedenti, le funzioni sigencode_string e sigdecode_string di ecdsa.util possono essere usate rispettivamente per scrivere e leggere le firme.

Le chiavi possono inoltre essere scritte in un formato gestibile da openssl:```python from ecdsa import SigningKey, VerifyingKey

with open("sk.pem") as f: sk = SigningKey.from_pem(f.read()) with open("sk.pem", "wb") as f: f.write(sk.to_pem())

with open("vk.pem") as f: vk = VerifyingKey.from_pem(f.read()) with open("vk.pem", "wb") as f: f.write(vk.to_pem())

root@kitploit:~
## Entropia

La creazione di una chiave di firma con `SigningKey.generate()` richiede una qualche forma di
entropia (a differenza di
`from_secret_exponent`/`from_string`/`from_der`/`from_pem`,
che sono deterministici e non richiedono una fonte di entropia). La fonte
predefinita è `os.urandom()`, ma puoi passare qualsiasi altra funzione che si comporti
come `os.urandom` come argomento `entropy=` per fare qualcosa di diverso. Questo
può essere utile nei test unitari, dove vuoi ottenere risultati ripetibili. L'utility
`ecdsa.util.PRNG` è utile in questo caso: prende un seed e produce da esso un
flusso pseudo-casuale robusto:```python
from ecdsa.util import PRNG
from ecdsa import SigningKey
rng1 = PRNG(b"seed")
sk1 = SigningKey.generate(entropy=rng1)
rng2 = PRNG(b"seed")
sk2 = SigningKey.generate(entropy=rng2)
# sk1 and sk2 are the same key

Allo stesso modo, la generazione di una firma ECDSA richiede un numero casuale, e ogni firma deve usarne uno diverso (usare lo stesso numero due volte rivelerà immediatamente la chiave di firma privata). Il metodo sk.sign() accetta un argomento entropy= che si comporta come SigningKey.generate(entropy=).

Firme Deterministiche

Se si chiama SigningKey.sign_deterministic(data) invece di .sign(data), il codice genererà una firma deterministica invece di una casuale. Questo utilizza l'algoritmo di RFC6979 per generare in modo sicuro un valore k unico, derivato dalla chiave privata e dal messaggio firmato. Ogni volta che si firma lo stesso messaggio con la stessa chiave, si otterrà la stessa firma (usando lo stesso k).

Questo potrebbe diventare il comportamento predefinito in una versione futura, poiché non è vulnerabile ai guasti della sorgente di entropia.

Esempi

Crea una coppia di chiavi NIST192p e salva entrambe immediatamente su disco:```python from ecdsa import SigningKey sk = SigningKey.generate() vk = sk.verifying_key with open("private.pem", "wb") as f: f.write(sk.to_pem()) with open("public.pem", "wb") as f: f.write(vk.to_pem())

root@kitploit:~
Carica una chiave di firma dal disco, usala per firmare un messaggio (usando SHA-1), e scrivi
la firma su disco:```python
from ecdsa import SigningKey
with open("private.pem") as f:
    sk = SigningKey.from_pem(f.read())
with open("message", "rb") as f:
    message = f.read()
sig = sk.sign(message)
with open("signature", "wb") as f:
    f.write(sig)

Carica la chiave di verifica, il messaggio e la firma dal disco e verifica la firma (supponendo un hash SHA-1):```python from ecdsa import VerifyingKey, BadSignatureError vk = VerifyingKey.from_pem(open("public.pem").read()) with open("message", "rb") as f: message = f.read() with open("signature", "rb") as f: sig = f.read() try: vk.verify(sig, message) print "good signature" except BadSignatureError: print "BAD SIGNATURE"

root@kitploit:~
Crea una coppia di chiavi NIST521p:```python
from ecdsa import SigningKey, NIST521p
sk = SigningKey.generate(curve=NIST521p)
vk = sk.verifying_key

Crea tre chiavi di firma indipendenti da un seed master:```python from ecdsa import NIST192p, SigningKey from ecdsa.util import randrange_from_seed__trytryagain

def make_key_from_seed(seed, curve=NIST192p): secexp = randrange_from_seed__trytryagain(seed, curve.order) return SigningKey.from_secret_exponent(secexp, curve)

sk1 = make_key_from_seed("1:%s" % seed) sk2 = make_key_from_seed("2:%s" % seed) sk3 = make_key_from_seed("3:%s" % seed)

root@kitploit:~
Load a verifying key from disk and print it using hex encoding in
uncompressed and compressed format (defined in X9.62 and SEC1 standards):```python
from ecdsa import VerifyingKey

with open("public.pem") as f:
    vk = VerifyingKey.from_pem(f.read())

print("uncompressed: {0}".format(vk.to_string("uncompressed").hex()))
print("compressed: {0}".format(vk.to_string("compressed").hex()))

Caricare una chiave di verifica da una stringa esadecimale in formato compresso, output non compresso:```python from ecdsa import VerifyingKey, NIST256p

comp_str = '022799c0d0ee09772fdd337d4f28dc155581951d07082fb19a38aa396b67e77759' vk = VerifyingKey.from_string(bytearray.fromhex(comp_str), curve=NIST256p) print(vk.to_string("uncompressed").hex())

root@kitploit:~
Scambio di chiavi ECDH con la controparte remota:```python
from ecdsa import ECDH, NIST256p

ecdh = ECDH(curve=NIST256p)
ecdh.generate_private_key()
local_public_key = ecdh.get_public_key()
#send `local_public_key` to remote party and receive `remote_public_key` from remote party
with open("remote_public_key.pem") as e:
    remote_public_key = e.read()
ecdh.load_received_public_key_pem(remote_public_key)
secret = ecdh.generate_sharedsecret_bytes()
Scarica lo strumento
brainpoolP512r1
secp112r1
secp112r2
secp128r1
secp160r1