目次
概要
最新の.NET環境において、標準ライブラリのみを使用してRSA暗号化方式のキーペア(秘密鍵と公開鍵)を新規生成し、取り回しのしやすいPEM形式(Base64文字列)としてエクスポートする実装です。 従来のXML形式(ToXmlString)に代わり、OpenSSLや他のプラットフォームとも互換性が高い標準的なテキスト形式を採用しています。
仕様(入出力)
- 入力: キーサイズ(ビット長、例: 2048, 4096)
- 出力:
- 秘密鍵のPEM形式文字列(
-----BEGIN PRIVATE KEY-----…) - 公開鍵のPEM形式文字列(
-----BEGIN PUBLIC KEY-----…)
- 秘密鍵のPEM形式文字列(
- 動作: メモリ上でキーを生成し、標準出力へ表示した後、文字列からキー情報を復元できることを検証します。
基本の使い方
using System.Security.Cryptography;
// 2048ビットでキーを生成
using var algorithm = RSA.Create(2048);
// 秘密鍵(PKCS#8)を文字列として取得
var privateKeyPem = algorithm.ExportRSAPrivateKeyPem();
// 公開鍵(SPKI)を文字列として取得
var publicKeyPem = algorithm.ExportSubjectPublicKeyPem();
コード全文
このコードは .NET 7 以降の環境で動作するコンソールアプリケーションです。
using System;
using System.Security.Cryptography;
class Program
{
static void Main()
{
// 1. RSAアルゴリズムのインスタンス生成(キーサイズ指定)
// 従来のRSACryptoServiceProviderではなく、クロスプラットフォーム対応のCreateを使用
using var secureIdentity = RSA.Create(2048);
Console.WriteLine($"[Key Generated] KeySize: {secureIdentity.KeySize} bits");
// 2. 秘密鍵のエクスポート(PEM形式: PKCS#8)
// サーバー側で保存・管理するための機密情報
string secretToken = secureIdentity.ExportRSAPrivateKeyPem();
Console.WriteLine("\n--- Exported Private Key (Keep Secret) ---");
Console.WriteLine(secretToken);
// 3. 公開鍵のエクスポート(PEM形式: SubjectPublicKeyInfo)
// クライアント等に配布して暗号化に使ってもらう情報
string publicToken = secureIdentity.ExportSubjectPublicKeyPem();
Console.WriteLine("\n--- Exported Public Key (Distribute) ---");
Console.WriteLine(publicToken);
// 4. 文字列からの復元検証(インポート)
VerifyKeyImport(secretToken, publicToken);
}
/// <summary>
/// エクスポートされたPEM文字列からRSAインスタンスが復元できるか検証します
/// </summary>
static void VerifyKeyImport(string privatePem, string publicPem)
{
Console.WriteLine("\n[Validation] Testing key import...");
// 復元用の新しいインスタンス
using var validationRsa = RSA.Create();
try
{
// 秘密鍵を含めてインポート(署名や復号が可能になる)
validationRsa.ImportFromPem(privatePem);
Console.WriteLine("- Private key import: Success");
// 念のため公開鍵だけで別インスタンスを初期化できるかも確認
using var publicOnlyRsa = RSA.Create();
publicOnlyRsa.ImportFromPem(publicPem);
Console.WriteLine("- Public key import: Success");
}
catch (CryptographicException ex)
{
Console.WriteLine($"- Import Error: {ex.Message}");
}
}
}
カスタムポイント
- キーサイズの変更:
RSA.Create(2048)の数値を4096に変更することで、強度は上がりますが処理速度は低下します。用途に合わせて調整してください。 - 保存先の変更: 現在は
Console.WriteLineで出力していますが、実運用ではSystem.IO.File.WriteAllText等を使用して.pemファイルとして保存するか、Azure Key Vault などのセキュアなストレージへ格納してください。 - フォーマットの選択: Java等のレガシーシステムと連携する場合は
ExportPkcs8PrivateKeyPemの代わりにExportEncryptedPkcs8PrivateKeyPemを使用し、パスワード付きでエクスポートすることを検討してください。
注意点
- 秘密鍵の流出厳禁: 出力された
secretToken(秘密鍵)は決して第三者に渡してはいけません。GitHub等のリポジトリへのコミットも厳禁です。 - ToXmlStringの利用回避: 古いコードで見られる
ToXmlStringはWindows固有の実装に依存する場合があり、Linux/Docker環境で動作しないことがあります。現代の.NET開発では上記のようなPEM形式またはDER(バイナリ)形式の使用が推奨されます。 - エフェメラルキーの寿命:
RSA.Create()で生成されたキーはメモリ上にのみ存在します。アプリケーション終了とともに消滅するため、永続化が必要な場合は必ずエクスポートして保存してください。
応用
署名データの作成(秘密鍵を使用)
生成したキーを使用して、データの改ざん検知用署名を作成する例です。
using System.Text;
// ... (前述のコードでキー生成済みとする) ...
var data = "Important Contract Data";
var dataBytes = Encoding.UTF8.GetBytes(data);
// 署名の作成(SHA256ハッシュを使用)
byte[] signature = secureIdentity.SignData(dataBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
Console.WriteLine($"\nSignature generated: {BitConverter.ToString(signature).Replace("-", "")}");
まとめ
秘密鍵の管理には細心の注意を払い、必要な場合のみエクスポート処理を行ってください。
RSAキー生成には RSACryptoServiceProvider ではなく RSA.Create() を使用します。
キーの文字列化には、互換性の低いXML形式ではなく、標準的なPEM形式(Export...Pem)を使用するのが現代の定石です。
