160

に変換する方法StringSecureString

4

14 に答える 14

218

との間で変換する別の方法もありSecureStringますString

1.文字列からSecureString

SecureString theSecureString = new NetworkCredential("", "myPass").SecurePassword;

2.SecureStringからStringへ

string theString = new NetworkCredential("", theSecureString).Password;

ここにリンクがあります

于 2017-03-29T04:51:18.190 に答える
158

あなたはそうしない。SecureStringオブジェクトを使用する理由は、文字列オブジェクト(メモリにロードされ、ガベージコレクションまでプレーンテキストで保持される)の作成を回避するためです。ただし、文字を追加することにより、SecureStringに文字を追加できます。

var s = new SecureString();
s.AppendChar('d');
s.AppendChar('u');
s.AppendChar('m');
s.AppendChar('b');
s.AppendChar('p');
s.AppendChar('a');
s.AppendChar('s');
s.AppendChar('s');
s.AppendChar('w');
s.AppendChar('d');
于 2009-10-15T05:28:23.663 に答える
70

以下のメソッドは、文字列を安全な文字列に変換するのに役立ちます

private SecureString ConvertToSecureString(string password)
{
    if (password == null)
        throw new ArgumentNullException("password");

    var securePassword = new SecureString();

    foreach (char c in password)
        securePassword.AppendChar(c);

    securePassword.MakeReadOnly();
    return securePassword;
}
于 2014-06-02T14:44:37.293 に答える
24

あなたはこれに従うことができます:

string password = "test";
SecureString sec_pass = new SecureString();
Array.ForEach(password.ToArray(), sec_pass.AppendChar);
sec_pass.MakeReadOnly();
于 2014-08-06T04:38:05.130 に答える
14

これが安価なlinqトリックです。

            SecureString sec = new SecureString();
            string pwd = "abc123"; /* Not Secure! */
            pwd.ToCharArray().ToList().ForEach(sec.AppendChar);
            /* and now : seal the deal */
            sec.MakeReadOnly();
于 2015-06-25T20:48:24.590 に答える
9

これを捨てます。なんで?

すべての文字列を安全な文字列に変更することはできず、突然アプリケーションが「安全」になります。安全な文字列は、文字列を可能な限り暗号化して保持するように設計されており、非常に短い期間だけ復号化され、操作が実行された後にメモリを消去します。

アプリケーション文字列の保護について心配する前に、設計レベルの問題に対処する必要があるかもしれないと言って危険です。あなたがやろうとしていることについてもう少し情報を教えてください。そうすれば、私たちはより良い手助けをすることができるかもしれません。

于 2009-10-15T05:25:28.773 に答える
8
unsafe 
{
    fixed(char* psz = password)
        return new SecureString(psz, password.Length);
}
于 2015-03-03T18:20:41.480 に答える
8

「それはポイントではありません」と言っているすべての人に指摘したいのですが、SecureStringこの質問をする人の多くは、正当な理由があるかどうかにかかわらず、特に心配していないアプリケーションにいる可能性がありますパスワードの一時的なコピーはGC可能な文字列としてヒープに配置されますが、オブジェクトのみを受け入れるAPIを使用する必要がありSecureStringます。だから、あなたはあなたが気にしないアプリを持っていますパスワードがヒープ上にあるかどうか、おそらく内部使用のみであり、パスワードは基盤となるネットワークプロトコルで必要とされるためにのみ存在し、パスワードが格納されている文字列を使用してリモートPowerShellを設定することはできません。ランスペース-しかし、SecureString必要なものを作成するための簡単でわかりやすいワンライナーはありません。これは小さな不便ですが、実際に必要なアプリケーションが作成者に使用や仲介を誘惑しないようにするためには、おそらく価値がありSecureStringます。:-)System.StringSystem.Char[]

于 2018-04-16T15:45:14.677 に答える
6

派手なlinqはなく、すべての文字を手作業で追加するのではなく、単純で単純です。

var str = "foo";
var sc = new SecureString();
foreach(char c in str) sc.appendChar(c);
于 2016-07-12T10:31:30.037 に答える
4

Spence(+1)に同意しますが、目的の学習またはテストのためにそれを行う場合は、文字列でforeachを使用し、AppendCharメソッドを使用して各文字をsecurestringに追加できます。

于 2009-10-15T05:29:34.637 に答える
4

次の2つの拡張機能でうまくいくはずです。

  1. charアレイの場合

    public static SecureString ToSecureString(this char[] _self)
    {
        SecureString knox = new SecureString();
        foreach (char c in _self)
        {
            knox.AppendChar(c);
        }
        return knox;
    }
    
  2. そしてのためにstring

    public static SecureString ToSecureString(this string _self)
    {
        SecureString knox = new SecureString();
        char[] chars = _self.ToCharArray();
        foreach (char c in chars)
        {
            knox.AppendChar(c);
        }
        return knox;
    }
    

推薦してくれたジョン・ダッグに感謝しAppendCharます。

于 2017-07-04T14:05:35.173 に答える
3

stringaからaSecureStringへの変換をステートメントに圧縮する場合はLINQ、次のように表現できます。

