해시를 위해 소금을 숨길 필요성


99

직장에서 우리는 소금에 대한 두 가지 경쟁 이론을 가지고 있습니다. 내가 작업하는 제품은 사용자 이름이나 전화 번호와 같은 것을 사용하여 해시를 솔트합니다. 본질적으로 각 사용자마다 다르지만 우리가 쉽게 사용할 수있는 것입니다. 다른 제품은 각 사용자에 대해 무작위로 솔트를 생성하고 사용자가 암호를 변경할 때마다 변경합니다. 그런 다음 솔트는 데이터베이스에서 암호화됩니다.

내 질문은 두 번째 접근 방식이 정말로 필요한지 여부입니다. 순전히 이론적 관점에서 첫 번째 접근 방식보다 더 안전하다는 것을 이해할 수 있지만 실용성 관점에서는 어떨까요? 현재 사용자를 인증하려면 솔트가 암호화되지 않고 로그인 정보에 적용되어야합니다.

그것에 대해 생각한 후, 나는이 접근 방식에서 진정한 보안 이득을 보지 못했습니다. 계정에서 계정으로 솔트를 변경하면 공격자가 각 계정에 대한 것이 무엇인지 신속하게 파악하는 방법을 알고 있더라도 누군가가 해싱 알고리즘을 무차별 대입하려고 시도하는 것은 매우 어렵습니다. 이것은 암호가 충분히 강력하다는 가정하에 진행됩니다. (분명히 두 자리 숫자 인 비밀번호 세트에 대해 올바른 해시를 찾는 것이 8 자리 비밀번호의 올바른 해시를 찾는 것보다 훨씬 쉽습니다). 내 논리가 잘못되었거나 내가 놓친 것이 있습니까?

편집 : 좋아 그래서 여기에 내가 소금을 암호화하는 것이 정말로 논쟁이라고 생각하는 이유가 있습니다. (내가 올바른 길을 가고 있는지 알 수 있음).

다음 설명에서는 암호가 항상 8 자이고 솔트가 5이고 모든 암호가 소문자로 구성되어 있다고 가정합니다 (수학이 더 쉬워 짐).

각 항목에 대해 다른 소금을 사용한다는 것은 동일한 무지개 테이블을 사용할 수 없음을 의미합니다 (실제로는 충분한 크기의 테이블이 있으면 사용할 수 있지만 지금은 무시하겠습니다). 이것이 내가 이해하는 소금의 진정한 열쇠입니다. 왜냐하면 모든 계정을 깨뜨리기 위해서는 각각에 대해 말할 수 있도록 바퀴를 재발 명해야하기 때문입니다. 이제 해시를 생성하기 위해 올바른 솔트를 암호에 적용하는 방법을 안다면 솔트가 실제로 해시 된 구문의 길이 / 복잡성을 확장하기 때문에 그렇게 할 것입니다. 그래서 나는 내가 소금이 무엇인지 알고 있기 때문에 암호 + 소금을 13 ^ 26에서 8 ^ 26으로 "알기"위해 생성해야 할 가능한 조합의 수를 줄일 것입니다. 이제는 더 쉬워 지지만 여전히 정말 어렵습니다.

그래서 소금을 암호화합니다. 솔트가 암호화되어 있다는 것을 안다면 먼저 암호화를 시도하거나 해독하지 않을 것입니다 (충분한 수준의 암호화가 있다고 가정 할 때). 나는 그것을 무시할 것이다. 암호를 해독하는 방법을 알아내는 대신 이전 예제로 돌아가서 13 ^ 26에 대한 모든 키를 포함하는 더 큰 무지개 테이블을 생성합니다. 소금을 모르면 확실히 속도가 느려지지만 소금 암호화를 먼저 해독하려는 기념비적 인 작업을 추가하지는 않을 것입니다. 그럴 가치가 없다고 생각하는 이유입니다. 생각?

다음은 무차별 대입 공격시 암호가 얼마나 오래 유지되는지 설명하는 링크입니다. http://www.lockdown.co.uk/?pg=combi


좋은 질문이에요, 케빈 보안에 대해서는 언급 할 수 없지만이 모든 암호화 및 암호 해독에는 성능 저하가 있습니다.
DOK

