C# で RSA暗号 (公開鍵暗号) を 利用 する 方法

0 件のコメント

ここでは 公開鍵暗号 で利用される RSA暗号 を C# で実際に利用するサンプルを掲載します。 あくまで暗号の利用に注目しての記事とするので、通信等のやり取りに関しては割愛します。

目次

鍵生成

RSA暗号では最初に公開鍵と秘密鍵のペアを作成します。 作成した公開鍵を利用して暗号化されたデータは秘密鍵によってのみ復号できます。 C# の RSACryptoServiceProvider を利用する場合、以下のようなパラメータが出力されます。

公開鍵

  • Modulus (法)
  • Exponent (指数)

秘密鍵

  • Modulus (法)
  • Exponent (指数)
  • P
  • Q
  • DP
  • DQ
  • InverseQ
  • D

※ 秘密鍵は公開鍵(Modulus、Exponent)を含んだものになっています。

鍵の生成

単純な鍵生成を行いたい場合、引数なしでインスタンス生成することで新規鍵を生成できます。 以下のサンプルコードでは鍵サイズを指定してインスタンス生成しています。

using System.Security.Cryptography;

private void CreateKey()
{
    // 新規鍵の設定
    var size = 1024;

    // 新規鍵の生成
    var csp = new RSACryptoServiceProvider(size);

    // 公開鍵をXMLで取得
    var publickKey = csp.ToXmlString(false);

    // 秘密鍵をXMLで取得
    var privateKey = csp.ToXmlString(true);
}

一度生成した鍵の保存、取り出し、削除

一度生成した鍵を保存して再利用する場合、キー コンテナ― を利用します。 生テキストでどこかに保存するのは非推奨なので止めてください。 キー コンテナ― に保存する場合は KeyContainerName を指定して RSACryptoServiceProvider を生成します。 キー コンテナ― から削除する場合も KeyContainerName を指定して 削除 を行います。

using System.Security.Cryptography;

/// <summary>
/// キーコンテナー名を指定して新規RSA鍵を生成します。
/// </summary>
/// <param name="keyContainerName">キーコンテナ―名</param>
/// <summary>
private void CreateKey(string keyContainerName)
{
    // 新規鍵の設定
    var size = 1024;
    var parameters = new CspParameters()
    {
        KeyContainerName = keyContainerName
    };

    // 新規鍵の生成
    var csp = new RSACryptoServiceProvider(size, parameters);

    // 公開鍵をXMLで取得
    var publickKey = csp.ToXmlString(false);

    // 秘密鍵をXMLで取得
    var privateKey = csp.ToXmlString(true);
}

/// キーコンテナ―名を指定してRSA鍵を削除します。
/// </summary>
/// <param name="keyContainerName">キーコンテナ―名</param>
private void DeleteKey(string keyContainerName)
{
    // コンテナ―名の指定
    var parameters = new CspParameters()
    {
        KeyContainerName = keyContainerName
    };

    // キーコンテナ―から鍵を削除
    using (var csp = new RSACryptoServiceProvider(parameters))
    {
        csp.PersistKeyInCsp = false;
        csp.Clear();
    }
}

暗号化

using System;
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// 公開鍵を指定して暗号化します。
/// </summary>
/// <param name="publicKey">公開鍵を表すXML文字列</param>
/// <param name="data">暗号化したい文字列</param>
/// <returns>暗号化された文字列</returns>
public string Encrypt(string publicKey, string data)
{
    // RSA暗号化サービスのインスタンスを準備
    var csp = new RSACryptoServiceProvider();
    csp.FromXmlString(publicKey);

    // 暗号化
    var encryptedData = csp.Encrypt(Encoding.UTF8.GetBytes(data), false);

    // Base64エンコードした文字列を返却
    return Convert.ToBase64String(encryptedData);
}

複合

using System;
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// 秘密鍵を指定して復号します。
/// </summary>
/// <param name="privateKey">秘密鍵</param>
/// <param name="data">復号したい文字列</param>
/// <returns>復号された文字列</returns>
private string Decrypt(string privateKey, string data)
{
    // RSA暗号化サービスのインスタンスを準備
    var csp = new RSACryptoServiceProvider();
    csp.FromXmlString(privateKey);

    // 復号
    var decryptedData = csp.Decrypt(Convert.FromBase64String(data), false);

    // UTF8に戻して返却
    return Encoding.UTF8.GetString(decryptedData);
}

参考記事