소금 줄은 어디에 보관합니까?


250

데이터베이스 저장소의 암호를 해시 할 때 항상 적절한 항목 별 솔트 문자열을 사용했습니다. 필자의 필요에 따라 해시 된 암호 옆에 DB에 소금을 저장하는 것이 항상 잘 작동했습니다.

그러나 어떤 사람들은 소금을 데이터베이스와 별도로 저장하는 것이 좋습니다. 데이터베이스가 손상된 경우에도 공격자는 특정 솔트 문자열을 고려하여 레인보우 테이블을 만들어 한 번에 하나의 계정을 크래킹 할 수 있습니다. 이 계정에 관리자 권한이 있으면 다른 사람을 크래킹하지 않아도됩니다.

보안 측면에서 소금을 다른 곳에 보관하는 것이 가치가 있습니까? 동일한 머신에 서버 코드 및 DB가있는 웹 애플리케이션을 고려하십시오. 솔트가 해당 머신의 플랫 파일에 저장되면 데이터베이스가 손상되면 솔트 파일도 손상 될 수 있습니다.

이에 대한 권장 솔루션이 있습니까?


9
침입자가 얻을 수없는 소금을 저장할 수있는 장소가 있다면 암호도 저장해야합니다. 그러나 모든 비밀번호에 대해 다른 소금을 사용하지 않는 이유는 무엇입니까?
jrockway

8
그는 모든 암호에 대해 다른 소금을 사용하고 있습니다.
Amber

9
소금은 얼마나 큽니까? 당신의 소금은 레인보우 테이블이 사전 계산 될 가능성이 거의 없을 정도로 충분히 커야합니다 (32 비트?).
M. Dudley

@emddudley 요즘 나는 64 비트 정수를 소금으로 사용하는 습관을 겪었지만 더 이상 만들 수있는 이유는 없습니다.
friedo

10
PWDTK의 저자 여기 sourceforge.net/projects/pwdtknet , 솔직히 걱정하지 않을 나는 암호와 같은 DB에 바로 저장 소금 것. 어쨌든 항상 소금이 공격자에게 알려져 있다고 가정해야하므로 큰 CRYPTO-RANDOM 소금을 사용하고 하나의 알려진 소금에 대해 하나의 레인보우 테이블조차 만들 수 없도록 충분한 키 스트레칭 (PBKDF2 반복)에 중점을 두어야합니다. 솔직히 당신이 소금을 다른 곳에 두어 달성하려고하는 것은 "불분명 한 보안 (Security by Obscurity)"이며 잠재적으로 다운 될 다른 서버와 같은 것을 볼 때 일반적으로 이점을 제공하지 않습니다.
thashiznets

답변:


259

레인보우 테이블의 요점은 사전에 생성되어 다른 사람들의 계산 시간을 절약하기 위해 대량으로 배포된다는 것입니다. 즉, 레인보우 테이블을 생성하는 데 암호 + 소금 조합을 직접 크랙하는 것만 큼 오래 걸립니다. 레인보우 테이블을 생성 할 때 수행되는 작업은 해시를 강제로 수행하는 계산을 사전 실행하는 것입니다.) 따라서 누군가가 "레인보우 테이블을 생성 할 수있는 소금을 알면 허위입니다.

솔트가 사용자별로 존재하는 한 별도의 파일에 솔트를 저장하는 데는 아무런 의미가 없습니다. 솔트의 요점은 단순히 하나의 레인보우 테이블이 DB의 모든 암호를 깰 수 없도록 만드는 것입니다.


17
동의했다. 소금을 별도로 저장하여 보호하는 위협 모델은 해로운 방법 (DB의 해시가 아닌)을 통해 DB의 소금에 액세스 할 수있는 사용자입니다. 그 사람은 나중에 해시를 찾을 수 있다고 가정하고 레인보우 테이블을 미리 계산하기 시작합니다. 불가능하지는 않지만이 단일 공격 경로를 방어하기위한 엔지니어링 노력도 가치가 없습니다.
Tom Ritter

좋은 포스트, 나는 같은 것을 궁금해했다. 나는 사용자 당 소금에 대해 전혀 생각하지 않았다. 나는 단일 소금이 모든 사용자에게 효과적이라고 생각했다. App Server에서로드 한 XML 파일로 저장된 솔트는 어떻습니까? 아니면 어떻게 든 서블릿에 하드 코딩되어 있습니까?
jigzat

