2
1

More than 3 years have passed since last update.

ログインしている自分or自OS(Windows資格情報)でのみ暗号化・復号できる・・・ProtectedDataクラス(.NET標準提供)

Last updated at Posted at 2021-06-02

この記事で知れること

ログインしている Windows ユーザーまたはコンピューターの資格情報を用いて暗号化・復号する
System.Security.Cryptography.ProtectedData クラスという存在、および使用法がわかると思います。

環境

.NET Framework 2.0以降 (古くからあるのですね)、.NET Core 1.0以降(Windowsのみ)
要参照設定 : System.Security.dll

Visual Studio 2019 (16.9.4) で実験しました

説明

Microsoft Docs の説明

このクラスは、Windows オペレーティングシステムで使用可能なデータ保護 API ( DPAPI ) へのアクセスを提供します。 これはオペレーティングシステムによって提供されるサービスであり、追加のライブラリは必要ありません。 ユーザーまたはコンピューターの資格情報を使用してデータを暗号化または復号化することにより、保護を提供します。

主たるメソッドは、静的な ProtectUnprotect の2つのみ、というシンプルな構成。

実験

サンプルコード

.NET Framework コンソールアプリケーションで作成してみました。
ProtectedData クラスは Byte 配列を扱いますが、わかりやすくするために文字列を扱います。

※アセンブリ System.Security の参照追加が必要です。
image.png

Program.cs
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var protectionScope = System.Security.Cryptography.DataProtectionScope.LocalMachine; // or CurrentUser;
            var salt = System.Text.Encoding.UTF8.GetBytes("AnyText"); // バイト配列になればなんでもOK

            while (true)
            {
                Console.Write("Original Text (Empty to exit): ");
                var originalText = Console.ReadLine();  // オリジナル文字列受付(空文字でループ終了)
                if (string.IsNullOrEmpty(originalText))
                    break;
                Console.WriteLine();

                // UTF8エンコード->暗号化->BASE64化
                var utf8OriginalTextBytes = System.Text.Encoding.UTF8.GetBytes(originalText);
                var encryptedUtf8OriginalTextBytes = System.Security.Cryptography.ProtectedData.Protect(utf8OriginalTextBytes, salt, protectionScope); // <-- Protect
                var encryptedUtf8OriginalTextBytesAsBase64Encoding = System.Convert.ToBase64String(encryptedUtf8OriginalTextBytes);
                Console.WriteLine($"Encryped Text : {encryptedUtf8OriginalTextBytesAsBase64Encoding}");
                Console.WriteLine();

                // BASE64からByte[]に復元->復号->UTF8デコード
                var encryptedUtf8TextBytes = System.Convert.FromBase64String(encryptedUtf8OriginalTextBytesAsBase64Encoding);
                var decryptedUtf8TextBytes = System.Security.Cryptography.ProtectedData.Unprotect(encryptedUtf8TextBytes, salt, protectionScope); // <-- Unprotect
                var decryptedText = System.Text.Encoding.UTF8.GetString(decryptedUtf8TextBytes);

                Console.WriteLine($"Decryped Text : {decryptedText}");
                Console.WriteLine();
            }

            Console.Write("Push any key");
            Console.ReadKey();
        }
    }
}

実行結果

コンピューター1

image.png

ユーザーA on コンピューター1

image.png

ユーザーB on コンピューター1

image.png

とにかく、もとの文字列に比べてめちゃくちゃ長い。
同じコンピューター上での実行であるためか、はじめのほうのフレーズ(データ)が共通しています。しかし解析は困難でしょう。

OS管理のアカウントと紐ついているので、デジタル証明書のように秘密鍵を第三者に盗まれて復号される心配もなし。
仮にこのデータ(文字列)を共有ファイルサーバー内に保存しても、他のユーザー or コンピューターには解読できない(超困難な)仕様です。
ローカルでのパスワードの安全な保存はもとより、共有ファイルサーバーをクラウドストレージの「個人用Vault」のようにも使えますね。

-- 以上です [記事作成時間 約1:30] --

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1