Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
python-ecdsa — 純Python製のECDSA署名/検証とECDH鍵合意 | Kitploit
ツール/GitHubGitHub/tlsfuzzer/python-ecdsa
暗号化/復号化ツール暗号化ユーティリティとフレームワーク認証学習と教育
GitHubtlsfuzzer/python-ecdsa

python-ecdsa

純Python製のECDSA署名/検証とECDH鍵合意

リポジトリを見る
9753422ヶ月前Kitploit レビュー済み

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

純Python製 ECDSA および ECDH

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

これは、ECC(楕円曲線暗号)の使いやすい実装です。 ECDSA(楕円曲線デジタル署名アルゴリズム)、 EdDSA(エドワーズ曲線デジタル署名アルゴリズム)、および ECDH (楕円曲線ディフィー・ヘルマン)をサポートし、純粋な Python で実装され、 MIT ライセンスで公開されています。このライブラリを使用すると、鍵ペア(署名 鍵と検証鍵)をすばやく作成し、メッセージに署名して、署名を検証できます。また、 交換した公開鍵に基づいて共有秘密鍵に合意することもできます。 鍵と署名は非常に短いため、取り扱いが容易で、 他のプロトコルに組み込みやすくなっています。

注記: このライブラリを本番環境で使用することは避けてください。詳細については セキュリティ を参照してください。

特徴

このライブラリは、鍵生成、署名、検証、および共有秘密鍵の導出を提供します。 5つの 一般的なNIST "Suite B" GF(p)(素数体)曲線(鍵長192、 224、256、384、521ビット)に対応しています。OpenSSLツール (openssl ecparam -list_curves)で知られているこれらの曲線の「短縮名」は、prime192v1、 secp224r1、prime256v1、secp384r1、secp521r1 です。また、 Bitcoinで使用される256ビット曲線 secp256k1 も含まれます。さらに、 160〜512ビットのBrainpool曲線の通常(非ツイスト)変種もサポートしています。 これらの曲線の「短縮名」は、brainpoolP160r1、brainpoolP192r1、 brainpoolP224r1、brainpoolP256r1、brainpoolP320r1、brainpoolP384r1、 brainpoolP512r1 です。SEC標準からの小さな曲線もいくつか 含まれています(主にライブラリのテストを高速化するため)。それらは次のとおりです: 、、、。 Ed25519および Ed448曲線についても、鍵生成、署名、検証がサポートされています。 他の曲線は含まれていませんが、素数体上の曲線を追加するのは それほど難しくありません。

依存関係

このライブラリは、Pythonと'six'パッケージのみを使用します。互換性があるのは Python 2.6、2.7、3.6+ です。また、pypyやpypy3のような代替実装での 実行もサポートしています。

gmpy2 または gmpy がインストールされている場合、より高速な演算にそれらが使用されます。 どちらもこのライブラリのインストール後にインストールできます。 python-ecdsa は起動時にそれらの存在を検出し、それらを 自動的に使用します。 Python3 で最適なパフォーマンスを得るには、gmpy2 を推奨します。

OpenSSL互換性テストを実行するには、'openssl'ツールが PATH に含まれている必要があります。このリリースは、OpenSSL 0.9.8o、 1.0.0a、1.0.2f、1.1.1d、3.0.1 などで正常にテストされています。

インストール

このライブラリはPyPIで入手できます。pip を使用してインストールすることをお勧めします:``` pip install ecdsa

root@kitploit:~
より高いパフォーマンスが必要で、ネイティブコードを使用しても問題ない場合は、`gmpy2` と一緒にインストールを指定することが可能です。```
pip install ecdsa[gmpy2]

または(遅い、レガシーオプション):``` pip install ecdsa[gmpy]

root@kitploit:~
## 速度

次の表は、このライブラリが鍵ペアの生成
(`keygen`)、データの署名(`sign`)、それらの署名の検証(`verify`)、
共有秘密の導出(`ecdh`)、および
鍵固有の事前計算なしでの署名検証(`no PC verify`)に要する時間を示しています。
これらの値はすべて秒単位です。
便宜上、これらの値の逆数も示しています:
1秒あたりに生成できる鍵の数(`keygen/s`)、1秒あたりに作成できる署名の数
(`sign/s`)、1秒あたりに検証できる署名の数
(`verify/s`)、1秒あたりに導出できる共有秘密の数
(`ecdh/s`)、および鍵固有の事前計算なしで1秒あたりに検証できる署名の数
(`no PC verify/s`)です。生の
署名のサイズ(一般に、最も小さい
署名のエンコード方式)も`siglen`列に示されています。
`tox -e speed`を使用して、この表を自分のコンピュータで生成できます。
Intel Core i7 4790K @ 4.0GHzでは、次のようなパフォーマンスが得られます:```
                  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

gmpy2 を読み込んだ状態でパフォーマンスをテストするには、tox -e speedgmpy2 を使用します。 同じマシンでは、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:~
(`gmpy` バージョンもあります。`tox -e speedgmpy` で実行してください)

