2012-04-17 5 views
2

私たちはユーザーのログオンプロファイルを保持するクラスを持っています。これは単にディスクにシリアライズする単純なクラスです。シリアライゼーションプロセスを暗号化、圧縮などできることは間違いありませんが、私は他の理由でシンプルにしたいと思います。XMLシリアル化を使用する際に機密値(パスワード)を保護しますか?

シリアライズされるアイテムの1つがパスワード(文字列)プロパティです。私はそれがシリアル化されている気にしませんが、シリアル化された値を3DES暗号化して、誰かがファイルを開いた場合にパスワードを侵害しないようにします。私は単純に暗号化された値としてパスワードの値を設定し、暗号化された値を取得することができますが、私はそれを少し自動化したいので、GET'erが復号化を処理するときにSET'erが暗号化を処理するシームレス。

あなたはこれについて最善の方法を提案していますか?私が考えているのは、シリアライザによって無視される "Password"プロパティをマークする必要があり、それは暗号化された値を保持する別のプロパティへのパスなので、それを復号化して返します。これは、これを処理するための最善の方法ですか?ちょうど私がシリアル化されたクラスロジック内で暗号化/復号化を維持するためにこれを行うことができる唯一の方法でこれをコーディングする前に、より単純な方法があるかどうかを見たいと思っています。

ありがとうございました。あなたがシリアライズされるラッパープロパティのシリアル化と使用種類によって無視されるように、パスワードのプロパティをマークすることができ

+1

サイドノート:なぜパスワード自体を保存したいですか?あなたは塩とハッシュを作り、それらを代わりに保管することはできませんか?それらをもちろん暗号化することは、おそらく良いアイデアです... – Jeroen

+2

パスワードがすでにハッシュされていないのはなぜですか?暗号化されたプレーンテキストのパスワードを使用していないと教えてください。 – Stephen

+0

@Jeroen塩漬けされたパスワードハッシュを暗号化するのはどうしてですか?全体のポイントは、あなたがそれを塩にしてひどいハッシュアルゴリズムを使用しない限り、誰かがそれを受け取った場合、それほど気にしないことです。 – Servy

答えて

10

public class LogonInfo 
{ 
    [XmlIgnore] 
    public string Password { get; set; } 

    public string EncPassword { 
    { 
     get 
     { 
      return Encrypt(Password); 
     } 
     set 
     { 
      Password = Decrypt(value); 
     } 
    } 

    // TODO: add Encrypt and Decrypt methods 
} 
+0

これはうまくいきません、それは私が考えていたのと同じコンセプトです、私はそれがこのサンプルで正しくコード化されているとは思わない。 – Neal

+0

Getters/setterのコードはXmlIgnoreプロパティ "Password"にあるべきで、GETのEncPasswordを復号化し、SETの値を暗号化します。あなたがコードを編集した場合は、それを答えとしてマークします。触れられるだけです。ありがとう。 – Neal

+1

それは責任の反転で何も変えないだろうか?それについてはわかりませんが、コードは正しいと感じています。ユニットテストの時間;) – MatthiasG

1

私はあなたが好きな方法で使用して、パスワードのハッシュ値を格納します、例えばMD5。どの時点でも、メモリまたはディスクには実際のパスワードが格納されています。次に、認証するには、入力した平文のパスワードを取り、再度ハッシュし、格納されているハッシュに対してチェックします。そのようにしても、認証は引き続き実行されますが、初期エントリ以外の時点では、パスワードのクリアテキストが利用可能です。最初のエントリ中、パスワードは攻撃の脆弱性があります。データを受信して​​比較するためにハッシュする間にメモリに格納されていなければなりません。この時間が非常に短いので、攻撃は起こりそうもありませんが、可能です。

プログラムのこの段階では、ハッシュする前にパスワードを保存するのに、SecureStringが適しています。これにより、ハッシュする前にパスワードの自動暗号化が行われ、オブジェクトがメモリからいつ削除されるかを指定することができます。