var plain  = "The quick brown fox jumps over the lazy dog";
var secure = plain
             .ToCharArray()
             .Aggregate( new SecureString()
                       , (s, c) => { s.AppendChar(c); return s; }
                       , (s)    => { s.MakeReadOnly(); return s; }
                       );

ただし、使用LINQしてもこのソリューションのセキュリティは向上しないことに注意してください。からstringへの変換と同じ欠陥がありSecureStringます。stringオリジナルがメモリに残っている限り、データは脆弱です。

そうは言っても、上記のステートメントが提供できるのは、の作成、SecureStringデータによる初期化、そして最終的には変更からのロックです。

于 2015-07-28T08:05:50.633 に答える
0

完全を期すために、char配列と文字列からSecureStringに変換し、また元に戻すための2つの単体テストとメソッドを追加しました。文字列は完全に避けて、ここで提供する方法のように、char配列へのポインタまたはchar配列自体のいずれかのみを渡すようにしてください。文字列は、管理されたメモリにプレーンテキストのデータを保持するため、かなり不確定な量であるため安全ではありません。次のGCが実行または強制されるまでの時間は、できるだけ早く文字配列をSecureStringに入れてそこに保持し、文字配列として再度読み取ることをお勧めします。

テストは次のようになります。

using NUnit.Framework;
using System;
using SecureStringExtensions;
using System.Security;

namespace SecureStringExtensions.Test
{
    [TestFixture]
    public class SecureStringExtensionsTest
    {
        [Test]
        [TestCase(new char[] { 'G', 'O', 'A', 'T', '1', '2', '3' })]
        public void CopyCharArrayToSecureStringAndCopyBackToCharArrayReturnsExpected(char[] inputChars)
        {
            SecureString sec = inputChars.ToSecureString();
            var copiedFromSec = sec.FromSecureStringToCharArray();
            CollectionAssert.AreEqual(copiedFromSec, inputChars);                
        }

        [Test]
        [TestCase("GOAT456")]
        public void CopyStringToSecureStringAndCopyBackToUnsafeStringReturnsExpected(string inputString)
        {
            SecureString sec = inputString.ToSecureString();
            var copiedFromSec = sec.FromSecureStringToUnsafeString();
            Assert.AreEqual(copiedFromSec, inputString);
        }
    }
}

そして、ここに拡張メソッドがあります:

using System;
using System.Runtime.InteropServices;
using System.Security;

namespace SecureStringExtensions
{
    public static class SecureStringExtensions
    {
        public static SecureString ToSecureString(this string str)
        {
            return ToSecureString(str.ToCharArray());
        }

        public static SecureString ToSecureString(this char[] str)
        {
            var secureString = new SecureString();
            Array.ForEach(str, secureString.AppendChar);
            return secureString;
        }

        /// <summary>
        /// Creates a managed character array from the secure string using methods in System.Runetime.InteropServices
        /// copying data into a BSTR (unmanaged binary string) and then into a managed character array which is returned from this method.
        /// Data in the unmanaged memory temporarily used are freed up before the method returns.
        /// </summary>
        /// <param name="secureString"></param>
        /// <returns></returns>
        public static char[] FromSecureStringToCharArray(this SecureString secureString)
        {
            char[] bytes;
            var ptr = IntPtr.Zero;
            try
            {
                //alloc unmanaged binary string  (BSTR) and copy contents of SecureString into this BSTR
                ptr = Marshal.SecureStringToBSTR(secureString);
                bytes = new char[secureString.Length];
                //copy to managed memory char array from unmanaged memory 
                Marshal.Copy(ptr, bytes, 0, secureString.Length);
            }
            finally
            {
                if (ptr != IntPtr.Zero)
                {
                    //free unmanaged memory
                    Marshal.ZeroFreeBSTR(ptr);
                }
            }
            return bytes;
        }

        /// <summary>
        /// Returns an unsafe string in managed memory from SecureString. 
        /// The use of this method is not recommended - use instead the <see cref="FromSecureStringToCharArray(SecureString)"/> method
        /// as that method has not got multiple copies of data in managed memory like this method.
        /// Data in unmanaged memory temporarily used are freed up before the method returns.
        /// </summary>
        /// <param name="secureString"></param>
        /// <returns></returns>
        public static string FromSecureStringToUnsafeString(this SecureString secureString)
        {
            if (secureString == null)
            {
                throw new ArgumentNullException(nameof(secureString));
            }
            var unmanagedString = IntPtr.Zero;
            try
            {
                //copy secure string into unmanaged memory
                unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
                //alloc managed string and copy contents of unmanaged string data into it
                return Marshal.PtrToStringUni(unmanagedString);
            }
            finally
            {
                    if (unmanagedString != IntPtr.Zero)
                {
                    Marshal.FreeBSTR(unmanagedString);
                }
            }
        }

    }
}

ここでは、System.Runtime.InteropServicesのメソッドを使用して、BSTR(バイナリアンマネージ文字列)を一時的に割り当て、一時的に使用されているアンマネージメモリを解放します。

于 2021-07-21T22:11:10.020 に答える
-1

この簡単なスクリプトを使用できます

private SecureString SecureStringConverter(string pass)
{
    SecureString ret = new SecureString();

    foreach (char chr in pass.ToCharArray())
        ret.AppendChar(chr);

    return ret;
}
于 2017-10-28T06:32:43.107 に答える