-
Notifications
You must be signed in to change notification settings - Fork 0
MS_DotNetCryptoAlgorithms
- 戻る(.NET開発、暗号化アルゴリズム)
- .NETの署名・暗号化アルゴリズム
- BouncyCastle
- OpenSSL
暗号化アルゴリズムは、一通り揃っている。
| 分類 | .NET のクラス |
|---|---|
| 乱数生成 | RNGCryptoServiceProvider |
| パスワードからのキー生成 | Rfc2898DeriveBytes |
| ハッシュ | 暗号ハッシュ(HashAlgorithm)/キー付きハッシュ(KeyedHashAlgorithm) |
| 秘密鍵・暗号化 |
Aes, DES, RC2, Rijndael, TripleDES
|
| 公開鍵・暗号化 |
RSA, DSA, ECDsa
|
| ハイブリッド暗号化(キー交換) |
RSA, ECDiffieHellman
|
| 署名 |
RSA, DSA, ECDsa
|
| 認証(MAC) |
HMACMD5, HMACSHA256/384/512, MACTripleDES 等 |
- 認証済み暗号(AEAD)については自作が必要。
- 3DES-CBC / AES-CBC / AES-CTR / AES-CCM / AES-GCM ★ / AES-GMAC
補足(最新化): 「AEAD は自作が必要」は、現在は解消している。 .NET Core 3.0 以降、
AesGcmとAesCcmが標準で提供される。 .NET 8 ではChaCha20Poly1305も使える。using var aes = new AesGcm(key, tagSizeInBytes: 16); aes.Encrypt(nonce, plaintext, ciphertext, tag);自作の「AES-CBC + HMAC」より、標準の
AesGcmを使うこと。 自作の Encrypt-then-MAC は、比較を定数時間で行わない、 IV を再利用する、といった実装ミスが混入しやすい。
補足(最新化・非推奨 API): 本ページ執筆時から、 いくつかの API が明確に非推奨になっている。
非推奨 現在 RNGCryptoServiceProviderRandomNumberGenerator.Fill()/GetBytes()(.NET 6 で Obsolete)Rfc2898DeriveBytes(既定 SHA-1・低反復)Rfc2898DeriveBytes.Pbkdf2()にハッシュと反復回数を明示MD5/SHA1/RIPEMD160署名用途では使用しない(衝突攻撃が実用化済み) DES/RC2/TripleDESAES Rijndael/RijndaelManagedAes/AesGcm(.NET 6 で Obsolete)RSACryptoServiceProviderRSA.Create()(プラットフォーム最適な実装が返る)なお、
RijndaelとAESは同じではない。 Rijndael は 128/192/256 ビットのブロック長を取りうるが、 AES はブロック長 128 ビットに固定した Rijndael の部分集合である。RijndaelManagedでBlockSize = 256を指定したデータはAesでは復号できないので、移行時に問題になる。
-
RNGCryptoServiceProviderを使用して、暗号乱数を生成する。 -
Membership.GeneratePasswordも下位でRNGCryptoServiceProviderを使用している。
補足: 現在は次のとおり。
byte[] bytes = RandomNumberGenerator.GetBytes(32); // .NET 6+ int n = RandomNumberGenerator.GetInt32(0, 100); // 偏りのない範囲指定
System.Randomは暗号用途に使ってはならない (トークン、パスワード、salt、nonce の生成すべて)。
-
Rfc2898DeriveBytesを使用して、パスワード ベースのキーを生成する。 - 主に、キー付きハッシュ(
KeyedHashAlgorithm)や
秘密鍵暗号方式(SymmetricAlgorithm)のキーを生成する
(パスワードをそのまま使用しない)。
補足:
Rfc2898DeriveBytesは PBKDF2 だが、 古いコンストラクタの既定は HMAC-SHA1・反復 1000 回で、 現在の基準では明確に不足している。byte[] key = Rfc2898DeriveBytes.Pbkdf2( password, salt, iterations: 600_000, HashAlgorithmName.SHA256, outputLength: 32);なお、パスワードの保存が目的なら PBKDF2 より Argon2id や bcrypt(メモリ ハードな関数)が望ましい。 ASP.NET Identity は 内部で PBKDF2 を使い、反復回数をバージョンで引き上げている。
-
HashAlgorithm.Createというファクトリを使用して、
HashAlgorithm型で扱えば、あまり差異が無く使える。 - Managed、CAPI(CSP)、CNG 実装が揃っている。
対象: MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512
補足: .NET 5 以降は ワンショットの静的メソッドが使える。 インスタンス生成・
Disposeが不要で、アロケーションも少ない。byte[] hash = SHA256.HashData(data);
-
KeyedHashAlgorithm.Createというファクトリを使用して扱う
(ただし、Key 指定する場合、個別のコンストラクタを使用する必要がある)。 - Managed 実装のみで、CAPI(CSP)、CNG 実装は無い。
対象: HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256/384/512, MACTripleDES
補足: MAC やトークンの比較は、必ず定数時間比較で行うこと。
SequenceEqualや==はタイミング攻撃の対象になる。CryptographicOperations.FixedTimeEquals(expected, actual);
- Managed、CAPI(CSP)、CNG 実装の統一性が無い。
基本、CAPI(CSP) に、CNG・Managed 実装が混入しているイメージ。
対象: Aes, DES, RC2, Rijndael, TripleDES
-
AsymmetricAlgorithmの内、暗号化・復号化が可能な公開鍵暗号方式は RSA のみ
(他のアルゴリズムは、キー交換や署名のみサポート)。
補足: RSA で暗号化する際のパディングは OAEP を選ぶこと(
RSAEncryptionPadding.OaepSHA256)。 PKCS#1 v1.5 パディングは Bleichenbacher 攻撃の対象である。そもそも RSA で大きなデータを直接暗号化することはできないため、 実務ではハイブリッド暗号(データは AES、AES 鍵を RSA で包む)にする。
-
AsymmetricKeyExchangeFormatter/Deformatter
(RSAOAEP.../RSAPKCS1...) -
ECDiffieHellman(ECDiffieHellmanCng/ECDiffieHellmanOpenSsl)
- RSA だけは、署名・検証だけでなく、暗号化・復号化にも利用可能。
- Managed、CAPI(CSP)、CNG 実装が一通り提供されている。
新しいアルゴリズムは、CNG と OpenSSL の二択になって行くようにも見える。
対象: RSA, DSA, ECDsa(それぞれ ...Cng / ...CryptoServiceProvider / ...OpenSsl)
補足: RSA 署名のパディングは PSS(
RSASignaturePadding.Pss) が推奨である。 ただし JWT のRS256は PKCS#1 v1.5 を指すので、 相互運用が要る場面では仕様に従うこと(PS256が PSS 版)。
| 接尾辞 | 実装 |
|---|---|
...Managed |
.NET によるマネージ実装 |
...CryptoServiceProvider (CSP) |
CryptoAPI Cryptographic Service Providers(≒ CAPI)実装 |
...Cng |
Cryptography Next Generation (CNG) 実装 |
-
CNG 系の暗号化プロバイダの秘密鍵、暗号化操作は、
CNG キー分離サービスが分離 LSA プロセスでホストされているため、
CC (Common Criteria) 国際標準規格の要求に従ってキープロセス分離を提供する。 -
分離 LSA プロセス
- 仮想化ベースのセキュリティを使って保護され、OS の他の部分からアクセスできない。
- CNG プロバイダを使用するプロセスは、RPC を使って分離 LSA プロセスと通信する。
-
マネージ実装
.NET Framework をサポートするすべてのプラットフォームで利用可能。
ただし、マネージ実装は FIPS に認定されておらず、
ラッパー クラスよりも低速である場合がある。 -
CAPI 実装
CSP ラッパー。以前の OS で使用可能だが、開発中止となっている。 -
CNG 実装
CNG ラッパー。まさに最新の実装であり、新しい開発が行われる。
-
選択と言うより、プラットフォームによって限定的になるもよう。
-
例えば、X.509 を使用した際に取得できる RSA プロバイダが、
- .NET Framework では
RSACryptoServiceProvider - .NET Core on Windows では
RSACng - .NET Core on Linux では
RSAOpenSsl
になることなどを観測した。
- .NET Framework では
-
この辺りは、プラットフォーム依存が強いので、
クロスプラットフォーム対応は難しい部分がありそう。 -
ただし、バージョンが上がるにつれて、着実に実装の移行・追加が進んでいる。
補足: この差異を吸収するには、 具象クラスではなくファクトリを使うのが要点である。
using RSA rsa = RSA.Create(2048); // 各プラットフォームで最適な実装が返る
new RSACryptoServiceProvider()と書くと Windows 専用になる。 同様にcert.GetRSAPrivateKey()のような拡張メソッドを使い、cert.PrivateKeyへのキャストは避けること。
-
System.Security.Cryptography— 昨今(クロスドメイン認証周りの需要でか)日進月歩で追加されている -
System.Security.Cryptography.Xml— XML署名・暗号(MS_XMLSignatureEncryption.md)
- OpenSSL
- BouncyCastle
-
libsodium
- C 言語で開発された、クロスプラットフォームの暗号化ライブラリを含む。
- PHP では PECL で提供されていたがコアに標準的に組み込まれた等の経緯がある。
- Open棟梁 の暗号・復号化 部品
- 暗号化アルゴリズム
- 証明書
- BouncyCastle
- .NET Framework の暗号モデル - Microsoft Learn
- 暗号ライブラリの比較 - Wikipedia
- .NETの暗号ライブラリが進化している件について。 - 開発基盤部会 Blog
Tags: .NET開発, セキュリティ, 暗号化, 証明書
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。