比較のために、OpenSSL 1.1.1d のような高度に最適化された実装(一部の曲線では曲線固有のアセンブリを含む)は、同じマシン上で以下の性能数値を示します。
再現するには、`openssl speed ecdsa` と `openssl speed ecdh` を実行してください:```
                              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

鍵と署名はさまざまな方法でシリアライズできます(下記の「使用法」を参照)。 NIST192pキーの場合、3つの基本的な表現には、以下の長さ(バイト単位)の 文字列が必要です:

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)

履歴

2006年、Peter Pearsonは、ECDSAのPure-Python実装をsci.cryptへのメッセージで発表し、彼のダウンロードサイトから入手できるようにしました。2010年、Brian Warnerはこのコードのラッパーを作成し、少し使いやすく、より安全にしました。2020年、Hubert Karioは、内部でヤコビアン座標を使用する楕円曲線暗号の実装を含め、パフォーマンスを約20倍向上させました。あなたが今見ているのは、このラッパーのREADMEです。

テスト

完全なテストスイートを実行するには、次のようにします:

root@kitploit:~
tox -e coverage

Intel Core i7 4790K @ 4.0GHzでは、テストの実行に約18秒かかります。テストスイートはhypothesisを使用しているため、テストスイートの実行時間には本質的な変動があります。

test_pyecdsa.pyとtest_ecdh.pyの一部は、"openssl"CLIツールを実行することでOpenSSLとの互換性をチェックします。OpenSSLとの互換性をテストしたい場合は、そのツールがPATHに含まれていることを確認してください(OpenSSLが存在しない、古すぎる、またはアップストリームリリースでサポートされているすべての曲線をサポートしていない場合は、上記のcoverage実行でスキップされたテストが表示されます)。

セキュリティ

このライブラリはセキュリティを考慮して設計されていません。保護が必要なデータを処理する場合は、OpenSSLの高品質なラッパーを使用することをお勧めします。pyca/cryptographyはそのようなラッパーの一例です。このライブラリの主な使用目的は、相互運用性テスト用のポータブルライブラリおよび教育ツールです。

このライブラリはサイドチャネル攻撃から保護しません。

攻撃者に鍵ペアの生成やメッセージの署名にかかる時間を測定させないでください。鍵ペアの生成や署名が行われているときに、攻撃者に同じ物理マシン上でコードを実行させないでください(仮想マシンも含みます)。鍵ペアの生成やメッセージの署名中に、攻撃者にコンピュータの消費電力を測定させないでください。鍵ペアの生成やメッセージの署名中に、攻撃者にコンピュータから発生するRF干渉を測定させないでください。注:秘密鍵を読み込むだけでも鍵ペアの生成が発生します。他の操作や攻撃経路も攻撃に対して脆弱である可能性があります。高度な攻撃者にとっては、秘密鍵を使った1回の操作を観察するだけで、秘密鍵を完全に再構築するのに十分です。

また、Pure-Python暗号ライブラリはすべて同じサイドチャネル攻撃に対して脆弱であることに注意してください。これは、Pythonがサイドチャネルセキュアなプリミティブを提供していないためです(hmac.compare_digest()を除く)。そのため、サイドチャネルセキュアなプログラミングは不可能です。

このライブラリは強力な乱数ソースに依存しています。os.urandom()が暗号学的に安全な乱数を提供しないシステムでは使用しないでください。

使用法

まずSigningKeyを作成します。これは、データをバイト文字列として渡し、署名(これもバイト文字列)を受け取ることで、データに署名するために使用できます。SigningKeyに、対応するVerifyingKeyを要求することもできます。VerifyingKeyは、データ文字列と署名バイト文字列の両方を渡すことで署名の検証に使用できます。Trueを返すか、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:~
各 `SigningKey`/`VerifyingKey` は、NIST192p(デフォルト)などの特定の曲線に
関連付けられています。曲線が長いほど安全性は高くなりますが、使用に時間が
かかり、鍵と署名も長くなります。```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")

SigningKey は複数の異なる形式にシリアライズできます。最も短いのは s=sk.to_string() を呼び出し、その後 SigningKey.from_string(s, curve) で再作成する方法です。この短い形式は曲線を記録しないため、元の鍵で使用したのと同じ曲線を必ず from_string() に渡す必要があります。NIST192p ベースの署名鍵の短い形式は、わずか 24 バイト長です。ポイントエンコーディングが無効であるか、指定された曲線上にない場合、from_string() は 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:~
注: メソッドは `to_string()` と呼ばれますが、返す型は実際には
`bytes` であり、「string」の部分は Python 2 からの名残です。