サードパーティがハッシュを取得した場合、正しいアロジリティムでは元に戻すことができないため、ハッシュを取得することは無意味です。また、プログラムがハッシュを使用してログインしようとすると、プログラムは再びハッシュし、チェックに失敗します。余分な編集的であるためには、ファイル全体を常に暗号化することもできます!

これはローカルで起こっていること、またはネットワーク接続が暗号化されていると想定しています(例:https)。上記のコメントに従って、決してネットワーク上で平文パスワードを送信しないでください。

+1

パスワードはある時点でメモリになければなりません。それ以外の場合、ハッシュをどのように計算しますか? – phoog

+0

真実ですが、瞬間的です。私はもっ​​とはっきりしていたはずです。私はあなたのプログラムが実行されていて、ファイルがメモリに直列化解除されている間に、平文パスワードが保存されていないことを意味しました。これをチェックすると、ハッシュする前に一時的に利用可能になりますが、短時間のウィンドウはうまくいくはずです。混乱のためのお詫び – Venatu

+0

他にも言及しているように、ネットワーク上にクリアテキストパスワードを送信しないでください。私はあなたのプログラムに暗号化されていないパスワードを入力しているように、暗号化されたデータストリームを使用していると仮定しています – Venatu

1

ExtendedXmlSerializerを使用できます。あなたが暗号化される必要があるプロパティを持つクラスを持っている場合は :

public class Person 
{ 
    public string Name { get; set; } 
    public string Password { get; set; } 
} 

あなたは、インタフェースIPropertyEncryptionを実装する必要があります。たとえば、Base64エンコーディングが表示されますが、現実世界では、より安全なものを使用する方が良いと考えられます。 RSA。:あなたはプロパティを暗号化するかを指定する必要がPersonクラスの構成では

public class Base64PropertyEncryption : IPropertyEncryption 
{ 
    public string Encrypt(string value) 
    { 
     return Convert.ToBase64String(Encoding.UTF8.GetBytes(value)); 
    } 

    public string Decrypt(string value) 
    { 
     return Encoding.UTF8.GetString(Convert.FromBase64String(value)); 
    } 
} 

public class PersonConfig : ExtendedXmlSerializerConfig<Person> 
{ 
    public PersonConfig() 
    { 
     Encrypt(p => p.Password); 
    } 
} 

その後、あなたはあなたのPersonConfigクラスとIPropertyEncryptionの実装を登録する必要があります。マニュアルには、Autofacを使用した設定が記載されています。シンプルな構成があります:

var toolsFactory = new SimpleSerializationToolsFactory(); 

// Register your config class 
toolsFactory.Configurations.Add(new PersonConfig()); 

// If you want to use property encryption you must register your implementation of IPropertyEncryption, e.g.: 
toolsFactory.EncryptionAlgorithm = new Base64PropertyEncryption(); 

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer(toolsFactory); 

次にあなたがオブジェクトをシリアル化することができます

var obj = new Person {Name = "John", Password = "Ab238ds2"}; 
var xml = serializer.Serialize(obj); 

あなたのXMLは次のようになります。

<?xml version="1.0" encoding="utf-8"?> 
<Person type="ExtendedXmlSerialization.Samples.Encrypt.Person"> 
    <Name>John</Name> 
    <Password>QWIyMzhkczI=</Password> 
</Person> 

ExtendedXmlSerializerは、他の多くの便利な機能を備えています。

  • 標準から非直列化xmlプロパティインタフェース
  • シリアライズ循環参照と参照してXmlSerializerを
  • シリアライゼーションクラスID
  • XML
  • プロパティの暗号化の古いバージョン
  • カスタム・シリアライザ

ExtendedXmlSerializerのデシリアライズは、.NET 4.5をサポートしています。ネットコア。 WebApiとAspCoreを統合することができます。

関連する問題