web-dev-qa-db-ja.com

ドロップして同じ名前で再作成することによる証明書とキーアルゴリズムの変更

TRIPLE_DESを使用して対称キーが(かなり前に)作成された状況があります。これは、パスワード列の暗号化に使用され、約10のストアドプロシージャ(OPEN SYMMETRIC KEY SSN_Key_01 DECRYPTION BY CERTIFICATE MyCertificate01;でこれらを使用する)で使用されます。

証明書とキー(将来の保証を提供するため)をAES_192に置き換えます。ただし、可能であれば、ストアドプロシージャの編集は避けたいと思います。

私は次のルーチンを書きました:

  1. パスワード列をプレーンテキストフィールドに暗号化解除します
  2. 既存の鍵と証明書を削除します
  3. 上記と同じ名前の新しい証明書とキーを作成します
  4. 新しい証明書/キーを使用してプレーンテキスト列を再暗号化します

私の質問は、訓練された目にはここで、特に古い名前と新しい名前が同じであり、これらがストアドプロシージャ内で使用されているために、警報ベルが鳴る何かがありますか?

コードをテストしてみましたが、機能しましたが、暗号化の経験が足りず、今日は情報過多の状態になっているので、非常に緊張しているため、専門知識を求めています...

-- Decrypt data

ALTER TABLE [dbo].[tbl_Users] ADD PasswordClear nvarchar(250) NULL;
GO

OPEN SYMMETRIC KEY SSN_Key_01 DECRYPTION BY CERTIFICATE MyCertificate01;
 UPDATE [tbl_Users] SET PasswordClear = CONVERT(nvarchar(250), DECRYPTBYKEY(PasswordEnc))
CLOSE SYMMETRIC KEY SSN_Key_01;
GO

-- Drop old encryption

ALTER TABLE [dbo].[tbl_Users] DROP COLUMN PasswordEnc;
GO

DROP SYMMETRIC KEY SSN_Key_01;
GO

DROP CERTIFICATE [MyCertificate01];
GO


-- Create new certificate and key

CREATE CERTIFICATE MyCertificate01 WITH SUBJECT = 'My Certificate 01';
GO

CREATE SYMMETRIC KEY SSN_Key_01 WITH ALGORITHM = AES_192 ENCRYPTION BY CERTIFICATE MyCertificate01;
GO

ALTER TABLE [dbo].[tbl_Users] ADD PasswordEnc varbinary(256) NULL;
GO

OPEN SYMMETRIC KEY SSN_Key_01 DECRYPTION BY CERTIFICATE MyCertificate01;
 UPDATE [tbl_Users] SET PasswordEnc = ENCRYPTBYKEY(Key_GUID('SSN_Key_01'), PasswordClear);
CLOSE SYMMETRIC KEY SSN_Key_01;
GO

ALTER TABLE [dbo].[tbl_Users] DROP COLUMN PasswordClear;
GO

ALTER TABLE [dbo].[tbl_Users] ALTER COLUMN PasswordEnc varbinary(256) NOT NULL;
GO
5
EvilDr

これをフィードバックするために、プロセスは正常に機能し、データは正常に再暗号化されました。

したがって、対称的なデータ暗号化(これを正当化するためのビジネスルールがある)に関していくつかの懸念があるにもかかわらず、すべてがうまく機能しました。

キーを参照するすべてのストアドプロシージャは、変更を必要とせずに引き続き正常に機能しました。

1
EvilDr

次の問題が発生します。

  • すべてのパスワードがデータベース(およびログファイルとログのバックアップ、そして場合によってはいくつかのエラーログまたはトレースなど)で暗号化されない(短い)期間があり、これは実際のセキュリティ上の問題となる可能性があります
  • 別の名前で証明書を作成し、単一のトランザクションで復号化/再暗号化を行う方が良い

  • パスワードを解読することはできません。そうでない場合は保存されません(すべての開発者が解読ルーチンを呼び出してCEOのパスワードまたは自分のパスワードを取得し、それを使用して彼/彼女/彼女たちに有害なことをすることができます/あなたの名前)

  • 証明書を作成してENCRYPTBYKEY()を操作する代わりに、HASHBYTES('SHA2_256', password + salt)を使用する必要があります。この場合、新しいパスワードフィールドはBINARY(32)にする必要があります(長さはアルゴリズムによって異なります)

  • 誰かがログオンするときは、通常、パスワードをハッシュし(クライアント側が望ましいので、暗号化されていないパスワードがLAN経由でサーバーに送信されることは決してありません)、ハッシュのみを比較します。通常、すべてのプログラミング言語に共通のハッシュ関数(SHA_256など)のライブラリがあります。
  • あなたはあなたのパスワードを塩漬けしていないので、パスワード「P @ assw0rd」を持つすべての人が同じハッシュを持っています。これは攻撃に使用される可能性があります(自分のパスワードを何にでも設定し、同じパスワードを持つ人に見える)
  • したがって、デフォルトでNEWID()を使用してソルト列(UNIQUEIDENTIFIERデータ型)を追加し、暗号化する前に元のパスワードに追加します
  • ログオンプロセスでは、現在のユーザーのソルト(シークレットではない)をクライアントに送信して、入力したパスワードに追加してハッシュする必要がある場合があります。
  • ソルティング/ハッシュ化を実装する場合(または将来変更する場合)、すべてのパスワードをリセットする必要がある場合があります(パスワードを復号化できないため)。
  • 忘れたパスワードメールを元のパスワードで送信することはできなくなります(送信できないはずです)。 Webサーフェイスがある場合は、代わりにリセットパスワードマスクへの特別なリンクを送信します。それ以外の場合は、パスワードをランダムなものに設定してこれを送信し(これは常に弱い方法です)、最初のログイン後にユーザーにパスワードをリセットするよう強制します。
0
Thomas Franz