動機は何でも構わないんですが…
user.configファイルの中身が剥き出しってどうよ?
って思ってしまったのが運の尽きで…
折々に手法を凝らして工夫してきましたが、まぁ帯だったり襷だったり褌だったり。
そんな中でも、一番のお気に入りを披露しちゃおうと思います。
特徴
- プログラム本体側では通常のプロパティアクセスを行うだけでオッケー
-
.cs
ファイルを増やすだけで暗号化対応完了 -
user.config
ファイルを別ユーザ・別パソコンにコピーしても正規ファイルとは認められません - 残念ながら
string
型のプロパティにしか対応できません…
=ここが部分的
実装
Settings.Crypto.cs
using System;
using System.Security.Cryptography;
using System.Text;
namespace TestSettings.Properties {
internal sealed partial class Settings {
public override object this[string propertyName] {
get {
if(!(base[propertyName] is string)) {
return base[propertyName];
}
try {
return Decrypt(base[propertyName]);
}
catch {
return Settings.Default.Properties[propertyName].DefaultValue;
}
}
set {
if(base[propertyName] is string)
try {
base[propertyName] = Encrypt(value);
}
catch {
base[propertyName] = Settings.Default.Properties[propertyName].DefaultValue;
} else
base[propertyName] = value;
}
}
byte[] entropy = { 141, 238, 28, 197, 169, 105, 209, 230 };
object Encrypt(object text) {
return Convert.ToBase64String(ProtectedData.Protect(Encoding.UTF8.GetBytes(text as string), entropy, DataProtectionScope.CurrentUser));
}
object Decrypt(object text) {
return Encoding.UTF8.GetString(ProtectedData.Unprotect(Convert.FromBase64String(text as string), entropy, DataProtectionScope.CurrentUser));
}
}
}
-
namespace
はプロジェクトに合わせて下さい - エントロピーは適当に変えていただいて構いません
肝はSettings
クラスのインデクサをoverride
してるとこですね。で、ここで暗号化/復号化をしちゃってるので、プロパティを使う側は全く無意識でuser.config
内は暗号化されちゃっていると云う感じ。
配置方法
クラスファイルは、↓此処の位置に配置するのが宜しいかと…
(Properties
フォルダ配下)
やってみる
Program.cs
using System;
namespace TestSettings {
class Program {
static void Main(string[] args) {
Console.WriteLine(Properties.Settings.Default.TestString);
Properties.Settings.Default.TestString = "とほほ…";
Properties.Settings.Default.Save();
Console.WriteLine(Properties.Settings.Default.TestString);
Console.ReadKey();
}
}
}
ちゃんと、復号化も出来ている様で、めでたい。
心残り
- アプリケーションスコープのプロパティを事前暗号化しておきたい時には、この方式は全く馴染みません
- 暗号化には
DPAPI
を使ってるので、他のユーザとか他のパソコンにこのuser.config
を持って行ったとしても復号化には失敗する(筈)
此処の検証ができていないのが残念(単なるめんどくさがり、と云うだけですが) - 上記のケース等の様に復号化に失敗した場合は、設定画面で指定した既定値が復活するようになっています
user.config
の中身を改竄した場合も同様 -
string
以外も暗号化したい場合はどうしたらいいんだろう?
違うアプローチが必要そうなので、何かが下りてくるまで熟考したい