DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

DOBON.NET

文字列を暗号化する

共有キー暗号方式により文字列(String型データ)を暗号化し、文字列として取得する方法を紹介します。

方法は「ファイルを暗号化する」と同じですが、「ファイルを暗号化する」ではファイルから読み込んだデータを暗号化し、ファイルに書き込んでいるため、CryptoStreamオブジェクトを作成する際に、暗号化の対象とするストリームとしてFileStreamオブジェクトを指定していましたが、ここではMemoryStreamオブジェクトを指定することにします。

[VB.NET]
''' <summary>
''' 文字列を暗号化する
''' </summary>
''' <param name="str">暗号化する文字列</param>
''' <param name="key">パスワード</param>
''' <returns>暗号化された文字列</returns>
Public Shared Function EncryptString(ByVal str As String, _
                                ByVal key As String) As String
    '文字列をバイト型配列にする
    Dim bytesIn As Byte() = System.Text.Encoding.UTF8.GetBytes(str)

    'DESCryptoServiceProviderオブジェクトの作成
    Dim des As New System.Security.Cryptography.DESCryptoServiceProvider

    '共有キーと初期化ベクタを決定
    'パスワードをバイト配列にする
    Dim bytesKey As Byte() = System.Text.Encoding.UTF8.GetBytes(key)
    '共有キーと初期化ベクタを設定
    des.Key = ResizeBytesArray(bytesKey, des.Key.Length)
    des.IV = ResizeBytesArray(bytesKey, des.IV.Length)

    '暗号化されたデータを書き出すためのMemoryStream
    Dim msOut As New System.IO.MemoryStream
    'DES暗号化オブジェクトの作成
    Dim desencrypt As System.Security.Cryptography.ICryptoTransform = _
        des.CreateEncryptor()
    '書き込むためのCryptoStreamの作成
    Dim cryptStreem As New System.Security.Cryptography.CryptoStream( _
        msOut, desencrypt, _
        System.Security.Cryptography.CryptoStreamMode.Write)
    '書き込む
    cryptStreem.Write(bytesIn, 0, bytesIn.Length)
    cryptStreem.FlushFinalBlock()
    '暗号化されたデータを取得
    Dim bytesOut As Byte() = msOut.ToArray()

    '閉じる
    cryptStreem.Close()
    msOut.Close()

    'Base64で文字列に変更して結果を返す
    Return System.Convert.ToBase64String(bytesOut)
End Function

''' <summary>
''' 暗号化された文字列を復号化する
''' </summary>
''' <param name="str">暗号化された文字列</param>
''' <param name="key">パスワード</param>
''' <returns>復号化された文字列</returns>
Public Shared Function DecryptString(ByVal str As String, _
                            ByVal key As String) As String
    'DESCryptoServiceProviderオブジェクトの作成
    Dim des As New System.Security.Cryptography.DESCryptoServiceProvider

    '共有キーと初期化ベクタを決定
    'パスワードをバイト配列にする
    Dim bytesKey As Byte() = System.Text.Encoding.UTF8.GetBytes(key)
    '共有キーと初期化ベクタを設定
    des.Key = ResizeBytesArray(bytesKey, des.Key.Length)
    des.IV = ResizeBytesArray(bytesKey, des.IV.Length)

    'Base64で文字列をバイト配列に戻す
    Dim bytesIn As Byte() = System.Convert.FromBase64String(str)
    '暗号化されたデータを読み込むためのMemoryStream
    Dim msIn As New System.IO.MemoryStream(bytesIn)
    'DES復号化オブジェクトの作成
    Dim desdecrypt As System.Security.Cryptography.ICryptoTransform = _
        des.CreateDecryptor()
    '読み込むためのCryptoStreamの作成
    Dim cryptStreem As New System.Security.Cryptography.CryptoStream( _
        msIn, desdecrypt, _
        System.Security.Cryptography.CryptoStreamMode.Read)

    '復号化されたデータを取得するためのStreamReader
    Dim srOut As New System.IO.StreamReader( _
        cryptStreem, System.Text.Encoding.UTF8)
    '復号化されたデータを取得する
    Dim result As String = srOut.ReadToEnd()

    '閉じる
    srOut.Close()
    cryptStreem.Close()
    msIn.Close()

    Return result
End Function

''' <summary>
''' 共有キー用に、バイト配列のサイズを変更する
''' </summary>
''' <param name="bytes">サイズを変更するバイト配列</param>
''' <param name="newSize">バイト配列の新しい大きさ</param>
''' <returns>サイズが変更されたバイト配列</returns>
Private Shared Function ResizeBytesArray(ByVal bytes() As Byte, _
                            ByVal newSize As Integer) As Byte()
    Dim newBytes(newSize - 1) As Byte
    If bytes.Length <= newSize Then
        Dim i As Integer
        For i = 0 To bytes.Length - 1
            newBytes(i) = bytes(i)
        Next i
    Else
        Dim pos As Integer = 0
        Dim i As Integer
        For i = 0 To bytes.Length - 1
            newBytes(pos) = newBytes(pos) Xor bytes(i)
            pos += 1
            If pos >= newBytes.Length Then
                pos = 0
            End If
        Next i
    End If
    Return newBytes