적당한 크기의 무지개 테이블을 무시할 필요가 없습니다.이 테이블은 솔트 된 해시를 해독하고 원래 해시를 해독하는 데 다시 사용할 수 있기 때문에 암호화 된 솔트 모트를 만듭니다. 좋은 소식은 테이블을 만드는 데 아마도 수세기가 걸릴 것이라는 것입니다.
tloach

나를 얻는 것은 그 크기의 무지개 테이블을 만드는 데 그렇게 오래 걸릴지 완전히 확신하지 못한다는 것입니다. 그는 엉뚱한 생각입니다. Kraken과 같은 분산 컴퓨팅 플랫폼을 사용하여 생성합니다. 그럼 얼마나 걸릴까요?
kemiller2002

3
@Kevin : SHA1은 40 자 16 진수 문자열을 반환하므로 40 ^ 16 개의 가능한 반환 값이 있습니다. 한 대의 컴퓨터가 매초 1000 개의 해시를 계산할 수 있다고 가정하면 1000000 대의 컴퓨터를 계산하면 해당 크기의 문자열을 결정할 수있는 무지개 테이블을 생성하는 데 약 100 억 년이 걸립니다.
tloach

+1 좋은 질문이며 잘 읽었습니다. 이 질문에 대한 답이 틀렸다고 생각합니다. 해시는 얻을 때까지 해시를 깨뜨릴 수 없기 때문에 항상 비밀이어야합니다. CWE-760에 대해 읽어야합니다 ( cwe.mitre.org/data/definitions/760.html )
rook

답변:


45

여기서 대답은 당신이 정말로 보호하려는 것이 무엇인지 스스로에게 물어 보는 것입니다. 누군가 데이터베이스에 액세스 할 수있는 경우 암호화 된 솔트에 액세스 할 수 있으며 사용자 코드에도 액세스 할 수 있습니다. 그들은 암호화 된 솔트를 해독 할 수 있습니까? 그렇다면 암호화는 어쨌든 거의 쓸모가 없습니다. 소금은 실제로 그것을 만들기 위해 존재하므로 전체 암호 데이터베이스가 침입 당하면 한 번에 전체 암호 데이터베이스를 크래킹하는 무지개 테이블을 형성하는 것은 불가능합니다. 이러한 관점에서 각 솔트가 고유 한 한 차이가없는 한 각 암호에 대해 솔트 또는 암호화 된 솔트를 사용하여 무차별 대입 공격이 필요합니다.


이러한 개념에 익숙하지 않습니다. 따라서 순진한 질문처럼 보일 수 있지만 가능한 모든 암호에 대해 솔트 값에 대해 하나의 조합 만 시도하므로 각 암호에 대한 솔트를 알고있는 무지개 테이블을 만드는 것이 더 쉽지 않을까요?
stdout

일반적으로 사용되는 1000 개의 암호의 ranbow 테이블은 해싱과 거의 동일한 속도로 이것을 깨뜨릴 것입니다. 이것이 작동하는 유일한 방법은 암호의 배포가 균일하다고 가정하는 것입니다. 그리고 우리는 그렇지 않다는 것을 알고 있습니다.
DaWNFoRCe

100

소금을 숨길 필요는 없습니다.

해시마다 다른 솔트를 사용해야합니다. 실제로 이것은 암호화 품질 난수 생성기에서 8 바이트 이상을 가져 오면 쉽게 얻을 수 있습니다.

A로부터 내 이전의 대답 :

Salt는 사전 계산 된 사전 공격을 막는 데 도움이됩니다.

공격자가 가능한 암호 목록을 가지고 있다고 가정합니다. 그는 각각을 해시하고 피해자의 암호 해시와 비교하여 일치하는지 확인할 수 있습니다. 목록이 크면 시간이 오래 걸릴 수 있습니다. 그는 다음 목표에 그렇게 많은 시간을 보내고 싶지 않기 때문에 해시가 해당 입력을 가리키는 "사전"에 결과를 기록합니다. 암호 목록이 매우 길면 Rainbow Table과 같은 기술을 사용하여 공간을 절약 할 수 있습니다.

그러나 그의 다음 대상이 암호를 솔트했다고 가정합니다. 공격자가 솔트가 무엇인지 알고 있더라도 사전 계산 된 테이블은 쓸모가 없습니다. 솔트는 각 암호의 결과로 해시를 변경합니다. 그는 자신의 목록에있는 모든 암호를 다시 해시하고 대상의 솔트를 입력에 추가해야합니다. 각기 다른 솔트에는 다른 사전이 필요하며 충분한 솔트가 사용되면 공격자는 모두에 대한 사전을 저장할 공간이 없습니다. 시간 절약을위한 거래 공간은 더 이상 선택 사항이 아닙니다. 공격자는 공격하려는 각 대상에 대해 자신의 목록에있는 각 암호를 해싱해야합니다.

