次の方法で共有


データの復号化

更新 : 2007 年 11 月

復号化は暗号化の逆の操作です。共有キー暗号方式では、データを暗号化するときに使用されたキーと IV の両方を知っておく必要があります。公開キー暗号方式では、公開キー (秘密キーでデータが暗号化された場合) または秘密キー (公開キーでデータが暗号化された場合) のいずれかを知っている必要があります。

対称復号化方式

対称アルゴリズムによって暗号化されたデータの復号化は、対称アルゴリズムによってデータを暗号化するプロセスと似ています。CryptoStream クラスは、任意のマネージ ストリーム オブジェクトから読み込まれたデータを復号化するために .NET Framework に用意されている、対称暗号化クラスと共に使用されます。

RijndaelManaged クラスの新しいインスタンスを作成する方法と、それを使用して CryptoStream オブジェクトで復号化を実行する方法を次の例に示します。この例では、まず RijndaelManaged クラスの新しいインスタンスを作成します。次に CryptoStream オブジェクトを作成し、MyStream というマネージ ストリームの値に初期化します。次に、暗号化で使用されたのと同じキーと IV を RijndaelManaged クラスの CreateDecryptor メソッドに渡し、その戻り値を CryptoStream コンストラクタに渡します。最後に、CryptoStreamMode.Read 列挙値を CryptoStream コンストラクタに渡し、ストリームへの読み込みアクセスを指定します。

Dim RMCrypto As New RijndaelManaged()
Dim CryptStream As New CryptoStream(MyStream, RMCrypto.CreateDecryptor(RMCrypto.Key, RMCrypto.IV), CryptoStreamMode.Read)
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream CryptStream = new CryptoStream(MyStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read);

ストリームを作成し、ストリームを復号化し、ストリームから読み込み、ストリームを閉じるプロセス全体を次の例に示します。待機オブジェクトへの接続時に、ネットワーク ストリームを初期化する TCPListener オブジェクトが作成されます。次に、CryptoStream クラスと RijndaelManaged クラスを使用してネットワーク ストリームを復号化します。この例では、キーと IV の値が正常に転送されているか、またはあらかじめ一致していることが前提となります。この例には、キーと IV の値を暗号化および転送するために必要なコードは含まれません。

Imports System
Imports System.Net.Sockets
Imports System.Threading
Imports System.IO
Imports System.Net
Imports System.Security.Cryptography

Module Module1
    Sub Main()
            'The key and IV must be the same values that were used
            'to encrypt the stream.  
            Dim Key As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}
            Dim IV As Byte() = {&H1, &H2, &H3, &H4, &H5, &H6, &H7, &H8, &H9, &H10, &H11, &H12, &H13, &H14, &H15, &H16}
        Try
            'Initialize a TCPListener on port 11000
            'using the current IP address.
            Dim TCPListen As New TcpListener(IPAddress.Any, 11000)

            'Start the listener.
            TCPListen.Start()

            'Check for a connection every five seconds.
            While Not TCPListen.Pending()
                Console.WriteLine("Still listening. Will try in 5 seconds.")

                Thread.Sleep(5000)
            End While

            'Accept the client if one is found.
            Dim TCP As TcpClient = TCPListen.AcceptTcpClient()

            'Create a network stream from the connection.
            Dim NetStream As NetworkStream = TCP.GetStream()

            'Create a new instance of the RijndaelManaged class
            'and decrypt the stream.
            Dim RMCrypto As New RijndaelManaged()


            'Create an instance of the CryptoStream class, pass it the NetworkStream, and decrypt 
            'it with the Rijndael class using the key and IV.
            Dim CryptStream As New CryptoStream(NetStream, RMCrypto.CreateDecryptor(Key, IV), CryptoStreamMode.Read)

            'Read the stream.
            Dim SReader As New StreamReader(CryptStream)

            'Display the message.
            Console.WriteLine("The decrypted original message: {0}", SReader.ReadToEnd())

            'Close the streams.
            SReader.Close()
            NetStream.Close()
            TCP.Close()
            'Catch any exceptions. 
        Catch
            Console.WriteLine("The Listener Failed.")
        End Try
    End Sub
