2009-03-12 5 views
0

.Net 프레임 워크에서 기존 SecureString 형식을 확장하기 위해 안전한 문자열 유형 (SecureStringV2)을 작성하기 시작했습니다. 이 새로운 유형은 기존 유형에 대한 몇 가지 기본 기능 (동등성 검사, 비교 등)을 추가하지만 SecureString 유형이 제공하는 보안을 유지합니다. 즉, 유형 사용 후 메모리에서 모든 것이 제거됩니다. 마샬 클래스와 해시 알고리즘을 사용하여 이러한 기능을 구현할 계획입니다. 이 일을 끝내고 올바르게 끝내는 방법에 대한 조언을 주시면 감사하겠습니다. 이 아이디어를 구현 한 아이디어에 문제가있는 사람이 있습니까? 고마워요.안전한 문자열 유형 구축시 고려 사항

업데이트 : 이것은 내 핵심 아이디어가 라이브러리의 핵심 클래스와 관련하여 지금까지 나를 이끌었습니다. 한 번 둘러보고 내 생각을 알려주세요.

/// <summary> 
/// This class is extension of the SecureString Class in the .Net framework. 
/// It provides checks for equality of multiple SStringV2 instances and maintains 
/// the security provided by the SecureString Class 
/// </summary> 
public class SStringV2 : IEquatable<SStringV2> , IDisposable 
{ 
    private SecureString secureString = new SecureString(); 
    private Byte[] sStringBytes; 
    private String hash = string.Empty; 

    /// <summary> 
    /// SStringV2 constructor 
    /// </summary> 
    /// <param name="confidentialData"></param> 
    public SStringV2(ref Char[] confidentialData) 
    { 
     GCHandle charArrayHandle = GCHandle.Alloc(confidentialData, GCHandleType.Pinned); 
     // The unmanaged string splices a zero byte inbetween every two bytes 
     //and at its end doubling the total number of bytes 
     sStringBytes = new Byte[confidentialData.Length*2]; 
     try 
     { 
      for (int index = 0; index < confidentialData.Length; ++index) 
      {     
       secureString.AppendChar(confidentialData[index]); 
      } 
     } 
     finally 
     { 
      ZeroOutSequence.ZeroOutArray(ref confidentialData); 
      charArrayHandle.Free(); 
     } 
    } 

    /// <summary> 
    /// Computes the hash value of the secured string 
    /// </summary> 
    private void GenerateHash() 
    { 
     IntPtr unmanagedRef = Marshal.SecureStringToBSTR(secureString); 
     GCHandle byteArrayHandle = GCHandle.Alloc(sStringBytes, GCHandleType.Pinned); 
     Marshal.Copy(unmanagedRef, sStringBytes, 0, sStringBytes.Length); 
     SHA256Managed SHA256 = new SHA256Managed(); 

     try 
     { 
      hash = Convert.ToBase64String(SHA256.ComputeHash(this.sStringBytes)); 
     } 
     finally 
     { 
      SHA256.Clear(); 
      ZeroOutSequence.ZeroOutArray(ref sStringBytes); 
      byteArrayHandle.Free(); 
      Marshal.ZeroFreeBSTR(unmanagedRef); 
     } 
    } 

    #region IEquatable<SStringV2> Members 

    public bool Equals(SStringV2 other) 
    { 
     if ((this.hash == string.Empty) & (other.hash == string.Empty)) 
     { 
      this.GenerateHash(); 
      other.GenerateHash(); 
     } 
     else if ((this.hash == string.Empty) & !(other.hash == string.Empty)) 
     { 
      this.GenerateHash(); 
     } 
     else if (!(this.hash == string.Empty) & (other.hash == string.Empty)) 
     { 
      other.GenerateHash(); 
     } 

     if (this.hash.Equals(other.hash)) 
     { 
      return true; 
     } 
      return false; 
    } 

    #endregion 

    #region IDisposable Members 

    public void Dispose() 
    { 
     secureString.Dispose(); 
     hash = string.Empty; 
     GC.SuppressFinalize(this); 
    } 

    #endregion 
} 

} 당신이 securestring의 혜택을 상실하기 시작에서 당신이 문자 [] 배열을 전달하는 경우

+0

비교 방법에 '&'를 하나만 사용하고 있습니다. 그것들은 '&&'이어야합니다. – Doug

답변

0

. char [] 배열은 가비지 수집기가 메모리에서 제거하기 전에 복사 할 수 있습니다.

+0

사실, 전달한 직후 char [] 배열을 고정하면 문제가 해결됩니다. 적어도 내부적으로는 어느 정도 믿을 수 있습니다. 이 작업을 수행해야합니다 : GCHandle.Alloc (confidentialData, GCHandleType.Pinned); – gogole

+1

아직 잘못되었습니다. Append와 같은 방법 만 사용해야합니다. 나는 실제로 안전띠가 뱀 기름이라고 생각합니다. 나는 ss가 사용되는 경우의 99 %에서 민감한 데이터가 실수로 디스크에 기록 될 위험이 있는데, 이는 ss에 저장되기 전에 프로그램의 다른 곳에 저장되기 때문입니다. –

+0

ss에 대한 두 가지 사용 사례가 있습니다. 1) 스왑에 안전한 데이터 유출을 방지합니다. 그것은 많은주의 사항이있는 'ok'일을합니다. 2) 활성 로컬 공격자로부터 보호합니다. 이 경우 로컬 공격자가 SecureString에 추가 된 모든 문자열을 기록 할 수 있기 때문에 상황이 악화됩니다. –

1

해시 평등을 데이터 평등과 혼동하는 문제를 묻습니다. 서로 다르다는 확률은 낮지 만 한번 공격하면 악몽이 될 것입니다./(나는 "행운"을 가졌습니다. "몇 년 전에 같은 실수를 저지른 사용자 정의 해시 맵 구현을 디버그하고 수정하려면이 부분을 신뢰하십시오.

+0

이것에 대해 자세히 설명해 주시겠습니까? 필자의 관점에서 볼 때, SecureString과 Equals() 메서드가 호출 된 후 관련 값으로 초기화 된 채로 유지되는 해시 일뿐입니다. 해시가 같으면 나는 비교되는 두 인스턴스가 동등하다는 것을 안전하게 일반화 할 수 있다고 믿습니다. – gogole

+0

문제를 명확히 표시하려면 문자열 길이가 100x 이상이면 해시가 분명합니다.이 길이가 더 큰 문자열은 동일한 해시를 가져야합니다. 사용 된 해시 함수에 따라 주어진 확률로 더 짧은 문자열에 대해서도 마찬가지입니다. 경고되었습니다.) – RnR

+0

오, 알았습니다. 나는 지금 당신의 관점을 얻었을 것입니다. 나는 먹은 이래로 아무런 이유가 없다고 생각합니다. 전체 문자열 - 특정 바이트를 추출하지 않음 - 해시 함수에 따라서 두 문자열의 가장 작은 차이가 분명히 다른 해시를 생성합니다. 머리를 주셔서 감사합니다 :) – gogole

1

SecureString이 양방향 암호화를 사용한다는 사실을 잊지 마십시오. 귀하의 수업에 암호화가 표시되지 않습니다.