따라서 소금을 비밀로 유지할 필요는 없습니다. 공격자가 특정 솔트에 해당하는 사전 계산 된 사전이 없는지 확인하는 것으로 충분합니다.


이것에 대해 조금 더 생각 해보니 소금이 숨겨 질 수 있다고 생각하도록 속이는 것이 위험하다는 것을 깨달았습니다. 소금을 숨길 수 없다고 가정하고 시스템을 안전하게 설계하는 것이 훨씬 낫습니다. 다른 답변에서 더 자세한 설명 제공합니다 .


그러나 NIST의 최근 권장 사항은 추가 비밀 "소금" 의 사용을 권장합니다 (다른 사람들이이 추가 비밀 "후추"라고 부르는 것을 보았습니다). 이 비밀을 솔트로 사용하여 키 파생의 추가 반복을 수행 할 수 있습니다. 이 라운드는 미리 계산 된 조회 공격에 대한 강도를 높이기보다는 좋은 키 파생 함수에서 많은 반복 횟수와 마찬가지로 암호 추측으로부터 보호합니다. 이 비밀은 해시 된 암호와 함께 저장되면 아무 용도가 없습니다. 비밀로 관리해야하며 대규모 사용자 데이터베이스에서는 어려울 수 있습니다.


1
해시를 얻을 때까지 해시를 깨뜨릴 수 없기 때문에 소금을 숨겨야합니다. 이것은 CWE-760 ( cwe.mitre.org/data/definitions/760.html ) 과 관련이 있습니다
rook

28
@The Rook-아니, 당신은 그 문제를 잘못 해석하고 있습니다. 예측 가능한 염의 사용을 나타냅니다. 소금을 비밀로하는 것에 대해서는 아무 말도하지 않습니다. 실제로 다른 비밀을 사용하지 않고는 소금 비밀을 지킬 수 없습니다. 그렇다면 두 번째 비밀을 소금으로 사용하지 않는 이유는 무엇입니까? 사용자 이름을 솔트로 사용하는 것은 여러 시스템이 동일한 사용자 이름을 공유 할 가능성이 높기 때문에 특정 솔트에 대한 테이블을 만드는 것이 더 가치가 있기 때문입니다. 무작위 소금이 가장 좋지만 비밀로 유지할 필요 는 없습니다 .
erickson


1
@erickson, 여기에서 용어를 혼동하고 있다고 생각합니다. 솔트는 숨겨져 있지 않는 한 사전 공격을 방해하지 않습니다. 많은 소금이 공개적으로 저장됩니다. 그리고 소금을 알고 있다면 사전 공격은 사전 용어에 소금을 추가하는 데 걸리는 시간만큼만 느려집니다. :) 소금은 Rainbow 테이블 조회를 방지합니다 .... 꽤 빠른 속도입니다. 공격자가 여러분의 염분을 알고 있다면 사전 공격으로부터 보호받지 못합니다. 공격자가 당신의 소금을 모르면 사전 공격으로부터 보호되며 무차별 대입 공격을 사용해야합니다.
Ultratrunks

4
@Ultratrunks 예, "사전 계산 된 사전 공격"이라는 용어를 사용하여이 주제에 대한 몇 가지 답변을 명확히했습니다. Rainbow 테이블보다 일반적으로 해시를 키로 사용하여 일반 텍스트의 역방향 조회를 허용하는 모든 구조를 나타냅니다. 선택한 용어에 관계없이 소금은 Rainbow 테이블 및 유사한 메커니즘을 무력화하기위한 것이라고 명시 적으로 설명합니다. 항상 공격자가 소금을 알고 있다고 가정해야합니다. 비밀을 유지할 수 있다면 암호를 해시 할 필요가 없습니다.
erickson

3

"소금"에 대한 나의 이해는 크래킹을 더 어렵게하지만 여분의 데이터를 숨기려고하지 않는다는 것입니다. 솔트를 "비밀"로 만들어 더 많은 보안을 얻으려는 경우 암호화 키에 더 많은 비트가 필요합니다.


3