End Module
using System;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Net;
using System.Security.Cryptography;

class Class1
{
   static void Main(string[] args)
   {
      //The key and IV must be the same values that were used
      //to encrypt the stream.  
      byte[] Key = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
      byte[] IV = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
      try
      {
         //Initialize a TCPListener on port 11000
         //using the current IP address.
         TcpListener TCPListen = new TcpListener(IPAdress.Any, 11000);

         //Start the listener.
         TCPListen.Start();

         //Check for a connection every five seconds.
         while(!TCPListen.Pending())
         {
            Console.WriteLine("Still listening. Will try in 5 seconds.");
            Thread.Sleep(5000);
         }

         //Accept the client if one is found.
         TcpClient TCP = TCPListen.AcceptTcpClient();

         //Create a network stream from the connection.
         NetworkStream NetStream = TCP.GetStream();

         //Create a new instance of the RijndaelManaged class
         // and decrypt the stream.
         RijndaelManaged RMCrypto = new RijndaelManaged();


         //Create a CryptoStream, pass it the NetworkStream, and decrypt 
         //it with the Rijndael class using the key and IV.
         CryptoStream CryptStream = new CryptoStream(NetStream, 
            RMCrypto.CreateDecryptor(Key, IV), 
            CryptoStreamMode.Read);

         //Read the stream.
         StreamReader SReader = new StreamReader(CryptStream);

         //Display the message.
         Console.WriteLine("The decrypted original message: {0}", SReader.ReadToEnd());

         //Close the streams.
         SReader.Close();
         NetStream.Close();
         TCP.Close();
      }
      //Catch any exceptions. 
      catch
      {
         Console.WriteLine("The Listener Failed.");
      }
   }
}

上記の例を正しく動作させるためには、リスナへの接続を暗号化する必要があります。この接続では、リスナと同じキー、IV、およびアルゴリズムを使用する必要があります。そのような接続が確立されると、メッセージが復号化されてコンソールに表示されます。

非対称復号化方式

通常は、送信側 (A) が公開キーと秘密キーの両方を生成して、キーをメモリまたは暗号化キー コンテナに格納します。次に A は、相手側 (B) に公開キーを送信します。B は公開キーを使用してデータを暗号化し、そのデータを A に返信します。A はデータを受け取った後で、対応する秘密キーを使用してデータを復号化します。復号化が成功するのは、B がデータの暗号化で使用した公開キーに対応する秘密キーを A が使用した場合だけです。

非対称キーを安全な暗号化キー コンテナに格納する方法、および非対称キーを後で取得する方法については、「方法 : キー コンテナに非対称キーを格納する」を参照してください。

共通キーと IV を表現する 2 つのバイト配列の復号化を次の例に示します。非対称の公開キーを、第三者に簡単に送信できる形式で RSACryptoServiceProvider オブジェクトから抽出する方法については、「データの暗号化」を参照してください。

'Create a new instance of the RSACryptoServiceProvider class.
Dim RSA As New RSACryptoServiceProvider()

' Export the public key information and send it to a third party.
' Wait for the third party to encrypt some data and send it back.

'Decrypt the symmetric key and IV.
SymmetricKey = RSA.Decrypt(EncryptedSymmetricKey, False)
SymmetricIV = RSA.Decrypt(EncryptedSymmetricIV, False)
//Create a new instance of the RSACryptoServiceProvider class.
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

// Export the public key information and send it to a third party.
// Wait for the third party to encrypt some data and send it back.

//Decrypt the symmetric key and IV.
SymmetricKey = RSA.Decrypt( EncryptedSymmetricKey, false);
SymmetricIV = RSA.Decrypt( EncryptedSymmetricIV , false);

参照

概念

暗号化と復号化のためのキーの生成

データの暗号化

その他の技術情報

暗号タスク

暗号サービス