秘密鍵をローカルに暗号化して保存する方法[C# Windows]
C#+ローカル環境にて、暗号化する際のメモを示しています。
はじめに
C#でアプリケーションを作成する際、ユーザーの機密情報(ログイン情報、APIキーなど)を保存する必要がある場合がある。
この際、機密情報を平文でローカルに保存してしまうと、
ローカルファイルがハッキングされたり、ア
プリケーションをインストールしたPCが売却されたりした際に、機密情報が流出してしまう恐れがある。
そのため、ローカルに機密データを保存する場合には、暗号化が適切である。
しかし、アプリケーションにて暗号化を行う場合、機密情報を暗号化しても、その暗号化キーをローカルに保存しなければならない。
そのため、暗号化キー自体の保護が必要となる。
さらに、そのキーをどうやって安全に管理するかという問題も発生する。このように、そもそもマスターキーをどのように暗号化し、安全に管理するかという課題に直面する。
本記事では、DPAPI(Data Protection API)を用いた暗号化について自分のメモがてら簡単に解説する。
DPAPIとは?
DPAPI(Data Protection API)は、Windowsオペレーティングシステムに組み込まれているデータ保護機能。
主に、ユーザーやシステムのコンテキストに基づいてデータの暗号化および復号化を行うために使用される。このAPIを利用することで、開発者は暗号化システムを独自で実装することなく手軽にAPIにて暗号化することができる。またDPAPIはWindowsにプリインストールされているため、ローカル環境においても実行できる。
DPAPIの背景と特徴
なぜDPAPIが生まれたか
DPAPIが生まれた背景には、機密情報の安全な管理が困難であるという課題があった。従来、アプリケーションは独自に暗号化メカニズムを実装し、暗号化キーの生成、管理、保護を行わなければならなかった。このプロセスは複雑であり、セキュリティ上のリスクを伴う。
特に、暗号化キーの管理が不適切であると、暗号化そのものが無意味になり、機密情報が簡単に漏洩する可能性があった。しかし、暗号化キーの運用については、キーの管理が困難な試みであり、最大の問題は、どうやって復号鍵を安全に格納するかということであった。
このような問題を解決するために、MicrosoftはDPAPIを提供している。DPAPIはユーザーのログオン機密、あるいはシステム暗号化に関してシステムのドメイン認証機密から対称鍵を生成し、ソフトウェア開発者に暗号化手順を提供する。(一部Wikipediaより)
DPAPIの特徴
ユーザー固有の保護:
DPAPIはユーザーのプロファイルに基づいてデータを保護するため、同じコンピュータ上の他のユーザーからのアクセスを防ぐことができる。この機能により、機密情報の漏洩リスクが大幅に低減される。システムレベルの保護:
システム全体で共有されるデータの保護も可能であり、システムアカウントに関連付けられた暗号化キーを使用することで、特定のアプリケーションやサービスにのみアクセスを許可することができる。簡便なキー管理:
DPAPIを利用することで、開発者は暗号化キーの生成や管理に煩わされることなく、安全な暗号化を実現できる。これにより、開発コストやメンテナンスの負担が軽減される。
DPAPIの実装
暗号化
using System;
using System.Text;
using System.Security.Cryptography;
public class DataProtectionExample
{
public static byte[] EncryptData(string data)
{
// 平文データをバイト配列に変換
byte[] plainTextBytes = Encoding.UTF8.GetBytes(data);
// 暗号化を実行
byte[] encryptedBytes = ProtectedData.Protect(plainTextBytes, null, DataProtectionScope.CurrentUser);
return encryptedBytes;
}
public static void Main()
{
string sensitiveData = "機密情報";
byte[] encryptedData = EncryptData(sensitiveData);
Console.WriteLine("暗号化されたデータ: " + Convert.ToBase64String(encryptedData));
}
}
このコードでは、ProtectedData.Protectメソッドを使用してデータを暗号化している。
DataProtectionScope.CurrentUserは、現在のユーザーのコンテキストに基づいてデータを保護するためのスコープ
復号化
using System;
using System.Text;
using System.Security.Cryptography;
public class DataProtectionExample
{
public static string DecryptData(byte[] encryptedData)
{
// 復号化を実行
byte[] decryptedBytes = ProtectedData.Unprotect(encryptedData, null, DataProtectionScope.CurrentUser);
// バイト配列を平文データに変換
string plainText = Encoding.UTF8.GetString(decryptedBytes);
return plainText;
}
public static void Main()
{
string sensitiveData = "機密情報";
byte[] encryptedData = EncryptData(sensitiveData);
Console.WriteLine("暗号化されたデータ: " + Convert.ToBase64String(encryptedData));
string decryptedData = DecryptData(encryptedData);
Console.WriteLine("復号化されたデータ: " + decryptedData);
}
public static byte[] EncryptData(string data)
{
byte[] plainTextBytes = Encoding.UTF8.GetBytes(data);
byte[] encryptedBytes = ProtectedData.Protect(plainTextBytes, null, DataProtectionScope.CurrentUser);
return encryptedBytes;
}
}
ProtectedData.Unprotectメソッドを使用して暗号化されたデータを復号化している。
DataProtectionScope.CurrentUserは、暗号化時と同様に、現在のユーザーのコンテキストに基づいてデータを復号化するためのスコープ。
おまけ:Windows以外での暗号化
Android: Keystore
安全な鍵管理:鍵はハードウェアで保護され、アプリケーション外からのアクセスが制限される。
鍵の使用制限:鍵は指定された用途にのみ使用できるように制限できる(例えば、暗号化専用、署名専用など)。
認証情報の保護:ユーザー認証情報(PIN、パスワード、バイオメトリクス)を用いた追加のセキュリティ層を提供する。
DPAPIとの違い
Keystoreは、主にハードウェアセキュリティモジュール(HSM)やセキュアエンクレーブを利用して鍵を保護する。一方、DPAPIはユーザーのログオン認証情報を基に鍵を保護する。
Keystoreは鍵の用途を制限できるが、DPAPIにはそのような制限機能はない。
Keystoreはモバイルデバイス向けに設計されているため、バイオメトリクスなどのユーザー認証情報を活用できる。
iOS: Keychain
データの暗号化:保存されるデータは自動的に暗号化される。
アクセスコントロール:データへのアクセスは、特定の条件(例えば、デバイスのロック解除後のみアクセス可能)に基づいて制御できる。
同期機能:iCloudを使用して、複数のデバイス間でKeychainデータを同期することができる。
DPAPIとの違い
KeychainはAppleのエコシステム全体で動作し、iCloudを使用したデータ同期が可能であるが、DPAPIにはそのような同期機能はない。
KeychainはiOSおよびmacOSで使用されるため、クロスプラットフォームのAppleデバイス間で一貫したセキュリティを提供する。一方、DPAPIはWindowsプラットフォームに限定される。
Keychainはアプリごとにデータをサンドボックス化して保護するが、DPAPIはユーザーやシステムのコンテキストに基づいてデータを保護する。
macOS: Keychain
一貫したAPI:iOSとmacOSの両方で同じAPIを使用して、Keychainにアクセスできる。
安全なデータストレージ:データは強力な暗号化アルゴリズムを使用して保護される。
便利な管理ツール:Keychain Accessアプリを使用して、ユーザーが手動でKeychainデータを管理することができる。
DPAPIとの違い
macOSのKeychainはユーザーが手動で管理できるツールを提供するが、DPAPIにはそのようなツールはない。
KeychainはiCloudを利用した同期機能を提供するが、DPAPIにはクラウド同期機能がない。