그것은, 마커스 아담스의 대답의 확장하지만 내가 여기에 언급을 참조하지 않았다고 한 것은 당신의 가능성이있는 경우를 식별하고 사용자를 인증 모두에 단일 정보를 사용하지해야한다는 것입니다 타이밍 공격 ,하는 수 응답 시간의 차이를 사용하여 문자열 비교가 얼마나 멀리되었는지 추측하십시오.
"키"를 사용하여 사용자 또는 자격 증명을 조회하는 시스템을 사용하는 경우 수천 개의 요청을 보내고 데이터베이스가 찾는 데 걸리는 시간을 검사하여 시간이 지남에 따라 해당 정보를 점진적으로 추측 할 수 있습니다. 찾기) 기록. "키"가 키의 단방향 해시 대신 일반 텍스트로 저장되는 경우 특히 그렇습니다. 사용자에게 키를 다시 표시 할 수 있어야하는 경우 사용자의 키를 일반 텍스트로 저장하거나 대칭 적으로 암호화 할 수 있습니다.
두 번째 정보 또는 "비밀"이 있으면 먼저 타이밍 공격에 취약 할 수있는 "키"를 사용하여 사용자 또는 자격 증명을 조회 한 다음 타이밍 안전 비교 기능을 사용하여 값을 확인할 수 있습니다. 비밀".
다음은 해당 함수의 Python 구현입니다.
https://github.com/python/cpython/blob/cd8295ff758891f21084a6a5ad3403d35dda38f7/Modules/_operator.c#L727
그리고 그것은 hmac
lib (그리고 아마도 다른 것)에 노출됩니다 .
https://docs.python.org/3/library/hmac.html#hmac.compare_digest
여기서 주목해야 할 점은 비교되는 값이 입력 문자열의 문자가 변경 될 때마다 무작위로 변경되기 때문에 이러한 종류의 공격이 조회 전에 해시되거나 암호화 된 값에 대해 작동하지 않는다는 것입니다. 여기에 대한 좋은 설명을 찾았 습니다 .
API 키를 저장하는 솔루션은 다음과 같습니다.
- 별도의 키와 비밀을 사용하고, 키를 사용하여 레코드를 조회하고, 타이밍 안전 비교를 사용하여 비밀을 확인합니다. 이를 통해 사용자에게 키와 비밀을 다시 표시 할 수 있습니다.
- 별도의 키와 비밀을 사용하고, 비밀에 대해 대칭적이고 결정론적인 암호화를 사용하고, 암호화 된 비밀의 정상적인 비교를 수행합니다. 이를 통해 사용자에게 키와 시크릿을 다시 표시 할 수 있으며 타이밍에 안전한 비교를 구현하지 않아도됩니다.
- 별도의 키와 비밀을 사용하고 비밀을 표시하고 해시하고 저장 한 다음 해시 된 비밀의 일반적인 비교를 수행합니다. 이렇게하면 양방향 암호화를 사용할 필요가 없으며 시스템이 손상 될 경우 보안을 유지하는 추가 이점이 있습니다. 사용자에게 다시 비밀을 보여줄 수 없다는 단점이 있습니다.
- 단일 키를 사용 하여 사용자에게 한 번 보여주고 해시 한 다음 해시되거나 암호화 된 키의 일반적인 조회를 수행합니다. 단일 키를 사용하지만 사용자에게 다시 표시 할 수 없습니다. 시스템이 손상된 경우 키를 안전하게 유지하는 이점이 있습니다.
- 단일 키를 사용 하여 사용자에게 한 번 보여주고 암호화 한 다음 암호화 된 비밀을 정상적으로 조회합니다. 사용자에게 다시 표시 될 수 있지만 시스템이 손상되면 키가 취약 해집니다.
이 중 3이 보안과 편리함의 가장 좋은 균형이라고 생각합니다. 키를 발급받을 때 많은 웹 사이트에서 구현되는 것을 보았습니다.
또한 실제 보안 전문가를 초청하여이 답변을 비판합니다. 나는 이것을 또 다른 논의 포인트로 사용하고 싶었습니다.