2010-03-19 1 views
3

이전 개발자가 작성한 시스템을 인계받습니다. 시스템에 관리자가 사용자 계정을 승인하면 시스템에서 암호를 해시하고 데이터베이스에 저장하기 위해 다음 방법을 사용합니다. 그것은 해킹되지 않은 암호를 사용자에게 전송합니다. 사용자가 로그인 할 때 시스템은 똑같은 방법을 사용하여 사용자가 입력 한 것을 해시하고 데이터베이스 값과 비교합니다. 데이터베이스 항목이 사용자 유치 항목과 일치하지 않을 때 몇 번 실행되었습니다. 그래서이 방법은 항상 같은 값을 해시하지 않는 것으로 보입니다. 누구든지이 해싱 방법이 신뢰할 수없고 어떻게 신뢰할 수 있는지 알고 있습니까? 감사. 절차 (즉, 완전히 결정이다), 그리고 사용되는 알고리즘의 구현이 동일 (그들이 있어야 할 임의 의사 결정을 사용하지 않는 경우해싱 패스워드가 다른 결과를 나타냄

private string HashPassword(string password) 
    { 
     string hashedPassword = string.Empty; 

     // Convert plain text into a byte array. 
     byte[] plainTextBytes = Encoding.UTF8.GetBytes(password); 

     // Allocate array, which will hold plain text and salt. 
     byte[] plainTextWithSaltBytes = 
       new byte[plainTextBytes.Length + SALT.Length]; 

     // Copy plain text bytes into resulting array. 
     for(int i = 0; i < plainTextBytes.Length; i++) 
      plainTextWithSaltBytes[i] = plainTextBytes[i]; 

     // Append salt bytes to the resulting array. 
     for(int i = 0; i < SALT.Length; i++) 
      plainTextWithSaltBytes[plainTextBytes.Length + i] = SALT[i]; 

     // Because we support multiple hashing algorithms, we must define 
     // hash object as a common (abstract) base class. We will specify the 
     // actual hashing algorithm class later during object creation. 
     HashAlgorithm hash = new SHA256Managed(); 

     // Compute hash value of our plain text with appended salt. 
     byte[] hashBytes = hash.ComputeHash(plainTextWithSaltBytes); 

     // Create array which will hold hash and original salt bytes. 
     byte[] hashWithSaltBytes = new byte[hashBytes.Length + 
              SALT.Length]; 
     // Copy hash bytes into resulting array. 
     for(int i = 0; i < hashBytes.Length; i++) 
      hashWithSaltBytes[i] = hashBytes[i]; 

     // Append salt bytes to the result. 
     for(int i = 0; i < SALT.Length; i++) 
      hashWithSaltBytes[hashBytes.Length + i] = SALT[i]; 

     // Convert result into a base64-encoded string. 
     hashedPassword = Convert.ToBase64String(hashWithSaltBytes); 

     return hashedPassword; 
    } 

답변

1

은 - SHA256는 정확히 역할을하도록되어 Base64 문자열의 경우에도 동일), 알고리즘 자체가 "값을 동일하게 해시하지 않는"경우는 거의 없습니다.

오류를 재현 할 수 없다면 (서버에서 해시 할 때 항상 해시를 생성하고 클라이언트가 해시 할 때 하나의 해시를 생성하는 값을 찾으십시오.) 값을 전송하고 올바르게 수신해야합니다. 어쩌면 클라이언트가 암호화되지 않은 비밀 번호를 얻었 을까요? 어쩌면 서버가 클라이언트로부터 손상된 데이터를 수신하고 있습니까? 어쩌면 서버 데이터베이스 자체의 데이터가 어떻게 든 변경 되었습니까? 모든 거래가 유효한지, 즉 사용자가 손상된 비밀번호를받을 수 없는지 확인하십시오.

4

이 함수는 의 소금으로 해시 처리를 수행합니다. 이것은 동일한 암호에 대해 다른 해시를 생성하고 테이블 조회를 훨씬 어렵게 만드는 기법입니다.

은 소금 값이 같을 때만입니다.

이 기술에 대한 자세한 내용은 위키 백과 http://en.wikipedia.org/wiki/Salt_%28cryptography%29을 참조하십시오. http://msdn.microsoft.com/en-us/magazine/cc164107.aspx을 인용

: 공격 속도를 느리게하기 위해

, 소금을 사용합니다. 소금은 암호를 해싱하기 전에 암호를 사용하는 방법으로 공격자의 사전 계산 사전 은 쓸모가 없습니다. 그것이 어떻게 완료되었는지 알려드립니다. 데이터베이스에 항목을 추가 할 때마다 임의의 문자열을 계산하여 소금으로 사용합니다. Alice의 암호 해시를 계산하려면 Alice의 계정에 대해 값의 소금을 찾아 앞에 붙이고 을 해시합니다. 결과 데이터베이스는 다음과 같이 같습니다 지금 밥과 프레드 같은 비밀번호를 사용하는 를 알 수있는 방법이 없습니다

<users> 
    <user name='Alice' salt='Tu72*&' password='6DB80AE7...'/> 
    <user name='Bob' salt='N5sb#X' password='096B1085...'/> 
    <user name='Fred' salt='q-V3bi' password='9118812E...'/> 
</users> 

참고. 소금 자체는 은 비밀이 아닙니다.