web-dev-qa-db-ja.com

暗号化アルゴリズムの暗号化キーを作成する方法は?

.Net Security名前空間で利用可能な暗号化アルゴリズムを使用したいのですが、キーの生成方法を理解しようとしています。たとえば、AESアルゴリズムには256ビット、16バイトのキー、初期化ベクトル(数バイトも必要)などがあります。

  1. キーとIVで値の組み合わせを使用できますか?例えばキーとIVのすべてのゼロが有効かどうか私は多くのxorsを行うアルゴリズムの詳細を知っているので、ゼロは何の役にも立ちませんが、これらのアルゴリズムによる制限はありますか?

  2. または、何らかのプログラムを使用してキーを生成し、どこかに永続的に保存する必要がありますか?

暗号化後にデータベースにデータを保存し、ユーザー名、パスワード、電話番号などの安全なプロファイルデータ、およびキーは、接続文字列に記載されているデータベースユーザーと管理者のみが使用できるようにします。

29
Akash Kava

暗号化を使用してデータを交換する場合、鍵交換プロトコルが必要になりますが、TLSやSSLのような既製のものを使用する代わりに自分で作成する必要はありません。

暗号化を使用してデータを保存する場合、 CryptGenRandom (またはそれに相当する.net RandomNumberGenerator.GetBytes )を使用してIVを生成し、ドキュメントに沿って保存します(明確で、不要です) IV)を保護します。キーを書き留めることはありません。キーはユーザーが提供します。通常、 CryptDeriveKey 、またはその.Netの同等の PasswordDeriveKey.CryptDeriveKey を使用して、パスワードフレーズからキーを導出します。

更新

ユーザーと管理者のみが使用できるデータベースにシークレットを保存するには、3つのキーを使用する必要があります。

  • データを暗号化するもの(DKキーと呼びます)
  • dKキーを暗号化する1つのユーザーキー(UKと呼びます)
  • dKキーを暗号化する1つの管理者キー(AKと呼びます)

理論的には、データをDKで暗号化し、次にDKをUKで暗号化して保存し、DKをAKで暗号化して保存します。この方法では、ユーザーは再びUKを使用してDKを復号化してからデータを復号化でき、管理者はAKを使用してDKを復号化してからデータを復号化できます。大きな問題は、システムが常に自動化されているという事実です。したがって、システムは管理者のキーにアクセスする必要があります。つまり、管理者の秘密キーではなく、システムキーです。たとえば拒否)。

率直に言って、IVが何であるか、C#からAESを使用する方法、および暗号化アルゴリズムがどのように機能するかについての知識があれば、この種の問題を解決するのにちょうど0(ゼロ)の牽引力が得られます。問題は、使用するIVやキーではなく、常にキーのプロビジョニングです。実際の暗号化操作については、データベースの組み込みサポートを使用してください。 SQL Serverの暗号化 を参照してください。必要なonlyファシリティはTDE( Transparent Data Encryption )であり、メディアの偶発的な損失を防ぐために簡単に議論できます。

13
Remus Rusanu

あなたは本当にこれを正しい方法で行うべきです:)

1)安全に生成されたランダムIVを使用する
2)安全に生成されたランダムキーを使用する
3)ECBモードを使用しない-[〜#〜] ever [〜#〜]

AesManaged aes = new AesManaged();
aes.GenerateKey();
aes.GenerateIV();

上記のコードは、ランダムIVおよびランダムキーを正しく安全に生成します。

37

Rfc2898DeriveBytesクラスを読み込む必要があるように聞こえます。

Rfc2898DeriveBytes.GetBytes();

単純なint値を供給することにより、対称暗号化アルゴリズムの.Keyおよび.IVプロパティに供給されるバイト配列のサイズを調整できるメソッド(上記)があります。 MSの公式の70-536本は、KeySizeプロパティを8で割ることにより、これをプログラム的に行うことを提案しています。

つまり、TripleDesまたはAESManaged。使用するものは何でも、アルゴリズム自体には、最初に会う必要があるいくつかの前提条件があります。つまり、キーサイズの条件を満たします。 RunTimeは、自動的にプロパティとフィールドなどに最適で最も強力な値を入力します。しかし、IVとキーはあなたから来る必要があります。これにより、次のことができます。

RijndaelManaged myAlg = new RiRijndaelManaged();
byte[] salt = Encoding.ASCII.GetBytes("Some salt value");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes("some password", salt);
myAlg.Key = key.GetBytes( myAlg.KeySize / 8);
myAlg.IV  = key.GetBytes( myAlg.BlockSize / 8);
// myAld should now fully set-up.

上記のように、私はそれをプログラム的に行うことで何を意味するのかを見ることができます。

Microsoft 70-536ブックは、.Keyプロパティは、ビットではなくバイトで提供するバイト配列を想定していると述べています。 RFCクラスはバイト単位で機能し、アルゴリズムとしてKeySizeプロパティはビット単位で機能します。 1バイト= 8ビット。これがどこに行くのかわかりますか...?これにより、上記のサンプルコードがそのまま実行される理由がわかります。私はそれを研究しました、そしてそれは私にとってかなり理にかなっています!

上記の答えにより、指定されたパスワードと、両端でハードコード化できる静的ソルト値を使用してアルゴリズムオブジェクトを作成できます。必要なことは、暗号化されたメッセージを正常に復号化できるように、.Keyおよび.IVに保存されたバイト配列を受信者に安全に転送する方法を心配することだけです。同じアルゴリズムオブジェクトを安全に再構築する。

OBTW:

AESManagedにはキーサイズの要件があります:128Bits = 16バイト!!! (8 * 8 = 64、64ビット/バイトあたり8ビット= 8バイト)したがって

64 * 2 = 128ビット、8 * 2、==> 16バイトのキーサイズ!

256ビット= 32バイト!!!!


70-536公式トレーニングキットの本によると、Aesのキーサイズは128ビットに制限されています。たとえば、256ビット、192および128のキーサイズは、Rijndaelクラスで使用できます。


その一方で、すべてのそのがらくたを完全に忘れて、代わりに.GenerateKeyメソッドとGenerateIVメソッドを使用するだけで、事前に共有され同意されたパスワードと静的ソルト値を整理する手間を省くことができます。唯一の懸念事項は、キーおよびIVバイト配列を保存および取得する方法を見つけることです。バイナリフォーマッタ? 。

14
IbrarMumtaz

特定の長さでランダムな文字/ 16進コードを生成します。

この関数( here から取得)は、特定の長さのランダムキーを返します。

private static string CreateSalt(int size)
{
    //Generate a cryptographic random number.
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] buff = new byte[size];
    rng.GetBytes(buff);

    // Return a Base64 string representation of the random number.
    return Convert.ToBase64String(buff);
}
8

使用する System.Security.Cryptography.RandomNumberGeneratorランダムバイトを生成するには:

var rnd = new System.Security.Cryptography.RandomNumberGenerator.Create();
var key = new byte[50];
rnd.GetBytes(key);
6
AxelEckenberger

それは本当にあなたがキーで何をしたかによって異なります。

キーをコンピューターで生成する場合(任意のランダムな値にすることができます)、通常、いくつかのGUIDのSHA256を取得します。これは、ハードウェア乱数ジェネレーターを使用しない場合とほぼ同じくらいランダムです。

すべて0のキーを使用できますが、明らかにあまり安全ではありません。

0
Adam Ruth