RSA暗号を利用して暗号化する - C#

C#でRSA暗号を利用して暗号化するコードを紹介します。

プログラム

UI

下図のUIを作成します。Windows フォームを3つ作成します。

FormKeyGen.cs


FormEncrypt.cs


FormDecrypt.cs


コード

FormKeyGen.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace SimpleRsa
{
  public partial class FormKeyGen : Form
  {
    public FormKeyGen()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      RSACryptoServiceProvider rsacsp = new RSACryptoServiceProvider();

      string PublicKey = rsacsp.ToXmlString(false);
      string PrivateKey = rsacsp.ToXmlString(true);

      textBox1.Text = PublicKey;
      textBox2.Text = PrivateKey;
    }
  }
}

FormEncrypt.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace SimpleRsa
{
  public partial class FormEncrypt : Form
  {
    public FormEncrypt()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      RSACryptoServiceProvider rsacsp = new RSACryptoServiceProvider();

      string PublicKey = textBox1.Text;
      rsacsp.FromXmlString(PublicKey);

      string ContentText = textBox2.Text;
      byte[] contentData = Encoding.UTF8.GetBytes(ContentText);
      byte[] encryptedData = rsacsp.Encrypt(contentData, false);

      string EncrptedText = Convert.ToBase64String(encryptedData);
      textBox3.Text = EncrptedText;
    }
  }
}

FormDecrypt.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace SimpleRsa
{
  public partial class FormDecrypt : Form
  {
    public FormDecrypt()
    {
      InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
      RSACryptoServiceProvider rsacsp = new RSACryptoServiceProvider();

      string PrivateKey = textBox1.Text;
      rsacsp.FromXmlString(PrivateKey);

      string EncryptedText = textBox2.Text;    
      byte[] encryptedData = Convert.FromBase64String(EncryptedText);
      byte[] contentData = rsacsp.Decrypt(encryptedData, false);

      string ContentText = Encoding.UTF8.GetString(contentData);
      textBox3.Text = ContentText;
    }
  }
}

解説

FormKeyGen.cs

[鍵生成]ボタンのクリックにより、RSAの公開鍵と秘密鍵を作成します。
RSAのアルゴリズムや処理はRSACryptoServiceProvider クラスによって提供されます。RSACryptoServiceProvider のインスタンスを作成します。
  RSACryptoServiceProvider rsacsp = new RSACryptoServiceProvider();

鍵はRSACryptoServiceProvider のインスタンスオブジェクトのToXmlString()メソッドで取得できます。ToXmlStringメソッドの引数にfalse を与えると公開鍵を取得でき、trueを与えると、秘密鍵を取得できます。鍵はXML形式の文字列として取得できます。
  string PublicKey = rsacsp.ToXmlString(false);
  string PrivateKey = rsacsp.ToXmlString(true);

  textBox1.Text = PublicKey;
  textBox2.Text = PrivateKey;

FormEncrypt.cs

公開鍵を利用してコンテンツを暗号化します。

RSACryptoServiceProviderのインスタンスを作成します。
   RSACryptoServiceProvider rsacsp = new RSACryptoServiceProvider();

TextBoxに入力された公開鍵を読み取り、RSACryptoServiceProvider に設定します。RSACryptoServiceProvider への設定には、FromXmlStringメソッドを利用します。
  string PublicKey = textBox1.Text;
  rsacsp.FromXmlString(PublicKey);

TextBoxに入力された暗号化する文字列を読み取ります。String型のままでは暗号化できないため、UTF8でエンコーディングしたbyte配列に変換します。
  string ContentText = textBox2.Text;
  byte[] contentData = Encoding.UTF8.GetBytes(ContentText);

RSACryptoServiceProvider オブジェクトのEncrypt()メソッドを呼び出し暗号化します。第一引数に暗号化するbyte配列のデータを与えます。第二引数はOAEPパディングの設定フラグです。今回はfalseを与えます。(OAEPパディングを有効にすると、平文(元データ)を加工し選択平文攻撃や選択暗号文攻撃に耐えられるようにします。)
Encrypt()メソッドの戻り値のbyte配列が暗号文になります。
  byte[] encryptedData = rsacsp.Encrypt(contentData, false);

暗号文をBase64でエンコードしてテキストボックスに表示します。
  string EncrptedText = Convert.ToBase64String(encryptedData);
  textBox3.Text = EncrptedText;

FormDecrypt.cs

公開鍵を利用してコンテンツを暗号化します。

RSACryptoServiceProviderのインスタンスを作成します。
  RSACryptoServiceProvider rsacsp = new RSACryptoServiceProvider();

TextBoxに入力された秘密鍵を読み取り、RSACryptoServiceProvider に設定します。RSACryptoServiceProvider への設定には、FromXmlStringメソッドを利用します。
  string PrivateKey = textBox1.Text;
  rsacsp.FromXmlString(PrivateKey);

TextBoxに入力された暗号文を読み取ります。String型のままでは複合化できないため、Base64でデコードしbyte配列に変換します。
  string EncryptedText = textBox2.Text;    
  byte[] encryptedData = Convert.FromBase64String(EncryptedText);

RSACryptoServiceProvider オブジェクトのDecrypt()メソッドを呼び出し復号化します。第一引数に復号化するbyte配列のデータを与えます。第二引数はOAEPパディングの設定フラグです。暗号化時にfalseを指定しているため、今回はfalseを与えます。
Decrypt()メソッドの戻り値に、復号されたデーターが返ります。
  byte[] contentData = rsacsp.Decrypt(encryptedData, false);

復号された平文をBase64でUTF8でエンコードされた文字列としてテキストボックスに表示します。
  string ContentText = Encoding.UTF8.GetString(contentData);
  textBox3.Text = ContentText;

実行結果

鍵生成

プロジェクトを実行し、FormKeyGenフォームを表示します。下図のウィンドウが表示されます。


[鍵生成]ボタンをクリックします。テキストボックスに公開鍵と秘密鍵のXMLが表示されます。表示された秘密鍵と公開鍵をメモ帳などにコピーペーストし、保存します。

暗号化

FormEncryptフォームを表示します。下図のウィンドウが表示されます。


公開鍵のテキストボックスに、先のFormKeyGenフォームで生成された、XML形式の公開鍵を入力します。コンテンツのテキストボックスに暗号化したい文字列を入力します。


テキスト入力後[暗号化]ボタンをクリックします。暗号文のテキストボックスに暗号化された文字列が表示されます。この文字列を保存します。

復号化

FormDecryptフォームを表示します。下図のウィンドウが表示されます。


秘密鍵のテキストボックスに鍵生成で生成したXML形式の秘密鍵を入力します。暗号文のテキストボックスに、先のFormEncryptフォームで暗号化された暗号文を入力します。


[復号化]ボタンをクリックします。暗号文が復号化され、平文がコンテンツ欄のテキストボックスに表示されます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2016-12-19
iPentec all rights reserverd.