2009-05-15 2 views
5

이전 ASP/MySql webapp을 ASP.NET/MS SQL로 업데이트하고 있습니다..NET 또는 MS SQL을 사용하여 MySql의 암호() 암호화 시뮬레이션

새 앱에서 작동하는 이전 웹 사이트의 로그인 정보를 유지하고 싶습니다.

아쉽게도 암호는 MySql의 password() 함수를 사용하여 MySql DB에 저장되었습니다.

.NET 또는 MS SQL에서 MySql의 password() 함수를 시뮬레이션 할 수 있습니까?

도움말/링크를 부탁드립니다.

+1

어떤 MySQL 버전을 사용하고 있습니까? 어떤 버전을 사용하고 있는지 알고 있다면 이것이 가능해야합니다. MySQL은 이중 SHA1 해시 알고리즘을 사용하여 암호를 인코딩합니다. –

+0

mysql DB에 액세스 할 때이를 확인합니다. 게시 된 솔루션에 감사드립니다! –

답변

12

MySQL 설명서에 따르면 알고리즘은 이중 SHA1 해시입니다. MySQL 소스 코드를 검토 할 때 libmysql/password.c에 make_scrambled_password()라는 함수가 있습니다. 함수는 다음과 같이 정의됩니다.

/* 
    MySQL 4.1.1 password hashing: SHA conversion (see RFC 2289, 3174) twice 
    applied to the password string, and then produced octet sequence is 
    converted to hex string. 
    The result of this function is used as return value from PASSWORD() and 
    is stored in the database. 
    SYNOPSIS 
    make_scrambled_password() 
    buf  OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string 
    password IN NULL-terminated password string 
*/ 

void 
make_scrambled_password(char *to, const char *password) 
{ 
    SHA1_CONTEXT sha1_context; 
    uint8 hash_stage2[SHA1_HASH_SIZE]; 

    mysql_sha1_reset(&sha1_context); 
    /* stage 1: hash password */ 
    mysql_sha1_input(&sha1_context, (uint8 *) password, (uint) strlen(password)); 
    mysql_sha1_result(&sha1_context, (uint8 *) to); 
    /* stage 2: hash stage1 output */ 
    mysql_sha1_reset(&sha1_context); 
    mysql_sha1_input(&sha1_context, (uint8 *) to, SHA1_HASH_SIZE); 
    /* separate buffer is used to pass 'to' in octet2hex */ 
    mysql_sha1_result(&sha1_context, hash_stage2); 
    /* convert hash_stage2 to hex string */ 
    *to++= PVERSION41_CHAR; 
    octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE); 
} 

이 방법을 사용하면 기본적으로 동일한 작업을 수행하는 .NET 대응 개체를 만들 수 있습니다. 여기에 내가 생각해내는 것이있다. SELECT PASSWORD ('test')를 실행할 때; MySQL을 내 로컬 복사본에 대해, 반환되는 값은 다음과 같습니다 소스 코드 (다시 password.c의)에 따르면

*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29

, 처음 별표 (*)이이를 암호화 후 MySQL의 4.1 방법을 나타냅니다 암호. VB에서 기능을 에뮬레이트 할 때.

Public Function GenerateMySQLHash(ByVal strKey As String) As String 
    Dim keyArray As Byte() = Encoding.UTF8.GetBytes(strKey) 
    Dim enc = New SHA1Managed() 
    Dim encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)) 
    Dim myBuilder As New StringBuilder(encodedKey.Length) 

    For Each b As Byte In encodedKey 
     myBuilder.Append(b.ToString("X2")) 
    Next 

    Return "*" & myBuilder.ToString() 
End Function 

가에서는 System.Security.Cryptography 네임 스페이스에) (SHA1Managed 유의 사항 : 인터넷은 예를 들어, 내가 가지고 올 것입니다. 이 메소드는 MySQL에서 PASSWORD() 호출과 동일한 출력을 리턴합니다. 이게 당신 한테 도움이되기를 바랍니다.

편집 : 여기 VB의 그물 C 번호

public string GenerateMySQLHash(string key) 
{ 
    byte[] keyArray = Encoding.UTF8.GetBytes(key); 
    SHA1Managed enc = new SHA1Managed(); 
    byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)); 
    StringBuilder myBuilder = new StringBuilder(encodedKey.Length); 

    foreach (byte b in encodedKey) 
     myBuilder.Append(b.ToString("X2")); 

    return "*" + myBuilder.ToString(); 
} 
+0