두 번째 방법은 약간 더 안전합니다. 솔트는 사전 공격과 레인보우 테이블 공격으로부터 사용자를 보호합니다. 야심 찬 공격자가 전체 시스템을 손상시키는 것을 어렵게 만들지 만 여전히 시스템의 한 사용자에게 초점을 맞춘 공격에 취약합니다. 전화 번호와 같이 공개적으로 사용 가능한 정보를 사용 하고 공격자가이 사실을 알게되는 경우 된다면 공격의 단계를 저장 한 것입니다. 물론 문제는 공격자가 전체 데이터베이스, 솔트 등을 얻는다면 의문의 여지가 있습니다.

편집 : 이 답변과 일부 의견을 다시 읽은 후 질문에 제시된 두 가지 매우 구체적인 경우 만 비교하고 있다는 사실로 인해 혼란이 발생할 수 있습니다. 무작위가 아닌 소금. 전화 번호를 솔트로 사용하는 문제는 공격자가 전체 데이터베이스를 가져 오면 논쟁의 여지가 있으며 솔트 사용에 대한 질문이 아닙니다 .


사전 공격으로부터 어떻게 보호합니까?
tloach

공격자가 각 암호 + 솔트 조합에 대해 새 사전을 만들도록합니다. 솔트가 없으면 전체 암호 테이블에 대해 하나의 사전을 사용할 수 있습니다.
Bill the Lizard

"물론 공격자가 전체 데이터베이스, 솔트 등을 입수한다면 문제는 의문의 여지가 있습니다." 소금이 암호화 된 이유가 아닌가요?
Patrick McElhaney

1
@Bill : 방금 무지개 테이블을 설명하셨습니다. 사전 공격은 일반적인 단어를 사용하여 인증을 시도하는 곳입니다. 응답 공간이 크게 줄어든 무차별 대입입니다. 무차별 대입을 막는 해시는 없습니다.
tloach

이 관행에 대해 들어 본 적이 없지만 보안 전문가는 아닙니다. 고유 한 솔트를 암호화하면 레인보우 테이블 공격에 대한 추가 보호 계층이 추가되는 것 같습니다.
Bill the Lizard

3

... 사용자 이름이나 전화 번호와 같은 것입니다. ...

내 질문은 두 번째 접근 방식이 정말로 필요한지 여부입니다. 순전히 이론적 관점에서 첫 번째 접근 방식보다 더 안전하다는 것을 이해할 수 있지만 실용성 관점에서는 어떨까요?

실용적인 관점에서 솔트는 구현 세부 사항입니다. 정확한 예를 사용하기 위해 사용자 정보가 수집되거나 유지되는 방식을 변경하고 사용자 이름과 전화 번호가 때때로 변경되는 경우 보안이 손상되었을 수 있습니다. 이러한 외부를 향한 변경이 훨씬 더 깊은 보안 문제를 갖기를 원하십니까?

각 계정에 전화 번호가 있어야한다는 요구 사항을 중지하려면 해당 계정이 보안 침해에 노출되지 않았는지 확인하기 위해 완전한 보안 검토가 필요합니까?


2
임의의 사용자 정보를 사용하고 있는지 여부는 말할 것도없고, 사용자가 해당 정보를 변경할 때 암호를 다시 입력해야 새 솔트를 사용하여 다시 암호화 할 수 있습니다.
Treborbob

3

숨겨진 소금은 더 이상 소금이 아닙니다. 후추입니다. 그것의 용도가 있습니다. 소금과는 다릅니다.

Pepper는 해시를 HMAC (Hash Based Message Authentication Code)로 만드는 비밀번호 + 솔트에 추가 된 비밀 키입니다. 해시 출력 및 솔트에 액세스 할 수있는 해커는 이론적으로 해시를 생성 할 입력을 무차별 대입하여 추측 할 수 있습니다 (따라서 암호 텍스트 상자에서 유효성 검사를 통과 함). 후추를 추가하면 암호 학적으로 무작위로 문제 공간을 늘려 심각한 하드웨어 없이는 문제를 처리하기 어렵게 만듭니다.

고추에 대한 자세한 내용은 여기 에서 확인 하세요. .

hmac 도 참조하십시오 .


2

다음은 각 해시에 대해 동일한 솔트를 사용하는 것이 왜 나쁜지 보여주는 간단한 예입니다.

다음 표를 고려하십시오.

