문자열을 SecureString으로 변환


답변:


137

당신은하지 않습니다. 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');

13
"그 조합은 12345... 그건 바보가 짐에 가지고있는 그런 것!"
Kolob Canyon

8
내가 보는 건*****
Ian Boyd

AppendChar런타임까지 실행되지 않으므로 해당 문자는 여전히 IL에서 읽을 수 있습니다. 맞습니까? 컴파일 타임 난독 화도 도움이 될 수 있습니다. 즉, 암호를 하드 코딩하는 경우입니다.
samis

5
그것은 절름발이 주장입니다. 암호는 어디에서 얻습니까? 양식 또는 명령 줄에서. 장치 또는 명령 줄 인수에서 직접 보안 문자열을 읽는 메서드를 만들 때까지 문자열을 SecureString으로 변환해야합니다.
Quarkly

1
@DonaldAirey 당신은 비밀 관리자로부터 암호를 얻습니다. 일반적으로 여기서 말하는 비밀은 사용자 암호가 아니라 잠재적으로 권한 상승 또는 데이터 유출로 이어질 수있는 것입니다. 즉, 암호는 다른 서비스 용이며 명령 줄이나 네트워크 채널을 통해 일반으로 전달해서는 안됩니다.
Barry Kelly

160

SecureString와 사이를 변환하는 또 다른 방법이 있습니다 String.

1. 문자열을 SecureString으로

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

2. SecureString에서 문자열로

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

여기에 링크가 있습니다


4
이것은 가장 일반적인 사용 사례에 대한 최고의 솔루션입니다!
Dan Bechard 2017

16
SecureString코드 string에서 보안하려는 값을 가진 객체를 만드는 경우 를 사용하는 것은 의미가 없습니다 . 목표는 SecureString관리되는 메모리에 문자열이 포함되지 않도록하는 것이므로 해당 메모리를 검사하는 공격자가 숨기려는 값을 찾을 수 있습니다. 때문에 NetworkCredential당신이 호출하는 생성자는 ... 물론을 갈 수있는 방법은 아니다 문자열을, 필요, 코드는에와 SecureString 변환하는 쉬운 방법이지만, 그것을 사용하는 간단한을 사용하는 등 안전뿐만 코드를 만든다string
지안 파올로

15
@GianPaolo는 이론상 옳지 만 실제로는 SecureString일부 라이브러리로 작업 할 때 여전히 사용해야합니다 . 솔직히 누군가가 애플리케이션의 메모리를 적극적으로 스캔하고 있다면 이미 잃어버린 것입니다. 내가 본 적이없는 SecureString을 올바르게 사용하더라도 추출 할 다른 귀중한 데이터가있을 것입니다.
Jonathan Allen

1
@JonathanAllen : 아마도 당신 말이 맞을 것입니다.하지만 우리가 보안을 사후 고려하는 문화를 가지고 있기 때문입니다. 레시피 웹 사이트를 만드는 경우 북한은 프로그램의 메모리를 스캔하려고하지 않을 것입니다. 은행 소프트웨어를 작성하는 경우 위협은 훨씬 더 현실적입니다.
Eric J.

58

아래 방법은 문자열을 보안 문자열로 변환하는 데 도움이됩니다.

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;
}

26
하지만 암호를 문자열 매개 변수로 전달하면 관리되는 메모리에 암호화되지 않은 문자열 인스턴스가 생성되고 처음부터 'SecureString'의 목적이 무효화됩니다. 이 코드를 사용하는 미래의 사람들을 위해 이것을 지적하십시오.
Cody

19
@Cody 사실이고 좋은 지적이지만 우리 중 많은 사람들은 SecureString이 안전한지 여부에 신경 쓰지 않고 일부 Microsoft API가 매개 변수로 필요하기 때문에 사용하고 있습니다.
댄 Bechard

3
@Cody SecureString 클래스조차도 문자열을 암호화 할 수 없다는 것이 밝혀졌습니다. 이것이 MS가 github.com/dotnet/platform-compat/blob/master/docs/DE0001.md 유형의 폐기를 고려하는 이유 입니다.
Martin Brown

19

다음을 따를 수 있습니다.

string password = "test";
SecureString sec_pass = new SecureString();
Array.ForEach(password.ToArray(), sec_pass.AppendChar);
sec_pass.MakeReadOnly();

11

다음은 저렴한 linq 트릭입니다.

            SecureString sec = new SecureString();
            string pwd = "abc123"; /* Not Secure! */
            pwd.ToCharArray().ToList().ForEach(sec.AppendChar);
            /* and now : seal the deal */
            sec.MakeReadOnly();

32
이 답변은 운동이 일반 텍스트의 많은 임시 복사본을 한 번에 생성 할 수있는 방법을보고입니다
마이크 카론

1
@ john-dagg가 제안했듯이 암호로 문자열을 설정하지 않는 것이 좋습니다. 그렇게하면 보안 문자열을 사용하는 이점이 없기 때문입니다. 귀하의 경우 암호를 일반 텍스트로 입력하면 나중에 보안 문자열을 사용하여 아무것도 보호하지 않습니다. 보안 문자열이 디스 어셈블리 또는 디버거를 보는 사람들로부터 문자열을 보호하기위한 것임을 이해하기를 바랍니다. 따라서 IL / 메모리의 내용을 확인하십시오.
user734028