굉장해, 고마워! 내 버전의 mysql에서 작동하는 경우 (지금은 확인할 수 없음) 알려 주시면 알려 드리겠습니다. 많은 연구와 훌륭한 솔루션에 대한 감사드립니다. –

+0

4.1.1 이전 버전을 사용하는 경우 이전 암호화 방법이 있습니다. 나는 그 방법을 쓸 수 있도록 도울 수 있습니다. 알려 주시면 기꺼이 도와 드리겠습니다. 행운을 빕니다! –

+0

실제로 T-SQL에서도이 작업을 수행 할 수있는 방법을 찾았습니다. 그것은보기 흉한 모양이지만 작동합니다! SELECT '*'+ SUBSTRING (master.dbo.fn_varbintohexstr (HASHBYTES ''SHA1 ', SHA1', 'VALUE-TO-ENCRYPT-GOES-HERE')))), 1,42) –

1

.Net에서 MD5 또는 SHA1을 사용하여 문자열을 암호화 할 수 있지만 MySQL이 사용하는 실제 알고리즘은이 두 가지 방법과 다를 수 있습니다. 나는 그것이 서버의 인스턴스에 기초한 어떤 종류의 '소금'을 기반으로한다고 생각하지만, 나는 모른다.

이론상 MySQL이 오픈 소스라고 생각하기 때문에 소스를 조사하고 이것이 어떻게 수행되는지를 결정할 수 있습니다.

http://dev.mysql.com/doc/refman/5.1/en/encryption-functions.html#function_password

편집 1 : 내가 사용하는 알고리즘이 다른 '비틀기'(this 블로그 포스트에 따르면)와 더블 SHA1 믿습니다.

+0

알아, 나도 알아 ... 그 정보도 연구 할 수 있었지만 실제로는 내 질문에 대답하지 않았다 :-) 어쨌든. –

+0

나는 소스를 보았고, SHA1을 기반으로하지만 소금과 무작위 화 기술은 다양하다고 생각합니다. 별로 도움이되지 않습니다. 그래서 대답은 다른 곳을보아야한다는 것입니다. ( – samjudson

+0

감사합니다. +1 소스를 확인하는 데 +1 : –

-3

MySql 암호() 기능을 시뮬레이트 할 수 없습니다. 적어도 많은 일과 행운이없이. MySql은 단방향 암호화 문자열에 자체 알고리즘을 사용하기 때문에 사용하는 알고리즘을 공개하지 않습니다.

내가 DB를 복제하지만, MySQL과 연결을 유지하는 것입니다 : 당신이 당신의 문제를 해결하려면, 등

을, 시행 착오를 할 결과 문자열을 비교해야 의미합니다. 플래그를 사용하여 최초 로그인을 식별하십시오. 현재 암호를 사용하도록 요청하십시오. MySql 암호() 함수로 암호를 확인하십시오. 암호가 유효한 경우; 동일한 암호를 다시 입력하거나 새 암호를 입력하여 재설정하도록 요청하십시오. 이 시점에서 당신이 좋아하는 암호화 알고리즘을 사용하여 MS SQL DB에 결과를 저장하십시오.

나는 고통 스러울 지 모르지만, MySql 암호화 알고리즘을 해독하려고 할 때 해킹하는 것이 가장 좋습니다.

행운을 빈다.

+0

감사합니다.부분적으로 솔루션을 사용하겠습니다. 첫 번째 단계에서 사용자를 MS SQL로 가져 와서 "HasMysqlPassword"비트를 "1"로 설정하십시오. 두 번째 단계로 로그인시 MS SQL 사용자 정보를 검색하고 HasMysqlPassword = 1인지 확인합니다. 그렇지 않으면 MS SQL의 "암호"필드를 확인합니다. 그렇다면, mysql에서 비밀번호를 검사 할 것이다. 일치하는 경우 SHA1을 사용하여 입력 된 암호를 암호화하고 HasMysqlPassword를 0으로 설정하면서 MS SQL에 저장합니다. 잠시 후 MySQL 데이터베이스를 분리하고 나머지 사용자에게 새 암호가 자동 생성됨을 알릴 수 있어야합니다. * –

+0

What 's 그 접근법에 대한 좋은 점은 사용자가 어떤 것을 발견하지 못한다는 것입니다. –

+0

올바르지 않습니다. NET에서 유효한 암호 해시로 변환하는 방법을 작성했습니다 ... –

0

동일한 부호에 '0'이 패드 년대 헥스 코드는 'E'[예]이면,이 기능이 올바르게 추가되도록 왼쪽 결과 문자열에 '0E'. 그래서 포함한 말의 사전 보류 '*'결과 문자열은 41 문자 길이 될 것입니다, MySQL의에서 필요로

Public Function GenerateMySQLHash(ByVal strKey As String) As String 

    Dim keyArray As Byte() = System.Text.UTF8Encoding.UTF8.GetBytes(strKey) 
    Dim enc = New Security.Cryptography.SHA1Managed() 
    Dim encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)) 
    Dim myBuilder As New System.Text.StringBuilder(encodedKey.ToString.Length) 

    For Each b As Byte In encodedKey 
     myBuilder.Append(Strings.Right("0" & b.ToString("X"), 2)) 
    Next 

    Return "*" & myBuilder.ToString() 