UserId  UserName,   Password
     1  Fred       Hash1 =  Sha(Salt1+Password1)    
     2  Ted        Hash2 =  Sha(Salt2+Password2)    

Salt 1이 salt2와 같은 경우 1 Hash2가 Hash1 로 바뀌면 사용자 2는 사용자 1 암호로 로그온 할 수 있습니다.

솔트 1이 동일한 솔트 2가 아닌 경우 2 Hash2가 Hash1로 바뀌면 user2는 사용자 1 암호로 로그온 할 수 없습니다.


각 계정에 대해 동일한 해시를 사용하지 않고 각 해시에 대해 동일한 유형의 정보를 사용하고 있습니다. 예를 들어, 계정의 솔트는 계정의 전화 번호 등입니다.
kemiller2002

오랜 시간이 지난 건 알지만 ... 이런 유형의 공격으로부터 보호하기 위해 소금에 의존 할 수는 없습니다. 우리는 공격자가 비밀 (즉, 암호)을 제외한 인증 시스템에 대한 모든 것을 알고 있다고 가정해야합니다. 따라서 우리는 공격자가 a) 우리가 솔트로 사용하는 것을 알고 있다고 가정해야합니다 (대부분의 경우 이것은 동일한 데이터베이스와 일반 텍스트 테이블에 저장 됨) b) 솔트를 사용하여 해싱하는 방법 (예 : 추가, 두 번, 기타). 사용자가 해시를 전환 할 수있는 능력이 있다면, 그들이 솔트도 전환 할 수 있다고 가정해야합니다. 소금은 여기서 도움이되지 않습니다.
Dave Satch 2014 년

1

목표가 다른 두 가지 기술이 있습니다.

  • "salt"는 두 개의 동일한 암호를 다르게 암호화하는 데 사용됩니다. 이런 식으로 침입자는 암호화 된 암호의 전체 목록에 대해 사전 공격을 효율적으로 사용할 수 없습니다.

  • (공유 된) "비밀"은 메시지를 해싱하기 전에 추가되므로 침입자가 자신의 메시지를 작성하여 수락 할 수 없습니다.


0

나는 소금을 숨기는 경향이 있습니다. 해싱하기 전에 암호 시작 부분에 1에서 1024까지의 임의의 숫자를 추가하여 10 비트 솔트를 사용합니다. 사용자가 입력 한 암호를 해시와 비교할 때 1에서 1024까지 반복하고 일치하는 것을 찾을 때까지 가능한 모든 salt 값을 시도합니다. 이것은 1/10 초도 채 걸리지 않습니다. PHP password_hashpassword_verify 에서 이런 식으로 할 아이디어를 얻었습니다 . 내 예에서 "비용"은 10 비트 소금에 대해 10입니다. 또는 다른 사용자의 말에서 숨겨진 "소금"을 "후추"라고합니다. 솔트는 데이터베이스에서 암호화되지 않습니다. 강제로 무차별 적입니다. 해시를 1000 배 더 크게 뒤집기 위해 레인보우 테이블이 필요합니다. 빠르지 만 여전히 안전한 것으로 간주되기 때문에 sha256을 사용합니다.


따라서 내 암호가 "345678"이고 앞에 추가 한 임의의 솔트가 "12"라고 말하면됩니다. 누군가 내 비밀번호로 "45678"을 입력하는 경우. 이것은 여러면에서 잘못된 것 같습니다.
Yurippenet 2011

-1

실제로 데이터를 보호하려는 공격 유형에 따라 다릅니다.

각 암호에 대한 고유 한 솔트의 목적은 전체 암호 데이터베이스에 대한 사전 공격을 방지하는 것입니다.

각 암호에 대해 고유 한 솔트를 암호화하면 개별 암호를 해독하기가 더 어려워 지지만 실제로 많은 이점이 있는지 여부를 고려해야합니다. 공격자가 무차별 대입으로 다음 문자열을 발견하면

Marianne2ae85fb5d

DB에 저장된 해시로 해시하면 어떤 부분이 패스이고 어떤 부분이 솔트인지 알아내는 것이 정말 어렵습니까?


2
누군가가 무차별 적으로 암호를 추측 할 수 없도록 강요한다면 어쨌든 아무도 생각지도 못한 기술을 가지고 있기 때문에 어쨌든 당신은 푹 빠졌다고 말할 것입니다.
Instance Hunter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.