公開鍵暗号方法で暗号化するここでは公開鍵暗号 (非対称暗号化方式、公開キー暗号方式)により暗号化、復号化する方法を紹介します。公開鍵暗号とは、公開鍵と秘密鍵(個人鍵)の2つの鍵を使って暗号化、復号化する方法です。公開鍵方式に関して「アスキーデジタル用語辞典」では、次のように説明されています。 「暗号化専用の鍵(公開鍵)と解読専用の鍵(個人鍵)を使って、暗号化と解読を行なう形式。受信側で事前に公開鍵と個人鍵のペアを用意し、暗号文の送信側に公開鍵のほうを配布する。送信側は平文を公開鍵で暗号文に変換できるが、解読はできない。受信側は、個人鍵で平文に復元可能。公開鍵だけでは解読できないという利点がある。」 .NETでは公開キー暗号化アルゴリズムを実装するクラスとして、DSACryptoServiceProvider(DSA、通信用語の基礎知識による説明)とRSACryptoServiceProvider(RSA、通信用語の基礎知識による説明)の2つが用意されていますが、ここではRSACryptoServiceProviderを使った例のみを示します。 暗号化にはRSACryptoServiceProvider.Encryptメソッドを使用しますが、この時渡す暗号化されるデータにはサイズの制限があります。OAEPパディング、Direct Encryption、ともにサポートなしのそれぞれで暗号化されるデータの最大長の計算法が異なり、このことはヘルプ(「RSACryptoServiceProvider.Encrypt メソッド」)で説明されています。 例えばDirect Encryption(高度暗号化パックがインストールされている Microsoft Windows 2000 以降)の場合、RSACryptoServiceProvider.KeySize プロパティから取得できるキーサイズが1024ビットだとすると、暗号化されるデータの最大長は、 1024/8-11=117バイト となります。下のコードでは暗号化されるデータの最大長のチェックは全く行っていませんので、ご注意ください。 次に示すサンプルは、公開鍵暗号により文字列を暗号化、復号化するため3つの静的メソッドからなります。まずCreateKeysメソッドで公開鍵と秘密鍵のペアを作成し、その公開鍵を使ってEncryptメソッドにより暗号化します。復号化は秘密鍵を指定してDecryptメソッドにより行います。 [VB.NET] ''' <summary> ''' 公開鍵と秘密鍵を作成して返す ''' </summary> ''' <param name="publicKey">作成された公開鍵(XML形式)</param> ''' <param name="privateKey">作成された秘密鍵(XML形式)</param> Public Shared Sub CreateKeys(ByRef publicKey As String, _ ByRef privateKey As String) 'RSACryptoServiceProviderオブジェクトの作成 Dim rsa As New _ System.Security.Cryptography.RSACryptoServiceProvider() '公開鍵をXML形式で取得 publicKey = rsa.ToXmlString(False) '秘密鍵をXML形式で取得 privateKey = rsa.ToXmlString(True) End Sub ''' <summary> ''' 公開鍵を使って文字列を暗号化する ''' </summary> ''' <param name="str">暗号化する文字列</param> ''' <param name="publicKey">暗号化に使用する公開鍵(XML形式)</param> ''' <returns>暗号化された文字列</returns> Public Shared Function Encrypt(ByVal str As String, _ ByVal publicKey As String) As String 'RSACryptoServiceProviderオブジェクトの作成 Dim rsa As New _ System.Security.Cryptography.RSACryptoServiceProvider() '公開鍵を指定 rsa.FromXmlString(publicKey) '暗号化する文字列をバイト配列に Dim data As Byte() = System.Text.Encoding.UTF8.GetBytes(str) '暗号化する '(XP以降の場合のみ2項目にTrueを指定し、OAEPパディングを使用できる) Dim encryptedData As Byte() = rsa.Encrypt(data, False) 'Base64で結果を文字列に変換 Return System.Convert.ToBase64String(encryptedData) End Function ''' <summary> ''' 秘密鍵を使って文字列を復号化する ''' </summary> ''' <param name="str">Encryptメソッドにより暗号化された文字列</param> ''' <param name="privateKey">復号化に必要な秘密鍵(XML形式)</param> ''' <returns>復号化された文字列</returns> Public Shared Function Decrypt(ByVal str As String, _ ByVal privateKey As String) As String 'RSACryptoServiceProviderオブジェクトの作成 Dim rsa As New _ System.Security.Cryptography.RSACryptoServiceProvider() '秘密鍵を指定 rsa.FromXmlString(privateKey) '復号化する文字列をバイト配列に Dim data As Byte() = System.Convert.FromBase64String(str) '復号化する Dim decryptedData As Byte() = rsa.Decrypt(data, False) '結果を文字列に変換 Return System.Text.Encoding.UTF8.GetString(decryptedData) End Function [C#] /// <summary> /// 公開鍵と秘密鍵を作成して返す /// </summary> /// <param name="publicKey">作成された公開鍵(XML形式)</param> /// <param name="privateKey">作成された秘密鍵(XML形式)</param> public static void CreateKeys(out string publicKey, out string privateKey) { //RSACryptoServiceProviderオブジェクトの作成 System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); //公開鍵をXML形式で取得 publicKey = rsa.ToXmlString(false); //秘密鍵をXML形式で取得 privateKey = rsa.ToXmlString(true); } /// <summary> /// 公開鍵を使って文字列を暗号化する /// </summary> /// <param name="str">暗号化する文字列</param> /// <param name="publicKey">暗号化に使用する公開鍵(XML形式)</param> /// <returns>暗号化された文字列</returns> public static string Encrypt(string str, string publicKey) { //RSACryptoServiceProviderオブジェクトの作成 System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); //公開鍵を指定 rsa.FromXmlString(publicKey); //暗号化する文字列をバイト配列に byte[] data = System.Text.Encoding.UTF8.GetBytes(str); //暗号化する //(XP以降の場合のみ2項目にTrueを指定し、OAEPパディングを使用できる) byte[] encryptedData = rsa.Encrypt(data, false); //Base64で結果を文字列に変換 return System.Convert.ToBase64String(encryptedData); } /// <summary> /// 秘密鍵を使って文字列を復号化する /// </summary> /// <param name="str">Encryptメソッドにより暗号化された文字列</param> /// <param name="privateKey">復号化に必要な秘密鍵(XML形式)</param> /// <returns>復号化された文字列</returns> public static string Decrypt(string str, string privateKey) { //RSACryptoServiceProviderオブジェクトの作成 System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); //秘密鍵を指定 rsa.FromXmlString(privateKey); //復号化する文字列をバイト配列に byte[] data = System.Convert.FromBase64String(str); //復号化する byte[] decryptedData = rsa.Decrypt(data, false); //結果を文字列に変換 return System.Text.Encoding.UTF8.GetString(decryptedData); } 注意:「マイクロソフト サポート技術情報 - 322371」によると、Web Service、ASP Page、COM+の場合は、上記コードの「RSACryptoServiceProviderオブジェクトの作成」の部分でエラーが発生することがあります。そのような場合は、この部分を以下のようにしてください。 [VB.NET] 'RSACryptoServiceProviderオブジェクトの作成 '(Web Service,ASP Page,COM+の時は次のようにUseMachineKeyStoreを指定する) Dim CSPParam As New System.Security.Cryptography.CspParameters CSPParam.Flags = _ System.Security.Cryptography.CspProviderFlags.UseMachineKeyStore Dim rsa As New _ System.Security.Cryptography.RSACryptoServiceProvider(CSPParam) [C#] //RSACryptoServiceProviderオブジェクトの作成 //(Web Service,ASP Page,COM+の時は次のようにUseMachineKeyStoreを指定する) System.Security.Cryptography.CspParameters CSPParam = new System.Security.Cryptography.CspParameters(); CSPParam.Flags = System.Security.Cryptography.CspProviderFlags.UseMachineKeyStore; System.Security.Cryptography.RSACryptoServiceProvider rsa = new System.Security.Cryptography.RSACryptoServiceProvider(CSPParam);
|
|
Copyright 2002-2008 DOBON!. All rights reserved.
|