15

一連のレコードをファイルに保存することを計画しています。各レコードはlibsodiumで署名されています。ただし、私のプログラムの将来のバージョンで、現在のバージョンが作成した署名をチェックできるようにしたいと考えています。理想的には、その逆も可能です。

Sodium の現在のバージョンでは、署名は Ed25519 アルゴリズムを使用して作成されます。デフォルトのプリミティブは、Sodium の新しいバージョンで変更される可能性があると思います (そうでなければ、libsodium は特定のものを選択する方法を公開しないと思います)。

するべきか...

  1. 常にデフォルトのプリミティブを使用します (つまりcrypto_sign)
  2. 特定のプリミティブを使用する (つまりcrypto_sign_ed25519)
  3. (1) を実行しますが、値をsodium_library_version_major()ファイル (専用の「ナトリウム バージョン」フィールドまたは一般的な「ファイル形式リビジョン」フィールドのいずれか) に保存し、現在実行中のバージョンが低い場合は終了します
  4. (3)を行うだけでなく、保存するcrypto_sign_primitive()
  5. (4) だけでなく、ストアcrypto_sign_bytes()とフレンドも行う

...または、まったく別のことを行う必要がありますか?

私のプログラムは C で書かれます。

4

2 に答える 2

4

まず、考えられる一連の問題を特定してから、それを解決してみましょう。いくつかのデータ (レコード) と署名があります。署名は、さまざまなアルゴリズムで計算できます。プログラムは進化し、その振る舞いを変えることができ、libsodium も (独立して) 進化し、その振る舞いを変えることができます。署名生成の面では、次のものがあります。

  • crypto_sign()、これは署名を生成するためにいくつかのデフォルトのアルゴリズムを使用します(執筆時点では単に invokes ですcrypto_sign_ed25519()
  • crypto_sign_ed25519()ed25519、特定のアルゴリズムに基づいて署名を生成します

同じ入力データと同じキーが与えられたある特定のアルゴリズムでは、常に同じ結果が得られると思います。これは数学であり、この規則からの逸脱はライブラリを完全に使用できなくするためです。

2 つの主なオプションを見てみましょう。

  1. crypto_sign_ed25519()常に使用し、これを変更することはありません。シンプルでありcrypto_sign_ed25519()、libsodium に存在し、出力が安定している限り、安定した固定サイズの署名と管理オーバーヘッドがゼロであるため、心配する必要はありません。もちろん、将来誰かがこのアルゴリズムの恐ろしい問題を発見する可能性があります。アルゴリズムを変更する準備ができていない場合、それはあなたにとって恐ろしい問題を意味する可能性があります。
  2. を使用しcrypto_sign()ます。これにより、アルゴリズムが変更される可能性があるため、突然多くの問題が発生するため、署名とともにいくつかのメタデータを保存する必要があります。これにより、一連の質問が開かれます。
    • 何を保管する?
    • このメタデータはレコード レベルまたはファイル レベルである必要がありますか?

2 番目のアプローチの言及された関数には何がありますか?

  • sodium_library_version_major()ライブラリAPIのバージョンを教えてくれる関数です。サポートされている/デフォルトのアルゴリズムの変更とは直接関係がないため、問題にはほとんど役に立ちません。
  • crypto_sign_primitive()で使用されるアルゴリズムを識別する文字列を返す関数ですcrypto_sign()。アルゴリズムが変更される正確なタイミングで出力が変更されると思われるため、これは必要なものに完全に一致します。
  • crypto_sign_bytes()crypto_sign()によって生成された署名のサイズをバイト単位で返す関数です。これは、署名に必要なストレージの量を決定するのに役立ちますが、アルゴリズムが変更された場合でも簡単に同じままになる可能性があるため、明示的に保存する必要があるメタデータではありません。

何を保存するかがわかったので、保存されたデータの処理の問題があります。アルゴリズム名を取得し、それを使用して一致する検証関数を呼び出す必要があります。残念ながら、私が見たところ、libsodium 自体は (openssl のような) アルゴリズム名を指定して適切な関数を取得する簡単な方法を提供していないため、EVP_get_cipherbyname()自分EVP_get_digestbyname()で作成する必要があります (もちろん、未知の名前では失敗するはずです)。また、自分で作成する必要がある場合は、ライブラリの名前の代わりに数値識別子を格納する方が簡単かもしれません (コードは増えます)。

ファイルレベルとレコードレベルの話に戻りましょう。これを解決するには、さらに 2 つの質問をする必要があります。いつでも古いレコードに新しい署名を生成できますか (それは技術的に可能ですか、ポリシーで許可されていますか)、古いファイルに新しいレコードを追加する必要がありますか?

古いレコードに新しい署名を生成できない場合、または新しいレコードを追加する必要があり、署名の再生成によるパフォーマンスの低下を望まない場合は、選択肢があまりなく、次のことを行う必要があります。

  • 署名に動的サイズのフィールドがある
  • 署名自体とともに署名の生成に使用されるアルゴリズム (動的文字列フィールドまたは内部 (アプリケーション用) ID) を保存します

新しい署名を生成できる場合、または特に新しいレコードを追加する必要がない場合は、特別なファイル レベル フィールドで使用されるアルゴリズムを保存し、署名アルゴリズムが変更された場合に、より単純なファイル レベルのアプローチを回避できます。 、ファイルを保存するときにすべての署名を再生成します(または、新しいレコードを追加するときに古い署名を使用します。これは、互換性ポリシーの問題でもあります)。

その他のオプション?さて、何がそんなに特別なのcrypto_sign()ですか?その動作はあなたの制御下にないということです.libsodium開発者はあなたのためにアルゴリズムを選択します(間違いなく彼らは良いものを選択します).独自の特定の選択を行い、あるアルゴリズムをあるファイル バージョンで使用し、別のアルゴリズムを別のファイル バージョンで使用します (もちろん、必要に応じて変換コードを使用します)。繰り返しますが、これは、新しい署名を生成でき、それがポリシーで許可されているという前提にも基づいています。

これにより、単にcrypto_sign_ed25519(). それは主にプログラムの寿命に依存します。おそらく(意見として)5年未満であれば、特定のアルゴリズムを1つだけ使用する方が簡単だと思います。簡単に10年以上かかる場合は、アルゴリズム(およびおそらく暗号ライブラリ全体)の変更に耐えられる必要があります。

于 2016-08-08T15:14:11.123 に答える
2

Just use the high-level API.

Functions from the high-level API are not going to use a different algorithm without the major version of the library being bumped.

The only breaking change one can expect in libsodium 1.x.y is the removal of deprecated/undocumented functions (that don't even exist in current releases compiled with the --enable-minimal switch). Everything else will remain backward compatible.

New algorithms might be introduced in 1.x.y versions without high-level wrappers, and will be stabilized and exposed via a new high-level API in libsodium 2.

Therefore, do not bother calling crypto_sign_ed25519(). Just use crypto_sign().

于 2016-10-16T17:34:20.227 に答える