End Function 
1

"그들이 알고리즘은 그들이 사용하는 것을 공개하지 않을 수 있습니다"

... 일어나 그들 모두가 데이터베이스의 구조 자체를 읽을 수 있기 때문에 무언가를 "공개"할 필요가없는 ... MySQL은 오픈 소스 있음을 말해야 사람 - 그냥 소스를 다운로드 암호화 기능 검색 (그들이 C++을 사용하고있는 것 같아요) inve 시작 징벌 적 ... SHA1은 현재 매우 안전하지 않은 것처럼 보입니다 - 단지 최근 몇 명의 과학자들이 제한없이 데이터의 20 %을 선택할 수 있음을 입증했으며 은 동일한 해시을 생성하므로 AES를 사용하는 것이 좋습니다. 또는 SHA2 (그러므로이 아닌 MySQL- PASSWORD -funC)

0

MySQL의 암호 기능이 특히 안전하지 유일한 이유 (아무 소금이나 일치하는 해시를 찾고에 대한 보호의 다른 방법이 없다 예) 나는 볼 수 있습니다 알고리즘을 복제하고자하는 경우 1 : mysql password()를 사용하는 사용자의 목록/테이블이있는 경우 2 : 사용자 테이블의 해시에서 mysql 암호를 해독하려고합니다.

그 밖의 다른 것을 사용하십시오. 예를 들어, 사용자 이름 (및/또는 다른 행 불변 값)과 암호를 결합한 해시를 사용할 수 있습니다. 두 명의 사용자가 동일한 암호를 선택하면 명확하지 않습니다. 테이블이 노출되면 보안이 저하되지 않습니다 (예 : 446a12100c856ce9는 매우 인기있는 암호의 암호() 해시입니다)

1

패딩 문제를 해결하기 위해 C# 버전이 수정되었습니다.
[테스트] 공개 무효 GenerateMySQLHashX2() { 문자열 암호 = "20iva05";

 byte[] keyArray = Encoding.UTF8.GetBytes(password); 
     SHA1Managed enc = new SHA1Managed(); 
     byte[] encodedKey = enc.ComputeHash(enc.ComputeHash(keyArray)); 
     StringBuilder myBuilder = new StringBuilder(encodedKey.Length); 

     foreach (byte b in encodedKey) 
     { 
      log.Debug(b.ToString() + " -> " + b.ToString("X2")); 
      myBuilder.Append(b.ToString("X2")); 
     } 

     Assert.AreEqual("*8C2029A96507478FD1720F6B713ADD57C66EED49", "*" + myBuilder.ToString()); 
    } 
관련 문제