`sk.to_pem()` と `sk.to_der()` は、署名鍵を OpenSSL が使用するのと同じ
形式にシリアライズします。PEM ファイルは、おなじみの ASCII アーマー付き
`"-----BEGIN EC PRIVATE KEY-----"` base64 エンコード形式のように見え、DER 形式
は同じデータのより短いバイナリ形式です。
`SigningKey.from_pem()/.from_der()` はこのシリアライゼーションを元に戻します。これらの
形式には曲線名が含まれるため、デシリアライザーに曲線
識別子を渡す必要はありません。ファイルが不正な場合、`from_der()`
および `from_pem()` は `UnexpectedDER` または` 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

同様に、VerifyingKey も同じ方法でシリアライズできます: vk.to_string()/VerifyingKey.from_string()、to_pem()/from_pem()、および to_der()/from_der()。同じ curve= 引数は 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:~
署名の計算方法には、いくつかの異なる方式があります。根本的には、
ECDSAは署名対象のデータを表す数値を取り、署名を表す数値のペアを返します。
この数値のペアが署名です。`sk.sign()` と `vk.verify()` への `hashfunc=` 引数は、
任意の文字列を固定長ダイジェストに変換するために使われます。
そのダイジェストは次にECDSAが署名できる数値に変換されます。
署名と検証の両方が同じ方式を使わなければなりません。デフォルト値は
`hashlib.sha1` ですが、NIST256pまたはそれより長い曲線を使う場合は、
代わりに `hashlib.sha256` を使うことができます。

署名を表現する方法も複数あります。デフォルトの
`sk.sign()` と `vk.verify()` メソッドは、シンプルさとオーバーヘッドを最小限にするため、
署名を短い文字列として提示します。別の方式を使うには、
`sk.sign(sigencode=)` と `vk.verify(sigdecode=)` 引数を使用します。
ここで役立つヘルパー関数が `ecdsa.util` モジュールにあります。

「シード」から `SigningKey` を作成することも可能で、これは決定論的です。
これは、他の秘密から一貫した署名鍵を導出したいプロトコルで使用できます。
例えば、3つの別々の鍵が必要で、単一のマスター秘密だけを保存したい場合などです。
まず、約 `curve.baselen` バイトのエントロピーを持つ、
一様分布で推測不可能なシードから始めます。次に、`ecdsa.util` の
ヘルパー関数のいずれかを使って、それを正しい範囲の整数に変換し、
最後にそれを `SigningKey.from_secret_exponent()` に渡します。
次のように:```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()

アプリケーションが単一の鍵で作成された多数の署名を検証する場合、 内部値の一部を事前計算することで、署名検証を大幅に高速化できます。 損益分岐点は、 約100件の署名を検証した時点で発生します。

事前計算を実行するには、precompute() メソッドを 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:~
`precompute()` を呼び出すと、このキーを使用したすべての署名検証が
高速に実行されます。

## OpenSSL 互換性

OpenSSL ツールで検証できる署名を生成する場合、またはそれらのツールで
生成された署名を検証する場合は、次を使用します:```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

注意:OpenSSL 1.0.0 以前との互換性が必要な場合、署名の書き込みと読み取りには、それぞれ ecdsa.util の sigencode_string と sigdecode_string を使用できます。

また、キーは 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:~
## エントロピー

`SigningKey.generate()` を使用して署名鍵を作成するには、何らかの形の
エントロピーが必要です(対照的に、
`from_secret_exponent`/`from_string`/`from_der`/`from_pem` は、
決定的で、エントロピー源を必要としません)。デフォルトの
エントロピー源は `os.urandom()` ですが、`os.urandom` と同様に動作する他の関数を
`entropy=` 引数として渡すことで、別の動作をさせることもできます。これは
単体テストで再現可能な結果を得たい場合に役立ちます。
`ecdsa.util.PRNG` ユーティリティはここで便利です: シードを受け取り、そこから強力な
擬似ランダムストリームを生成します:```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

同様に、ECDSA署名の生成には乱数が必要であり、各 署名は異なる乱数を使用しなければなりません(同じ乱数を2回使用すると、 署名秘密鍵が即座に露呈します)。sk.sign() メソッドは entropy= 引数を受け取り、これは SigningKey.generate(entropy=) と同じように動作します。

決定論的署名

SigningKey.sign_deterministic(data) を .sign(data) の代わりに呼び出すと、 コードはランダムな署名ではなく決定論的な署名を生成します。 これはRFC6979のアルゴリズムを使用して、一意の k 値を安全に生成します。 この値は秘密鍵と署名対象のメッセージから導出されます。署名するたびに 同じ鍵で同じメッセージに署名すると、同じ署名が得られます(同じ k を使用)。

これは将来のバージョンでデフォルトになる可能性があります。エントロピー源の 障害に対して脆弱ではないためです。

例

NIST192p の鍵ペアを作成し、すぐに両方をディスクに保存します。```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:~
ディスクから署名鍵を読み込み、それを使用してメッセージに署名し(SHA-1を使用)、
署名をディスクに書き込みます:```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)

検証鍵、メッセージ、署名をディスクから読み込み、署名を検証します(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:~
NIST521p 鍵ペアを作成します:```python
from ecdsa import SigningKey, NIST521p
sk = SigningKey.generate(curve=NIST521p)
vk = sk.verifying_key

マスターシードから3つの独立した署名鍵を作成します:```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:~
ディスクから検証鍵を読み込み、16進エンコーディングを使用して
非圧縮形式および圧縮形式(X9.62およびSEC1標準で定義)で出力します:```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()))

圧縮形式の16進文字列から検証鍵を読み込み、 非圧縮形式で出力:```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:~
リモート相手との ECDH 鍵交換:```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()
ツールをダウンロード
secp112r1
secp112r2
secp128r1
secp160r1