8

나는 이것을 밖으로 버릴 것이다. 왜?

모든 문자열을 보안 문자열로 변경할 수 없으며 갑자기 애플리케이션이 "보안"됩니다. 보안 문자열은 문자열을 가능한 한 오랫동안 암호화하고 매우 짧은 시간 동안 만 해독하여 작업이 수행 된 후 메모리를 지우도록 설계되었습니다.

응용 프로그램 문자열 보안에 대해 걱정하기 전에 처리해야 할 몇 가지 디자인 수준 문제가있을 수 있습니다. 귀하가하려는 작업에 대한 추가 정보를 제공해 주시면 더 나은 도움을 드릴 수 있습니다.


1
난 그냥 ... 나를 위해 일한 .. ProcessStartInfo를 위해 설정 암호를 사용하여 다른 사용자로 내 EXE 파일을 실행하려면
Developer404

4
내 애플리케이션은 보안 시스템에서 실행하여 보안을 유지합니다. 이 특정 문자열이 메모리에서 암호화되는 것에 대해 덜 신경 쓸 수 없습니다. 이 시스템에는 손상 될 경우 걱정해야 할 훨씬 더 중요한 정보가 있습니다. SecureString은 내 프로그램이 활용해야하는 Microsoft API에 필요합니다. 개발자가 자신의 사용 사례를 고려하고 문자열을 SecureString으로 변환하는 것이 컨텍스트에서 유효한 작업인지 여부를 결정한다는 것을 암시합니다.
Dan Bechard 2017

따라서이 방법은 DotPeek와 같은 디 컴파일러를 사용하는 경우 누군가가 암호를 보는 것을 막지 못합니까? 이 경우 문자열을 숨기는 방법이 있습니까?
M.Parent

물리 치려는 위협에 따라 몇 가지 방법이 있습니다. 로컬 관리자가 아닌 다른 사람으로부터 사용자 정보를 보호하려는 경우 Windows에서 DPAPI 메서드를 사용하여 파일을 암호화하고 여기에 비밀을 저장하고 보안 문자열로 읽어서 버릴 수 있습니다. 회사 비밀을위한 것이라면 애플리케이션이 암호를 해독 할 수 있는지, 결국 사용자도 암호를 해독 할 수 있는지 짧은 대답이됩니다.
Spence

6
unsafe 
{
    fixed(char* psz = password)
        return new SecureString(psz, password.Length);
}

5

모든 문자를 손으로 추가하지 않고 평범하고 간단합니다.

var str = "foo";
var sc = new SecureString();
foreach(char c in str) sc.appendChar(c);

심지어 애호가, 변수를 정의 할 필요가 없습니다
bigworld12

여기에 하나의 라이너입니다 :var sc = new SecureString(); foreach(char c in "foo") sc.appendChar(c);
bigworld12

4

Spence (+1)에 동의하지만 학습 또는 테스트 목적으로 수행하는 경우 문자열에 foreach를 사용하여 AppendChar 메서드를 사용하여 각 문자를 보안 문자열에 추가 할 수 있습니다.


3

저는 모든 사람들에게 "그게 요점이 아닙니다"라고 말하고 싶습니다. SecureString이 질문을하는 많은 사람들이 어떤 이유에서든 정당화 되든 그렇지 않든간에 특별히 걱정 하지 않는 응용 프로그램에있을 수 있습니다. 비밀번호의 임시 사본은 GC 가능 문자열로 힙에 있지만 , 비밀번호가 힙에 있는지 여부 승인 하는 API를 사용해야합니다. 내부 용일 수도 있고 비밀번호가 필요하기 때문에 거기에만 있습니다. 기본 네트워크 프로토콜에 의해 암호가 저장된 문자열은 예를 들어 원격 PowerShell Runspace를 설정하는 데 사용할 수 없다는 것을 알았습니다.하지만이를 생성하는 데 쉽고 간단한 한 줄은 없습니다.SecureString 객체 합니다. 그래서 당신은 당신이 신경 쓰지 않는 앱을 ​​가지고 있습니다.SecureString 필요한 것을 . 사소한 불편 함이지만 실제로 필요한 응용 프로그램이 작성자 나 중개자 를 사용하도록 유혹 하지 않도록하는 것이 그만한 가치가 있습니다 . :-)SecureStringSystem.StringSystem.Char[]


2

당신이 변환을 압축하려는 경우 stringA를 SecureStringLINQ문은 다음과 같이 당신은 그것을 표현할 수있다 :

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해도이 솔루션의 보안이 향상되지는 않습니다. 에서 로의 변환과 동일한 결함 stringSecureString있습니다. 원본 string이 메모리에 남아있는 한 데이터는 취약합니다.

즉, 위의 명령문이 제공 할 수있는 것은를 생성 SecureString하고 데이터로 초기화하고 마지막으로 수정하지 못하도록 잠그는 것입니다.


2

다음 2 개의 확장이 트릭을 수행해야합니다.

  1. A에 대한 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;
    }

추천 해 주신 John Dagg 에게 감사드립니다 AppendChar.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.