ここでは 公開鍵暗号 で利用される 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);
}
参考記事
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!