ここでは 公開鍵暗号 で利用される RSA暗号 を C# で実際に利用するサンプルを掲載します。 あくまで暗号の利用に注目しての記事とするので、通信等のやり取りに関しては割愛します。
目次
鍵生成
RSA暗号では最初に公開鍵と秘密鍵のペアを作成します。
作成した公開鍵を利用して暗号化されたデータは秘密鍵によってのみ復号できます。
C# の RSACryptoServiceProvider
を利用する場合、以下のようなパラメータが出力されます。
公開鍵
- Modulus (法)
- Exponent (指数)
秘密鍵
- Modulus (法)
- Exponent (指数)
- P
- Q
- DP
- DQ
- InverseQ
- D
※ 秘密鍵は公開鍵(Modulus、Exponent)を含んだものになっています。
鍵の生成
単純な鍵生成を行いたい場合、引数なしでインスタンス生成することで新規鍵を生成できます。 以下のサンプルコードでは鍵サイズを指定してインスタンス生成しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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
を指定して 削除 を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 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(); } } |
暗号化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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); } |
複合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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 の フォロー」 お願いします!!