9
@Jigzat-각 사용자에 대해 별도의 소금이 없으면 소금이 무의미합니다. 소금의 요점은 해시를 깨는 것이 각 사용자 암호에 대해 별도의 작업을 만드는 것입니다. 소금이 모두 동일하다면 그것은 사실이 아닙니다.
Amber

3
@TomRitter가 유일한 사례는 아닙니다. 모든 비밀번호가 복잡하다고 가정합니다. 일부 공격자는 솔트 및 해시를 사용하여 가장 일반적인 10,000 개의 암호 만 확인할 수 있습니다. 그런 식으로 그들은 적당한 수의 사람들을 얻을 것입니다. 그러나, 그들이 소금에 접근 할 수 없다면, 그것은 더 긴 암호를 가진 사용자와 유사합니다. 암호 데이터베이스가 도난당하는 동안 소금 데이터베이스가 안전하게 유지 될 가능성은 어느 정도이지만, 그것은 별도의 문제입니다.
chacham15

@ 앰버, TomRitter가 맞다고 생각합니다. 소금을 따로 보관한다는 것은 공격자가 무차별 대입 공격을 사용하는 것과 쉬운 사전 공격을하는 것의 차이를 의미합니다. 소금을 알고 있다면 밀 사전 공격을 실행하는 동안 소금을 추가 할 수 있습니다. 당신의 소금을 100 % 방어 할 수 있다면, 당신은 단순히 같은 소금을 사용하고 공격자가 강제로 모든 것을 무력화 할 수 있습니다. 그러나 당신은 당신의 소금을 방어 할 수 있습니다 .... 아마 아닙니다. 따라서 해시 옆에 저장하여 실패 지점을 줄이고 강력한 암호 규칙을 시행 할 수도 있습니다.
울트라 트렁크

35

나는 이것에 대해 약간 다른 테이크를 제공 할 것이다.

나는 항상 소금에 절인 암호 해시와 섞인 소금을 저장합니다.

예를 들어, 나는 소금의 첫 절반을 암호의 소금에 절인 해시 앞에 놓고 소금의 마지막 절반을 암호의 소금에 절인 해시 뒤에 놓습니다. 응용 프로그램은이 디자인을 알고 있으므로이 데이터를 가져 와서 소금과 소금에 절인 암호 해시를 얻을 수 있습니다.

이 접근법에 대한 나의 근거 :

암호 / 해시 데이터가 손상되어 공격자의 손에 들어가면 공격자는 데이터를 살펴보면 소금이 무엇인지 알 수 없습니다. 이런 식으로 공격자는 해시와 일치하는 암호를 얻기 위해 실제로 무차별 대입 공격을 수행 할 수 없습니다. 해시를 시작할지 모르고 데이터의 어떤 부분이 소금의 일부인지 알 수 없기 때문입니다. 솔트 된 비밀번호 해시의 일부 ( 응용 프로그램의 인증 로직을 모르는 경우 제외) ).

솔트 된 암호 해시가있는 그대로 저장되면, 솔트 및 해시 된 경우 솔트 된 암호 해시와 동일한 데이터를 생성하는 암호를 얻기 위해 무차별 대입 공격을 수행 할 수 있습니다.

그러나 예를 들어, 소금에 절인 암호 해시가있는 그대로 저장되었지만 단일 바이트로 미리 추가 된 경우에도 공격자가 첫 번째 바이트를 폐기해야한다는 사실을 모르면 어려움이 증가합니다. 공격의. 응용 프로그램은 사용자를 인증하는 데 사용될 때 데이터의 첫 바이트를 버리는 것을 알고 있습니다.

이것에 대한 결론 ..

1) 인증 응용 프로그램이 사용하는 데이터를 정확한 형식으로 저장하지 마십시오.

2) 가능하면 보안 강화를 위해 인증 논리를 비밀로 유지하십시오.

한 걸음 더 나아갑니다.

응용 프로그램의 인증 논리를 비밀로 유지할 수없는 경우 많은 사람들이 데이터가 데이터베이스에 저장되는 방식을 알고 있습니다. 그리고 소금과 함께 섞인 소금에 절인 해시를 저장하기로 결정했다고 가정 해 봅시다.

임의 소금을 생성 할 때, 소금에 절인 암호 해시 전후에 소금의 비율을 무작위로 결정할 수도 있습니다.

