Skip to content

MS_DotNetCryptoAlgorithms

nishi_74322014 edited this page Aug 4, 2026 · 1 revision

.NETの署名・暗号化アルゴリズム

概要

暗号化アルゴリズムは、一通り揃っている。

分類 .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 以降、AesGcmAesCcm が標準で提供される。 .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 が明確に非推奨になっている。

非推奨 現在
RNGCryptoServiceProvider RandomNumberGenerator.Fill() / GetBytes()(.NET 6 で Obsolete)
Rfc2898DeriveBytes(既定 SHA-1・低反復) Rfc2898DeriveBytes.Pbkdf2() にハッシュと反復回数を明示
MD5 / SHA1 / RIPEMD160 署名用途では使用しない(衝突攻撃が実用化済み)
DES / RC2 / TripleDES AES
Rijndael / RijndaelManaged Aes / AesGcm(.NET 6 で Obsolete)
RSACryptoServiceProvider RSA.Create()(プラットフォーム最適な実装が返る)

なお、RijndaelAES は同じではない。 Rijndael は 128/192/256 ビットのブロック長を取りうるが、 AES はブロック長 128 ビットに固定した Rijndael の部分集合である。 RijndaelManagedBlockSize = 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 より Argon2idbcrypt(メモリ ハードな関数)が望ましい。 ASP.NET Identity は 内部で PBKDF2 を使い、反復回数をバージョンで引き上げている。

ハッシュ化

暗号ハッシュ(HashAlgorithm)

  • HashAlgorithm.Create というファクトリを使用して、
    HashAlgorithm 型で扱えば、あまり差異が無く使える。
  • Managed、CAPI(CSP)、CNG 実装が揃っている。

対象: MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512

補足: .NET 5 以降は ワンショットの静的メソッドが使える。 インスタンス生成・Dispose が不要で、アロケーションも少ない。

byte[] hash = SHA256.HashData(data);

キー付きハッシュ(KeyedHashAlgorithm)

  • KeyedHashAlgorithm.Create というファクトリを使用して扱う
    (ただし、Key 指定する場合、個別のコンストラクタを使用する必要がある)。
  • Managed 実装のみで、CAPI(CSP)、CNG 実装は無い。

対象: HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256/384/512, MACTripleDES

補足: MAC やトークンの比較は、必ず定数時間比較で行うこと。 SequenceEqual== はタイミング攻撃の対象になる。

CryptographicOperations.FixedTimeEquals(expected, actual);

秘密鍵・暗号化方式(SymmetricAlgorithm)

  • Managed、CAPI(CSP)、CNG 実装の統一性が無い。
    基本、CAPI(CSP) に、CNG・Managed 実装が混入しているイメージ。

対象: Aes, DES, RC2, Rijndael, TripleDES

公開鍵・暗号化方式(AsymmetricAlgorithm)

  • AsymmetricAlgorithm の内、暗号化・復号化が可能な公開鍵暗号方式は RSA のみ
    (他のアルゴリズムは、キー交換や署名のみサポート)。

補足: RSA で暗号化する際のパディングは OAEP を選ぶことRSAEncryptionPadding.OaepSHA256)。 PKCS#1 v1.5 パディングは Bleichenbacher 攻撃の対象である。

そもそも RSA で大きなデータを直接暗号化することはできないため、 実務ではハイブリッド暗号(データは AES、AES 鍵を RSA で包む)にする。

ハイブリッド・暗号化(キー交換)

  • AsymmetricKeyExchangeFormatter / Deformatter
    RSAOAEP... / RSAPKCS1...
  • ECDiffieHellmanECDiffieHellmanCng / ECDiffieHellmanOpenSsl

署名・検証

デジタル署名

  • RSA だけは、署名・検証だけでなく、暗号化・復号化にも利用可能。
  • Managed、CAPI(CSP)、CNG 実装が一通り提供されている。
    新しいアルゴリズムは、CNG と OpenSSL の二択になって行くようにも見える。

対象: RSA, DSA, ECDsa(それぞれ ...Cng / ...CryptoServiceProvider / ...OpenSsl

補足: RSA 署名のパディングは PSS(RSASignaturePadding.Pss が推奨である。 ただし JWTRS256 は PKCS#1 v1.5 を指すので、 相互運用が要る場面では仕様に従うこと(PS256 が PSS 版)。

Managed、CAPI(CSP)、CNG実装とは?

接尾辞 実装
...Managed .NET によるマネージ実装
...CryptoServiceProvider (CSP) CryptoAPI Cryptographic Service Providers(≒ CAPI)実装
...Cng Cryptography Next Generation (CNG) 実装

CNG

  • CNG 系の暗号化プロバイダの秘密鍵、暗号化操作は、
    CNG キー分離サービスが分離 LSA プロセスでホストされているため、
    CC (Common Criteria) 国際標準規格の要求に従ってキープロセス分離を提供する。

  • 分離 LSA プロセス

    • 仮想化ベースのセキュリティを使って保護され、OS の他の部分からアクセスできない。
    • CNG プロバイダを使用するプロセスは、RPC を使って分離 LSA プロセスと通信する。

最適な実装の選択

  • マネージ実装
    .NET Framework をサポートするすべてのプラットフォームで利用可能。
    ただし、マネージ実装は FIPS に認定されておらず、
    ラッパー クラスよりも低速である場合がある。

  • CAPI 実装
    CSP ラッパー。以前の OS で使用可能だが、開発中止となっている。

  • CNG 実装
    CNG ラッパー。まさに最新の実装であり、新しい開発が行われる。

.NET Core、Linux

  • 選択と言うより、プラットフォームによって限定的になるもよう。

  • 例えば、X.509 を使用した際に取得できる RSA プロバイダが、

    • .NET Framework では RSACryptoServiceProvider
    • .NET Core on Windows では RSACng
    • .NET Core on Linux では RSAOpenSsl

    になることなどを観測した。

  • この辺りは、プラットフォーム依存が強いので、
    クロスプラットフォーム対応は難しい部分がありそう。

  • ただし、バージョンが上がるにつれて、着実に実装の移行・追加が進んでいる。

補足: この差異を吸収するには、 具象クラスではなくファクトリを使うのが要点である。

using RSA rsa = RSA.Create(2048);   // 各プラットフォームで最適な実装が返る

new RSACryptoServiceProvider() と書くと Windows 専用になる。 同様に cert.GetRSAPrivateKey() のような拡張メソッドを使い、 cert.PrivateKey へのキャストは避けること。

追加可能なプロバイダ

  • System.Security.Cryptography — 昨今(クロスドメイン認証周りの需要でか)日進月歩で追加されている
  • System.Security.Cryptography.Xml — XML署名・暗号(MS_XMLSignatureEncryption.md

ライブラリ

参考


Tags: .NET開発, セキュリティ, 暗号化, 証明書

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally