次の方法で共有


チュートリアル : 暗号化アプリケーションの作成

このチュートリアルでは、コンテンツの暗号化と復号化を行う方法について説明します。 このコード例は、Windows フォーム アプリケーション用として設計されています。 このアプリケーションは、スマート カードを使用するなどの現実的な状況ではなく、 暗号化と復号化の基本を示すためのものです。

このチュートリアルは、暗号化に関する次のガイドラインに従っています。

  • 対称アルゴリズムである RijndaelManaged クラスを使用して、自動的に生成される KeyIV でデータを暗号化および復号化する。

  • 非対称アルゴリズムである RSACryptoServiceProvider を使用して、RijndaelManaged で暗号化されたデータに対するキーを暗号化および復号化する。 非対称アルゴリズムは、キーなどの少量のデータに対してよく使用されます。

    メモメモ

    暗号化した内容を他のユーザーと交換するのではなく、コンピューター上のデータを保護することが目的の場合は、ProtectedData クラスまたは ProtectedMemory クラスの使用をお勧めします。

このトピックにおける暗号化タスクの概要を次の表に示します。

タスク

説明

Windows フォーム アプリケーションの作成

アプリケーションの実行に必要なコントロールを一覧で示します。

グローバル オブジェクトの宣言

文字列パス変数、CspParameters、および RSACryptoServiceProvider を宣言し、Form クラスのグローバル コンテキストを設定します。

非対称キーの作成

非対称の公開キーと秘密キーの値のペアを作成し、キー コンテナー名を割り当てます。

ファイルの暗号化

暗号化するファイルを選択するダイアログ ボックスを表示して、ファイルを暗号化します。

ファイルの復号化

復号化する暗号化ファイルを選択するダイアログ ボックスを表示して、ファイルを復号化します。

秘密キーの取得

キー コンテナー名を使用して、完全なキー ペアを取得します。

公開キーのエクスポート

公開パラメーターのみを使用して、キーを XML ファイルに保存します。

公開キーのインポート

XML ファイルからキー コンテナーにキーを読み込みます。

アプリケーションのテスト

このアプリケーションをテストする手順を示します。

必須コンポーネント

このチュートリアルを実行するには、次のコンポーネントが必要です。

Windows フォーム アプリケーションの作成

このチュートリアルでは、ほとんどのコード例が、ボタン コントロールのイベント ハンドラーとして設計されています。 サンプル アプリケーションに必要なコントロールおよびコード例と対応付けるのに必要な名前を次の表に示します。

コントロール

名前

テキスト プロパティ (必要な場合)

Button

buttonEncryptFile

Encrypt File (ファイルの暗号化)

Button

buttonDecryptFile

Decrypt File (ファイルの復号化)

Button

buttonCreateAsmKeys

Create Keys (キーの作成)

Button

buttonExportPublicKey

Export Public Key (公開キーのエクスポート)

Button

buttonImportPublicKey

Import Public Key (公開キーのインポート)

Button

buttonGetPrivateKey

Get Private Key (秘密キーの取得)

Label

label1

OpenFileDialog

openFileDialog1

OpenFileDialog

openFileDialog2

Visual Studio デザイナーの各ボタンをダブルクリックし、各ボタンに対応するイベント ハンドラーを作成します。

グローバル オブジェクトの宣言

次のコードをフォームのコンストラクターに追加します。 環境の文字列変数と基本設定を編集します。

' Declare CspParmeters and RsaCryptoServiceProvider 
' objects with global scope of your Form class.
Dim cspp As CspParameters = New System.Security.Cryptography.CspParameters
Dim rsa As RSACryptoServiceProvider

' Path variables for source, encryption, and
' decryption folders. Must end with a backslash.
Dim EncrFolder As String = "c:\Encrypt\"
Dim DecrFolder As String = "c:\Decrypt\"
Dim SrcFolder As String = "c:\docs\"

' Public key file
Dim PubKeyFile As String = "c:\encrypt\rsaPublicKey.txt"

' Key container name for
' private/public key value pair.
Dim keyName As String = "Key01"
// Declare CspParmeters and RsaCryptoServiceProvider
// objects with global scope of your Form class.
CspParameters cspp = new CspParameters();
RSACryptoServiceProvider rsa;

// Path variables for source, encryption, and
// decryption folders. Must end with a backslash.
const string EncrFolder = @"c:\Encrypt\";
const string DecrFolder = @"c:\Decrypt\";
const string SrcFolder = @"c:\docs\";

// Public key file
const string PubKeyFile = @"c:\encrypt\rsaPublicKey.txt";

// Key container name for
// private/public key value pair.
const string keyName = "Key01";

非対称キーの作成

このタスクでは、RijndaelManaged キーの暗号化と復号化を行う非対称キーを作成します。 このキーは、内容を暗号化するときに使用されたもので、ラベル コントロールにキー コンテナー名を表示します。

[Create Keys] ボタンの Click イベント ハンドラー (buttonCreateAsmKeys_Click) として次のコードを追加します。

Private Sub buttonCreateAsmKeys_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonCreateAsmKeys.Click
    ' Stores a key pair in the key container.
    cspp.KeyContainerName = keyName
    rsa = New RSACryptoServiceProvider(cspp)
    rsa.PersistKeyInCsp = True

    If rsa.PublicOnly = True Then
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only"
    Else
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair"
    End If

End Sub
private void buttonCreateAsmKeys_Click(object sender, System.EventArgs e)
{
    // Stores a key pair in the key container.
    cspp.KeyContainerName = keyName;
    rsa = new RSACryptoServiceProvider(cspp);
    rsa.PersistKeyInCsp = true;
    if (rsa.PublicOnly == true)
       label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
    else
       label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";

}

ファイルの暗号化

このタスクでは、[Encrypt File] ボタンのイベント ハンドラー メソッド (buttonEncryptFile_Click) と EncryptFile メソッドの 2 つのメソッドを使用します。 最初のメソッドでファイルを選択するダイアログ ボックスを表示し、選択したファイルの名前を、暗号化を実行する 2 番目のメソッドに渡します。

暗号化した内容、キー、IV のすべてを、暗号化パッケージと呼ばれる 1 つの FileStream に保存します。

EncryptFile メソッドは次の処理を行います。

  1. RijndaelManaged 対称アルゴリズムを作成して内容を暗号化する。

  2. RSACryptoServiceProvider オブジェクトを作成して RijndaelManaged キーを暗号化する。

  3. CryptoStream オブジェクトを使用してソース ファイルの FileStream をバイト ブロックの中に読み取り、暗号化して暗号化ファイル用の FileStream オブジェクトに格納する。

  4. 暗号化されたキーと IV の長さを判断し、それらの長さの値に相当するバイト配列を作成する。

  5. キー、IV、および長さの値を暗号化パッケージに書き込む。

暗号化パッケージでは、次の形式が使用されます。

  • キーの長さ、バイト 0 ~ 3

  • IV の長さ、バイト 4 ~ 7

  • 暗号化されたキー

  • IV

  • 暗号文

キーと IV の長さにより、ファイルを復号化するときに使用する、暗号化パッケージのすべての部分の開始位置と長さを判断できます。

[Encrypt File] ボタンの Click イベント ハンドラー (buttonEncryptFile_Click) として次のコードを追加します。

Private Sub buttonEncryptFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonEncryptFile.Click
    If rsa Is Nothing Then
        MsgBox("Key not set.")
    Else
        ' Display a dialog box to select a file to encrypt.
        OpenFileDialog1.InitialDirectory = SrcFolder
        If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Try
                Dim fName As String = OpenFileDialog1.FileName
                If (Not (fName) Is Nothing) Then
                    Dim fInfo As FileInfo = New FileInfo(fName)
                    ' Use just the file name without path.
                    Dim name As String = fInfo.FullName
                    EncryptFile(name)
                End If
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End If
    End If
End Sub
private void buttonEncryptFile_Click(object sender, System.EventArgs e)
{
    if (rsa == null)
        MessageBox.Show("Key not set.");
    else
    {

        // Display a dialog box to select a file to encrypt.
        openFileDialog1.InitialDirectory = SrcFolder;
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            string fName = openFileDialog1.FileName;
            if (fName != null)
            {
                FileInfo fInfo = new FileInfo(fName);
                // Pass the file name without the path.
                string name = fInfo.FullName;
                EncryptFile(name);
            }
        }
    }
}

フォームに次の EncryptFile メソッドを追加します。

Private Sub EncryptFile(ByVal inFile As String)

    ' Create instance of Rijndael for
    ' symetric encryption of the data.
    Dim rjndl As RijndaelManaged = New RijndaelManaged
    rjndl.KeySize = 256
    rjndl.BlockSize = 256
    rjndl.Mode = CipherMode.CBC
    Dim transform As ICryptoTransform = rjndl.CreateEncryptor

    ' Use RSACryptoServiceProvider to 
    ' enrypt the Rijndael key.
    Dim keyEncrypted() As Byte = rsa.Encrypt(rjndl.Key, False)

    ' Create byte arrays to contain
    ' the length values of the key and IV.
    Dim LenK() As Byte = New Byte((4) - 1) {}
    Dim LenIV() As Byte = New Byte((4) - 1) {}
    Dim lKey As Integer = keyEncrypted.Length
    LenK = BitConverter.GetBytes(lKey)
    Dim lIV As Integer = rjndl.IV.Length
    LenIV = BitConverter.GetBytes(lIV)

    ' Write the following to the FileStream
    ' for the encrypted file (outFs):
    ' - length of the key
    ' - length of the IV
    ' - ecrypted key
    ' - the IV
    ' - the encrypted cipher content
    ' Change the file's extension to ".enc"
    Dim startFileName As Integer = inFile.LastIndexOf("\") + 1
    Dim outFile As String = (EncrFolder _
                + (inFile.Substring(startFileName, inFile.LastIndexOf(".") - startFileName) + ".enc"))

    Using outFs As FileStream = New FileStream(outFile, FileMode.Create)

        outFs.Write(LenK, 0, 4)
        outFs.Write(LenIV, 0, 4)
        outFs.Write(keyEncrypted, 0, lKey)
        outFs.Write(rjndl.IV, 0, lIV)

        ' Now write the cipher text using
        ' a CryptoStream for encrypting.
        Using outStreamEncrypted As CryptoStream = New CryptoStream(outFs, transform, CryptoStreamMode.Write)
            ' By encrypting a chunk at
            ' a time, you can save memory
            ' and accommodate large files.
            Dim count As Integer = 0
            Dim offset As Integer = 0

            ' blockSizeBytes can be any arbitrary size.
            Dim blockSizeBytes As Integer = (rjndl.BlockSize / 8)
            Dim data() As Byte = New Byte((blockSizeBytes) - 1) {}
            Dim bytesRead As Integer = 0
            Using inFs As FileStream = New FileStream(inFile, FileMode.Open)
                Do
                    count = inFs.Read(data, 0, blockSizeBytes)
                    offset = (offset + count)
                    outStreamEncrypted.Write(data, 0, count)
                    bytesRead = (bytesRead + blockSizeBytes)
                Loop Until (count = 0)

                outStreamEncrypted.FlushFinalBlock()
                inFs.Close()
            End Using
            outStreamEncrypted.Close()
        End Using
        outFs.Close()
    End Using
End Sub

private void EncryptFile(string inFile)
{

    // Create instance of Rijndael for
    // symetric encryption of the data.
    RijndaelManaged rjndl = new RijndaelManaged();
    rjndl.KeySize = 256;
    rjndl.BlockSize = 256;
    rjndl.Mode = CipherMode.CBC;
    ICryptoTransform transform = rjndl.CreateEncryptor();

    // Use RSACryptoServiceProvider to
    // enrypt the Rijndael key.
    // rsa is previously instantiated: 
    //    rsa = new RSACryptoServiceProvider(cspp);
    byte[] keyEncrypted = rsa.Encrypt(rjndl.Key, false);

    // Create byte arrays to contain
    // the length values of the key and IV.
    byte[] LenK = new byte[4];
    byte[] LenIV = new byte[4];

    int lKey = keyEncrypted.Length;
    LenK = BitConverter.GetBytes(lKey);
    int lIV = rjndl.IV.Length;
    LenIV = BitConverter.GetBytes(lIV);

    // Write the following to the FileStream
    // for the encrypted file (outFs):
    // - length of the key
    // - length of the IV
    // - ecrypted key
    // - the IV
    // - the encrypted cipher content

    int startFileName = inFile.LastIndexOf("\\") + 1;
   // Change the file's extension to ".enc"
    string outFile = EncrFolder + inFile.Substring(startFileName, inFile.LastIndexOf(".")- startFileName) + ".enc";

    using (FileStream outFs = new FileStream(outFile, FileMode.Create))
    {

            outFs.Write(LenK, 0, 4);
            outFs.Write(LenIV, 0, 4);
            outFs.Write(keyEncrypted, 0, lKey);
            outFs.Write(rjndl.IV, 0, lIV);

            // Now write the cipher text using
            // a CryptoStream for encrypting.
            using (CryptoStream outStreamEncrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
            {

                // By encrypting a chunk at
                // a time, you can save memory
                // and accommodate large files.
                int count = 0;
                int offset = 0;

                // blockSizeBytes can be any arbitrary size.
                int blockSizeBytes = rjndl.BlockSize / 8;
                byte[] data = new byte[blockSizeBytes];
                int bytesRead = 0;

                using (FileStream inFs = new FileStream(inFile, FileMode.Open))
                {
                    do
                    {
                        count = inFs.Read(data, 0, blockSizeBytes);
                        offset += count;
                        outStreamEncrypted.Write(data, 0, count);
                        bytesRead += blockSizeBytes;
                    }
                    while (count > 0);
                inFs.Close();
                }
                outStreamEncrypted.FlushFinalBlock();
                outStreamEncrypted.Close();
            }
            outFs.Close();
    }

}

ファイルの復号化

このタスクでは、[Decrypt File] ボタンのイベント ハンドラー メソッド (buttonEncryptFile_Click) と DecryptFile メソッドの 2 つのメソッドを使用します。 最初のメソッドでファイルを選択するダイアログ ボックスを表示し、選択したファイルの名前を復号化を実行する 2 番目のメソッドに渡します。

Decrypt メソッドは次の処理を行います。

  1. RijndaelManaged 対称アルゴリズムを作成して内容を復号化する。

  2. 暗号化パッケージの FileStream の最初の 8 バイトをバイト配列に読み取り、暗号化されたキーと IV の長さを取得する。

  3. 暗号化パッケージからキーと IV をバイト配列に抽出する。

  4. RSACryptoServiceProvider オブジェクトを作成して RijndaelManaged キーを復号化する。

  5. CryptoStream オブジェクトを使用して FileStream 暗号化パッケージの暗号文セクションをバイト ブロックの中に読み取り、復号化して、復号化ファイル用の FileStream オブジェクトに格納する。 このタスクが終了すると、復号化が完了します。

[Decrypt File] ボタンの Click イベント ハンドラーとして次のコードを追加します。

Private Sub buttonDecryptFile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonDecryptFile.Click
    If rsa Is Nothing Then
        MsgBox("Key not set.")
    Else
        ' Display a dialog box to select the encrypted file.
        OpenFileDialog2.InitialDirectory = EncrFolder
        If (OpenFileDialog2.ShowDialog = Windows.Forms.DialogResult.OK) Then
            Try
                Dim fName As String = OpenFileDialog2.FileName
                If (Not (fName) Is Nothing) Then
                    Dim fi As FileInfo = New FileInfo(fName)
                    Dim name As String = fi.Name
                    DecryptFile(name)
                End If
            Catch ex As Exception
                MessageBox.Show(ex.Message)
            End Try
        End If
    End If
End Sub
private void buttonDecryptFile_Click(object sender, EventArgs e)
{
    if (rsa == null)
        MessageBox.Show("Key not set.");
    else
    {
        // Display a dialog box to select the encrypted file.
        openFileDialog2.InitialDirectory = EncrFolder;
        if (openFileDialog2.ShowDialog() == DialogResult.OK)
        {
            string fName = openFileDialog2.FileName;
            if (fName != null)
            {
                FileInfo fi = new FileInfo(fName);
                string name = fi.Name;
                DecryptFile(name);
            }
        }
    }
}

フォームに次の DecryptFile メソッドを追加します。

Private Sub DecryptFile(ByVal inFile As String)
    ' Create instance of Rijndael for
    ' symetric decryption of the data.
    Dim rjndl As RijndaelManaged = New RijndaelManaged
    rjndl.KeySize = 256
    rjndl.BlockSize = 256
    rjndl.Mode = CipherMode.CBC

    ' Create byte arrays to get the length of
    ' the encrypted key and IV.
    ' These values were stored as 4 bytes each
    ' at the beginning of the encrypted package.
    Dim LenK() As Byte = New Byte(4 - 1) {}
    Dim LenIV() As Byte = New Byte(4 - 1) {}

    ' Construct the file name for the decrypted file.
    Dim outFile As String = (DecrFolder _
                + (inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt"))

    ' Use FileStream objects to read the encrypted
    ' file (inFs) and save the decrypted file (outFs).
    Using inFs As FileStream = New FileStream((EncrFolder + inFile), FileMode.Open)

        inFs.Seek(0, SeekOrigin.Begin)
        inFs.Read(LenK, 0, 3)
        inFs.Seek(4, SeekOrigin.Begin)
        inFs.Read(LenIV, 0, 3)

        Dim lengthK As Integer = BitConverter.ToInt32(LenK, 0)
        Dim lengthIV As Integer = BitConverter.ToInt32(LenIV, 0)
        Dim startC As Integer = (lengthK + lengthIV + 8)
        Dim lenC As Integer = (CType(inFs.Length, Integer) - startC)
        Dim KeyEncrypted() As Byte = New Byte(lengthK - 1) {}
        Dim IV() As Byte = New Byte(lengthIV - 1) {}

        ' Extract the key and IV
        ' starting from index 8
        ' after the length values.
        inFs.Seek(8, SeekOrigin.Begin)
        inFs.Read(KeyEncrypted, 0, lengthK)
        inFs.Seek(8 + lengthK, SeekOrigin.Begin)
        inFs.Read(IV, 0, lengthIV)
        Directory.CreateDirectory(DecrFolder)
        ' User RSACryptoServiceProvider
        ' to decryt the Rijndael key
        Dim KeyDecrypted() As Byte = rsa.Decrypt(KeyEncrypted, False)

        ' Decrypt the key.
        Dim transform As ICryptoTransform = rjndl.CreateDecryptor(KeyDecrypted, IV)
        ' Decrypt the cipher text from
        ' from the FileSteam of the encrypted
        ' file (inFs) into the FileStream
        ' for the decrypted file (outFs).
        Using outFs As FileStream = New FileStream(outFile, FileMode.Create)
            Dim count As Integer = 0
            Dim offset As Integer = 0

            ' blockSizeBytes can be any arbitrary size.
            Dim blockSizeBytes As Integer = (rjndl.BlockSize / 8)
            Dim data() As Byte = New Byte(blockSizeBytes - 1) {}
            ' By decrypting a chunk a time,
            ' you can save memory and
            ' accommodate large files.
            ' Start at the beginning
            ' of the cipher text.
            inFs.Seek(startC, SeekOrigin.Begin)
            Using outStreamDecrypted As CryptoStream = New CryptoStream(outFs, transform, CryptoStreamMode.Write)
                Do
                    count = inFs.Read(data, 0, blockSizeBytes)
                    offset = (offset + count)
                    outStreamDecrypted.Write(data, 0, count)
                Loop Until (count = 0)

                outStreamDecrypted.FlushFinalBlock()
                outStreamDecrypted.Close()
            End Using
            outFs.Close()
        End Using
        inFs.Close()
    End Using
End Sub
private void DecryptFile(string inFile)
{

    // Create instance of Rijndael for
    // symetric decryption of the data.
    RijndaelManaged rjndl = new RijndaelManaged();
    rjndl.KeySize = 256;
    rjndl.BlockSize = 256;
    rjndl.Mode = CipherMode.CBC;

    // Create byte arrays to get the length of
    // the encrypted key and IV.
    // These values were stored as 4 bytes each
    // at the beginning of the encrypted package.
    byte[] LenK = new byte[4];
    byte[] LenIV = new byte[4];

    // Consruct the file name for the decrypted file.
    string outFile = DecrFolder + inFile.Substring(0, inFile.LastIndexOf(".")) + ".txt";

    // Use FileStream objects to read the encrypted
    // file (inFs) and save the decrypted file (outFs).
    using (FileStream inFs = new FileStream(EncrFolder + inFile, FileMode.Open))
    {

        inFs.Seek(0, SeekOrigin.Begin);
        inFs.Seek(0, SeekOrigin.Begin);
        inFs.Read(LenK, 0, 3);
        inFs.Seek(4, SeekOrigin.Begin);
        inFs.Read(LenIV, 0, 3);

        // Convert the lengths to integer values.
        int lenK = BitConverter.ToInt32(LenK, 0);
        int lenIV = BitConverter.ToInt32(LenIV, 0);

        // Determine the start postition of
        // the ciphter text (startC)
        // and its length(lenC).
        int startC = lenK + lenIV + 8;
        int lenC = (int)inFs.Length - startC;

        // Create the byte arrays for
        // the encrypted Rijndael key,
        // the IV, and the cipher text.
        byte[] KeyEncrypted = new byte[lenK];
        byte[] IV = new byte[lenIV];

        // Extract the key and IV
        // starting from index 8
        // after the length values.
        inFs.Seek(8, SeekOrigin.Begin);
        inFs.Read(KeyEncrypted, 0, lenK);
        inFs.Seek(8 + lenK, SeekOrigin.Begin);
        inFs.Read(IV, 0, lenIV);
        Directory.CreateDirectory(DecrFolder);
        // Use RSACryptoServiceProvider
        // to decrypt the Rijndael key.
        byte[] KeyDecrypted = rsa.Decrypt(KeyEncrypted, false);

        // Decrypt the key.
        ICryptoTransform transform = rjndl.CreateDecryptor(KeyDecrypted, IV);

        // Decrypt the cipher text from
        // from the FileSteam of the encrypted
        // file (inFs) into the FileStream
        // for the decrypted file (outFs).
        using (FileStream outFs = new FileStream(outFile, FileMode.Create))
        {

            int count = 0;
            int offset = 0;

            // blockSizeBytes can be any arbitrary size.
            int blockSizeBytes = rjndl.BlockSize / 8;
            byte[] data = new byte[blockSizeBytes];


            // By decrypting a chunk a time,
            // you can save memory and
            // accommodate large files.

            // Start at the beginning
            // of the cipher text.
            inFs.Seek(startC, SeekOrigin.Begin);
            using (CryptoStream outStreamDecrypted = new CryptoStream(outFs, transform, CryptoStreamMode.Write))
            {
                do
                {
                    count = inFs.Read(data, 0, blockSizeBytes);
                    offset += count;
                    outStreamDecrypted.Write(data, 0, count);

                }
                while (count > 0);

                outStreamDecrypted.FlushFinalBlock();
                outStreamDecrypted.Close();
            }
            outFs.Close();
        }
        inFs.Close();
    }

}

公開キーのエクスポート

このタスクは、[Create Keys] ボタンで作成されたキーをファイルに保存します。 公開パラメーターのみをエクスポートします。

このタスクは、Bob が Alice に渡すファイルを暗号化できるように、Alice が公開キーを Bob に渡すシナリオをシミュレートします。 Bob やその公開キーを持っている他のユーザーは、秘密パラメーターのある完全なキー ペアを持っていないため、そのファイルを復号化できません。

[Export Public Key] ボタンの Click イベント ハンドラー (buttonExportPublicKey_Click) として次のコードを追加します。

Private Sub buttonExportPublicKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonExportPublicKey.Click
    ' Save the public key created by the RSA
    ' to a file. Caution, persisting the
    ' key to a file is a security risk.
    Directory.CreateDirectory(EncrFolder)
    Dim sw As StreamWriter = New StreamWriter(PubKeyFile)
    sw.Write(rsa.ToXmlString(False))
    sw.Close()
End Sub
void buttonExportPublicKey_Click(object sender, System.EventArgs e)
{
    // Save the public key created by the RSA
    // to a file. Caution, persisting the
    // key to a file is a security risk.
    Directory.CreateDirectory(EncrFolder);
    StreamWriter sw = new StreamWriter(PubKeyFile, false);
    sw.Write(rsa.ToXmlString(false));
    sw.Close();
}

公開キーのインポート

このタスクは、[Export Public Key] ボタンで作成されたキーの公開パラメーターのみを読み込み、それをキー コンテナー名として設定します。

このタスクは、Bob が Alice のキーの公開パラメーターのみを読み込み、Alice に渡すファイルを暗号化するシナリオをシミュレートします。

[Import Public Key] ボタンの Click イベント ハンドラー (buttonImportPublicKey_Click) として次のコードを追加します。

Private Sub buttonImportPublicKey_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonImportPublicKey.Click
    Dim sr As StreamReader = New StreamReader(PubKeyFile)
    cspp.KeyContainerName = keyName
    rsa = New RSACryptoServiceProvider(cspp)
    Dim keytxt As String = sr.ReadToEnd
    rsa.FromXmlString(keytxt)
    rsa.PersistKeyInCsp = True
    If rsa.PublicOnly = True Then
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only"
    Else
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair"
    End If
    sr.Close()
End Sub
void buttonImportPublicKey_Click(object sender, System.EventArgs e)
{
    StreamReader sr = new StreamReader(PubKeyFile);
    cspp.KeyContainerName = keyName;
    rsa = new RSACryptoServiceProvider(cspp);
    string keytxt = sr.ReadToEnd();
    rsa.FromXmlString(keytxt);
    rsa.PersistKeyInCsp = true;
    if (rsa.PublicOnly == true)
        label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
    else
        label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";
    sr.Close();
}

秘密キーの取得

このタスクは、キー コンテナー名を、[Create Keys] ボタンを使用して作成されたキーの名前に設定します。 キー コンテナーは、秘密パラメーターを含む完全なキー ペアを表します。

このタスクは、Bob が暗号化したファイルを Alice が自分の秘密キーを使用して復号化するシナリオをシミュレートします。

[Get Private Key] ボタンの Click イベント ハンドラー (buttonGetPrivateKey_Click) として次のコードを追加します。

Private Sub buttonGetPrivateKey_Click(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles buttonGetPrivateKey.Click
    cspp.KeyContainerName = keyName
    rsa = New RSACryptoServiceProvider(cspp)
    rsa.PersistKeyInCsp = True
    If rsa.PublicOnly = True Then
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only"
    Else
        Label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair"
    End If
End Sub
private void buttonGetPrivateKey_Click(object sender, EventArgs e)
{
    cspp.KeyContainerName = keyName;

    rsa = new RSACryptoServiceProvider(cspp);
    rsa.PersistKeyInCsp = true;

    if (rsa.PublicOnly == true)
        label1.Text = "Key: " + cspp.KeyContainerName + " - Public Only";
    else
        label1.Text = "Key: " + cspp.KeyContainerName + " - Full Key Pair";

}

アプリケーションのテスト

アプリケーションを作成したら、以下のテストを実行します。

キーの作成、暗号化、および復号化を行うには

  1. [Create Keys] をクリックします。 ラベルにキー名が表示されます。また、これが完全なキー ペアであることも表示されます。

  2. [Export Public Key] をクリックします。 公開キー パラメーターをエクスポートしても、現在のキーは変更されません。

  3. [Encrypt File] をクリックし、ファイルを選択します。

  4. [Decrypt File] をクリックし、前の手順で暗号化したファイルを選択します。

  5. ファイルが復号化されたことを確認します。

  6. アプリケーションを終了して再起動し、次のシナリオで、保持されたキー コンテナーの取得をテストします。

公開キーを使用して暗号化するには

  1. [Import Public Key] をクリックします。 ラベルにキー名が表示されます。また、これが公開キーのみであることも表示されます。

  2. [Encrypt File] をクリックし、ファイルを選択します。

  3. [Decrypt File] をクリックし、前の手順で暗号化したファイルを選択します。 復号化するには秘密キーが必要なため、この操作は失敗します。

このシナリオは、公開キーのみを持っている場合は、他のユーザーに渡すファイルを暗号化することを示します。 通常、そのユーザーは公開キーのみを渡し、復号化に使用する秘密キーは渡しません。

秘密キーを使用して復号化するには

  1. [Get Private Key] をクリックします。 ラベルにキー名が表示されます。また、それが完全なキー ペアかどうかも表示されます。

  2. [Decrypt File] をクリックし、前の手順で暗号化したファイルを選択します。 復号化するための完全なキー ペアを持っているため、この操作は正常に終了します。

参照

概念

暗号サービス

その他の技術情報

暗号タスク