편집 : 원래 대답은 다음과 같습니다 - ... IMO 읽기,하지만 타이밍 공격에 대해 여전히 가치가 당신이 참조
페이지는 컴파일러 최적화에 대한 몇 가지 흥미로운 점을 제공합니다.
: 당신은 두 바이트 배열은 같은 길이 될 것입니다 알고있는 점을 감안하면
이 같은 뭔가를 시도 할 수 있습니다 (길이가 다른 경우 체크섬의
크기 가정, 특히 비밀되지 않고 즉시 반환 할 수 있습니다)
public static bool CompareArraysExhaustively(byte[] first, byte[] second)
{
if (first.Length != second.Length)
{
return false;
}
bool ret = true;
for (int i = 0; i < first.Length; i++)
{
ret = ret & (first[i] == second[i]);
}
return ret;
}
이제는 모든 입력에 동일한 시간이 걸리지 않습니다. 두 배열이 둘 다 L1 캐시에있는 경우 주 메모리에서 페치해야하는 경우보다 빠를 가능성이 큽니다. 그러나 보안 측면에서 중요한 문제가 발생하지는 않을 것으로 생각됩니다.
괜찮습니까? 누가 알아. 서로 다른 프로세서와 다른 버전의 CLR은 두 피연산자에 따라 &
작업에 서로 다른 시간이 걸릴 수 있습니다. 기본적으로 이것은 참조한 페이지의 결론과 동일합니다. 이는 휴대용 방식으로 얻는 것만 큼 좋지만 실행하려고하는 모든 플랫폼에서 유효성 검사가 필요하다는 것입니다.
적어도 위 코드는 비교적 간단한 조작 만 사용합니다. 어떤 경우에는 부적절한 최적화 작업이있을 수 있으므로 개인적으로 LINQ 작업을 사용하지 않아야합니다. 나는이 경우에 이이 될 것이라고 생각하지 않거나 패배하기 쉽습니다. 적어도 은 그들에 대해을 생각해야합니다. 거기에 대한 :)
원래 대답을
걱정 "전용"JIT 컴파일러 및 프로세서 최적화를 떠나 - 위의 코드와 함께, 소스 코드와 IL 사이에 적어도 상당히 밀접한 관계가있다 이 중 하나의 중요한 문제점 : 체크섬을 제공하려면 UTF-8로 인코딩 된 형식이 체크섬과 동일한 문자열이 있어야합니다. UTF-8로 인코딩 된 텍스트를 나타내지 않는 많은 바이트 시퀀스가 있습니다. 기본적으로 UTF-8을 사용하여 텍스트로 임의의 바이너리 데이터를 인코딩하려는 것은 좋지 않습니다.
는 Base64로, 다른 한편으로는,이를 위해 기본적으로 설계입니다 : 한편
static bool VerifyIntegrity(string secret, string checksum, string data)
{
// Verify HMAC-SHA256 Checksum
byte[] key = Encoding.UTF8.GetBytes(secret);
byte[] value = Encoding.UTF8.GetBytes(data);
byte[] checksumBytes = Convert.FromBase64String(checksum);
using (var hmac = new HMACSHA256(key))
{
byte[] expectedBytes = hmac.ComputeHash(value);
return checksumBytes.SequenceEqual(expectedBytes);
}
}
대신 바이트 배열에 SequenceEqual를 사용하여, 당신 수 Base64로 인코딩 실제 해시, 일치하는지 확인하십시오 :
static bool VerifyIntegrity(string secret, string checksum, string data)
{
// Verify HMAC-SHA256 Checksum
byte[] key = Encoding.UTF8.GetBytes(secret);
byte[] value = Encoding.UTF8.GetBytes(data);
using (var hmac = new HMACSHA256(key))
{
return checksum == Convert.ToBase64String(hmac.ComputeHash(value));
}
}
프레임 워크 내에서 더 잘 알지 못합니다. 처음에는 동일한 길이를 검사하는 배열 (또는 일반 ICollection<T>
구현)에 대해 특수화 된 SequenceEqual
연산자를 작성하는 것이 그리 어렵지는 않지만 해시가 짧다는 점을 고려하면 걱정하지 않을 것입니다. 당신이 SequenceEqual의 타이밍에 대해 걱정하는 경우
유효 포인트가 있지만 타이밍 공격 각도가 완전히 누락 된 것 같습니다. –
@Henk : "나는 이것이 약하다는 것을 알고 있지만, 나는 그 부분을 무시하고있다"고 오해한다. 편집 할 것입니다. –
@ 존 : 내 질문에 대한 철저한 답변을 주셔서 감사합니다. 기본적인 프로파일 링을했는데 Windows 7/Server 2008에서 'CompareArraysExhaustively'가 완벽하게 수행됩니다. –