2017-09-05 13 views
0

保存された資格情報を使用できる特定のWindowsアプリケーションを自動化するために、Windowsの保存された資格情報を管理するためのAPI呼び出しをadvapi32.dllに呼び出して動作します。COMのマーシャリングされていないアンマネージのUnicode文字列SecureStringのメモリ

いつでもパスワードに含まれるテキストとやりとりする必要がないので、SecureStringをパスワードに使用するようにコードを更新しようとしています。そのため、アプリケーションでパスワードがプレーンテキスト。

私はAPI呼び出しに渡すCOMタスクアロケータメモリにSecureStringをマーシャリングすることができています:それは戻ってアプリケーションにその情報を読み取るに来るとき、私は方法を見つけることができない、しかし

var unmanagedPassword = Marshal.SecureStringToCoTaskMemUnicode(userCredential.Password); 

そのような管理されていない文字列をSecureStringにマーシャリングするには、文字列またはバイト配列として管理されたメモリに文字列をコピーしないでください。

これを行うための安全な方法はありますか?見落としていますか?

+0

この質問が「どうしてうまくいかないの?私は方法を見つけることができない何かをする方法を尋ねています。私は私が必要なものを明確に指定したと思う。アンマネージメモリから新しいSecureStringを作成する。 – Ashigore

+0

これは興味深い見落としです。私は、最も単純な方法(アンマネージコードなし)は、Marshal.ReadInt16()のループで '.AppendChar()'を呼び出すことです(Unicode文字列を前提としています)。 'char *'と長さをとる安全でないコンストラクタもあります。管理されていないメモリはゼロにして割り当てを解除する必要があります。そうでなければ、すべてのデータがプレーンテキストで浮動している間に 'SecureString'を使用することはあまり意味がありません。 –

+0

ありがとう@JeroenMostert、そのトリックでした! – Ashigore

答えて

0

Jeroen Mostertこのソリューションにつながるご意見は、可能な限り安全であるはずです。

Jeroenが記述しているように、各文字はshortとして読み取られ、一度に1つずつ新しいSecureStringに追加されます。

タスクアロケータメモリの管理されていない文字列はヌルで終了します。したがって、0になるまで文字を読み込みます。アンマネージバイナリ文字列はプレフィックス長であるため、以下のコードを少し修正する必要があります。

var outString = new SecureString(); 
    outString.AppendChar('p'); 
    outString.AppendChar('a'); 
    outString.AppendChar('s'); 
    outString.AppendChar('s'); 
    outString.AppendChar('w'); 
    outString.AppendChar('o'); 
    outString.AppendChar('r'); 
    outString.AppendChar('d'); 
    var ptr = Marshal.SecureStringToCoTaskMemUnicode(outString); 

    var inString = new SecureString(); 
    var i = 0; 
    short c; 

    while ((c = Marshal.ReadInt16(ptr, i)) != 0) 
    { 
     inString.AppendChar((char)c); 
     i += 2; 
    } 

    Marshal.ZeroFreeCoTaskMemUnicode(ptr); 
関連する問題