예를 들어 512 바이트의 임의 소금을 생성합니다. 비밀번호에 솔트를 추가하고 솔트 된 비밀번호의 SHA-512 해시를 얻습니다. 또한 임의의 정수 200을 생성합니다. 그런 다음 처음 200 바이트의 소금을 저장 한 다음 소금에 절인 암호 해시와 나머지 소금을 저장합니다.

사용자의 비밀번호 입력을 인증 할 때 응용 프로그램은 문자열을 통과하고 데이터의 첫 1 바이트는 솔트의 첫 1 바이트이고 솔트 해시가 뒤따른다고 가정합니다. 이 패스는 실패합니다. 응용 프로그램은 처음 2 바이트의 데이터를 솔트의 첫 2 바이트로 계속 사용하고 처음 200 바이트를 솔트의 첫 200 바이트로 사용한 후 긍정적 결과가 나올 때까지 반복합니다. 암호가 틀리면 응용 프로그램은 찾을 수 없을 때까지 모든 순열을 계속 시도합니다.

이 접근법의 장점 :

보안 강화-인증 로직을 알고 있더라도 컴파일시 정확한 로직을 알 수 없습니다. 정확한 논리에 대한 지식이 있어도 무차별 대입 공격을 수행하는 것은 사실상 불가능합니다. 소금의 길이가 길수록 안전성이 더 높아집니다.

이 접근법의 단점 :

정확한 로직은 런타임에 유추되므로이 방법은 CPU를 많이 사용합니다. 솔트의 길이가 길수록이 방법은 CPU를 많이 사용합니다.

잘못된 비밀번호를 인증하면 CPU 비용이 가장 많이 듭니다. 이는 합법적 인 요청에 비생산적 일 수 있지만 공격자에 대한 보안을 강화합니다.

이 방법은 다양한 방식으로 구현 될 수 있으며 가변 너비 솔트 및 / 또는 솔트 비밀번호 해시를 사용하여 더욱 안전하게 만들 수 있습니다.


9
접근 방식을 사용하면 해시 프로세스 (소금을 적용하는 알고리즘)에 비밀을 추가하는 것입니다. 이 비밀 은 소금에 후추를 추가 하여 훨씬 쉽게 추가 할 수 있습니다 . 내 자습서 에서 이것을 지적하려고했습니다 . BCrypt와 같은 현대 해시 함수는 각 반복에서 원래 소금을 사용하여 소금을 자체적으로 적용하므로 어쨌든이를 제어 할 수 없습니다.
martinstoeckli

@martinstoeckli BCrypt가 자체적으로 소금을 바르는 것이 맞지만 그 소금 + 해시의 저장은 개발자에게 달려 있습니다. 따라서 후추를 salt + hash에 쉽게 추가하고 데이터베이스에 유지할 수 있습니다. 그런 다음 후속 검색시 데이터베이스에서 값을 읽고 후추 값을 제거하고 나머지 값을 BCrypt에 전달합니다.
PeterToTheThird

2
@PeterToTheThird-고추의 장점을 무효화합니다. 후추는 서버 측의 비밀을 추가하고 비밀로 유지되는 한 (소금과 반대되는) 작동합니다. 일반적인 공격은 SQL 주입인데, 누군가가 데이터베이스에 액세스하지만 코드에는 액세스하지 못하면 데이터베이스에 저장된 후추는 쓸모가 없습니다. 대부분의 BCrypt 구현은 결과 해시 값에 솔트를 자동으로 추가하므로이 값에는 이미 솔트, 비용 계수, 알고리즘 및 해시가 포함됩니다. 이 문자열은 60 자 길이의 단일 필드에 저장할 수 있습니다.
martinstoeckli

또한 BCrypt와 같은 "키 강화"기능을 사용할 때는 소금 사용을 제어 할 수 없습니다. 그러나 후추를 사용하려면 후추를 소금에 첨가하고 해싱 함수의 "소금"입력 대신 "고추 소금"으로 사용하면됩니다. "페퍼" 는 데이터베이스에 저장 되지 않지만 인증 코드에 포함되거나 다른 안전한 위치에 저장 되는 적절한 데이터 조각입니다 . SHA-512를 예제 함수로 사용하여 일반적인 관점에서 문제에 접근했지만 BCrypt 등도 비슷한 방식으로 사용할 수 있습니다.
Ibraheem