End Function
[C#]
/// <summary>
/// 文字列を暗号化する
/// </summary>
/// <param name="str">暗号化する文字列</param>
/// <param name="key">パスワード</param>
/// <returns>暗号化された文字列</returns>
public static string EncryptString(string str, string key) 
{
    //文字列をバイト型配列にする
    byte[] bytesIn = System.Text.Encoding.UTF8.GetBytes(str);

    //DESCryptoServiceProviderオブジェクトの作成
    System.Security.Cryptography.DESCryptoServiceProvider des =
        new System.Security.Cryptography.DESCryptoServiceProvider();

    //共有キーと初期化ベクタを決定
    //パスワードをバイト配列にする
    byte[] bytesKey = System.Text.Encoding.UTF8.GetBytes(key);
    //共有キーと初期化ベクタを設定
    des.Key = ResizeBytesArray(bytesKey, des.Key.Length);
    des.IV = ResizeBytesArray(bytesKey, des.IV.Length);

    //暗号化されたデータを書き出すためのMemoryStream
    System.IO.MemoryStream msOut = new System.IO.MemoryStream();
    //DES暗号化オブジェクトの作成
    System.Security.Cryptography.ICryptoTransform desencrypt =
        des.CreateEncryptor();
    //書き込むためのCryptoStreamの作成
    System.Security.Cryptography.CryptoStream cryptStreem =
        new System.Security.Cryptography.CryptoStream(msOut,
        desencrypt,
        System.Security.Cryptography.CryptoStreamMode.Write);
    //書き込む
    cryptStreem.Write(bytesIn, 0, bytesIn.Length);
    cryptStreem.FlushFinalBlock();
    //暗号化されたデータを取得
    byte[] bytesOut = msOut.ToArray();

    //閉じる
    cryptStreem.Close();
    msOut.Close();

    //Base64で文字列に変更して結果を返す
    return System.Convert.ToBase64String(bytesOut);
}

/// <summary>
/// 暗号化された文字列を復号化する
/// </summary>
/// <param name="str">暗号化された文字列</param>
/// <param name="key">パスワード</param>
/// <returns>復号化された文字列</returns>
public static string DecryptString(string str, string key) 
{
    //DESCryptoServiceProviderオブジェクトの作成
    System.Security.Cryptography.DESCryptoServiceProvider des =
        new System.Security.Cryptography.DESCryptoServiceProvider();

    //共有キーと初期化ベクタを決定
    //パスワードをバイト配列にする
    byte[] bytesKey = System.Text.Encoding.UTF8.GetBytes(key);
    //共有キーと初期化ベクタを設定
    des.Key = ResizeBytesArray(bytesKey, des.Key.Length);
    des.IV = ResizeBytesArray(bytesKey, des.IV.Length);

    //Base64で文字列をバイト配列に戻す
    byte[] bytesIn = System.Convert.FromBase64String(str);
    //暗号化されたデータを読み込むためのMemoryStream
    System.IO.MemoryStream msIn =
        new System.IO.MemoryStream(bytesIn);
    //DES復号化オブジェクトの作成
    System.Security.Cryptography.ICryptoTransform desdecrypt =
        des.CreateDecryptor();
    //読み込むためのCryptoStreamの作成
    System.Security.Cryptography.CryptoStream cryptStreem =
        new System.Security.Cryptography.CryptoStream(msIn,
        desdecrypt,
        System.Security.Cryptography.CryptoStreamMode.Read);

    //復号化されたデータを取得するためのStreamReader
    System.IO.StreamReader srOut =
        new System.IO.StreamReader(cryptStreem, 
        System.Text.Encoding.UTF8);
    //復号化されたデータを取得する
    string result = srOut.ReadToEnd();

    //閉じる
    srOut.Close();
    cryptStreem.Close();
    msIn.Close();

    return result;
}

/// <summary>
/// 共有キー用に、バイト配列のサイズを変更する
/// </summary>
/// <param name="bytes">サイズを変更するバイト配列</param>
/// <param name="newSize">バイト配列の新しい大きさ</param>
/// <returns>サイズが変更されたバイト配列</returns>
private static byte[] ResizeBytesArray(byte[] bytes, int newSize)
{
    byte[] newBytes = new byte[newSize];
    if (bytes.Length <= newSize)
    {
        for (int i = 0; i < bytes.Length; i++)
            newBytes[i] = bytes[i];
    }
    else
    {
        int pos = 0;
        for (int i = 0; i < bytes.Length; i++)
        {
            newBytes[pos++] ^= bytes[i];
            if (pos >= newBytes.Length)
                pos = 0;
        }
    }
    return newBytes;
}
  • 履歴:
  • 2004/9/12 ResizeBytesArrayメソッドを修正。
  • 2005/3/26 ResizeBytesArrayメソッドを修正。
  • 2009/6/13 EncryptString関数内の変数の名前を変更。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。