2
@martinstoeckli-예, 실제 구현은 사용하는 해시 함수에 따라 다릅니다. 인증 로직을 구현할 때 해시 함수의 매개 변수와 출력을 고려해야합니다. 궁극적으로 후추는 해싱 함수에 도입 된 또 다른 변수이며 소금 및 해시와 같은 위치에 저장 되지 않습니다 .
Ibraheem

23

종종 해시 앞에 붙고 같은 필드에 저장됩니다.

별도로 저장할 필요가 없습니다. 요점은 각 비밀번호에 대해 임의의 솔트를 사용하여 단일 레인보우 테이블을 전체 비밀번호 해시 세트에 사용할 수 없도록하는 것입니다. 무작위 소금을 사용하는 경우 공격자는 각 해시를 개별적으로 무차별 처리해야합니다 (또는 가능한 모든 소금에 대한 레인보우 테이블 계산-훨씬 더 많은 작업).

보다 안전한 저장 위치가 있다면 해시를 저장하는 것이 좋습니다.


4
그러나 일치하는 소금을 포함하여 모든 해시 된 암호가 유출되면 어떻게됩니까? 그렇게 안전하지 않습니까?
mghaoui

10
@mghaoui 그러나 만약 당신이 "암호"를 알고 싶다면 소금의 일부가 같지 않다면 각각의 소금마다 레인보우 테이블을 만들어야합니다.
프랭클린

4

William Penberthy의 ASP.NET MVC 4 웹 애플리케이션 개발 책을 기반으로 :

  1. 별도의 데이터베이스에 저장된 솔트에 액세스하려면 해커가 두 개의 서로 다른 데이터베이스를 해킹하여 솔트 및 솔트 된 비밀번호에 액세스해야합니다. 비밀번호와 동일한 테이블 또는 동일한 데이터베이스의 다른 테이블에 저장하면 해커가 데이터베이스에 액세스 할 때 솔트 및 비밀번호 해시 모두에 액세스 할 수 있습니다. 보안에는 시스템에 대한 해킹이 너무 비싸거나 시간이 많이 걸리는 프로세스가 포함되기 때문에 해커가 얻는 액세스 수를 두 배로 늘리면 시스템의 보안이 강화됩니다.
  2. 사용하기 쉬우므로 염분을 해시 된 비밀번호와 동일한 데이터베이스에 유지해야합니다. 두 개의 데이터베이스가 항상 동시에 사용 가능하고 항상 동기화되어 있는지 확인하지 않아도됩니다. 개인의 암호를 쉽게 발견 할 수 있지만 시스템의 암호를 해독하는 데 필요한 힘의 양이 많기 때문에 각 사용자가 임의의 소금을 사용하는 경우 소금을 사용하는 이점은 최소화됩니다. 이 수준의 논의에서는 암호를 보호하는 것이 실제로 기대되는 것입니다. 해커가 데이터베이스 사본을 확보 한 경우 애플리케이션 데이터가 이미 손상되었습니다. 이 시점에서 문제는 공유 암호의 가능성으로 인한 사용자 위험을 완화하는 것입니다.
  3. 두 개의 개별 연결된 데이터베이스를 유지 관리해야하는 요구 사항은 광범위합니다. 물론 보안에 대한 인식이 높아지지만 유일한 이점은 단일 데이터 요소 인 암호를 보호한다는 것입니다. 데이터베이스의 모든 필드가 개별적으로 암호화되고 동일한 소금이 사용 된 경우 시스템의 기본 보안이 향상되므로 데이터와 별도로 저장하는 것이 더 합리적입니다.

응용 프로그램이 두 데이터베이스를 모두 인증 할 수 있다면 공격자가 응용 프로그램 코드를 손상시킨 경우 하나의 데이터베이스 인 것처럼 본질적으로 동일하지 않습니까?
존 어니스트

0

소금의 요점은 모든 무지개 테이블을 쓸모 없게 만들고 새로운 세트를 만들어야한다는 것입니다. 무지개 테이블을 만드는 것처럼 문자열을 추측하는 데 시간이 오래 걸립니다. 예를 들어 "password"의 SHA-256 해시는 5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8입니다. "badpassword"와 같은 솔트가 추가 된 후 해시 될 새 문자열은 "passwordbadpassword"이며, 이는 눈사태 효과로 인해 출력을로 크게 변경합니다 457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6.

일반적으로 소금은 암호와 동일한 데이터베이스에 저장됩니다. 또한 한 데이터베이스가 해킹되면 다른 데이터베이스도 해킹 될 수 있기 때문입니다.

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