캔버스 핑거프린팅 설명: 똑같은 브라우저인데 왜 픽셀이 다르게 그려질까

캔버스 핑거프린팅은 대부분의 사람이 들어 봤지만 설명할 수 있는 사람은 가장 적은 기법입니다. 아이디어는 간단합니다. 브라우저에 무언가를 그리게 하고, 픽셀을 읽어 와서, 해시합니다. 흥미로운 부분은 애초에 컴퓨터마다 픽셀이 왜 다른가입니다.
그리기
핑거프린팅 스크립트는 화면 밖 <canvas>를 만들고 2D 컨텍스트를 가져온 뒤 짧은 순서로 그립니다. 채워진 사각형, 지정한 글꼴의 텍스트, 어쩌면 그라디언트, 곡선, 이모지까지. 그런 다음 toDataURL()이나 getImageData()를 호출해 결과를 읽고 그 바이트를 해시에 통과시킵니다. 출력은 71ae464e 같은 짧은 문자열이며, 이 문자열이 바로 “캔버스 해시”입니다.
그리기에는 비밀이 전혀 없고, 페이지가 이미 설명할 수 없는 어떤 것도 GPU로 보내지 않습니다. 정보는 명령이 아니라 렌더링에 있습니다.
픽셀이 달라지는 이유
변화의 주된 원천은 텍스트입니다. 글리프를 렌더링하는 데는 실제로 선택된 글꼴 파일(대체 글꼴은 운영체제마다 다릅니다), 힌팅과 안티앨리어싱 전략(그레이스케일인지 서브픽셀인지, 서브픽셀 순서는 무엇인지), 래스터라이저(FreeType, DirectWrite, CoreText 또는 브라우저 자체의 것), 그리고 합성을 GPU가 했는지 CPU가 했는지가 관여합니다. 이 각각이 가장자리 픽셀을 조금씩 다르게 만듭니다. “e”의 가장자리에 있는 밝은 회색 픽셀 하나만 달라져도 해시가 완전히 바뀝니다.
그라디언트와 곡선이 변화를 더합니다. 그래픽 드라이버와 안티앨리어싱 경로가 다르면 중간값을 반올림하는 방식이 다릅니다. 그 결과 브라우저 버전은 같아도 GPU, 드라이버, 운영체제가 다른 두 컴퓨터는 대체로 다른 해시를 만들고, 같은 컴퓨터는 매번 같은 해시를 만듭니다. 안정적이면서 다양하다는 것, 바로 트래커가 원하는 조건입니다.
해시가 사이트에 알려 주는 것
해시 자체는 누구인지에 대해 아무것도 알려 주지 않습니다. 이 브라우저가 이 그림을 이렇게 렌더링한다는 것, 그리고 그것이 어떤 컴퓨터 집단에 해당한다는 것만 알려 줍니다. 중요한 것은 그 집단의 크기입니다. 내장 그래픽과 기본 글꼴을 쓰는 흔한 노트북은 많은 다른 컴퓨터와 해시를 공유합니다. 특이한 구성은 거의 유일할 수 있습니다. 화면 크기, 언어 목록, 렌더러 문자열과 결합하면 흔한 해시조차 희귀한 조합의 일부가 됩니다.
브라우저는 이에 어떻게 대응하는가
Firefox는 resist-fingerprinting을 켜면 빈 캔버스나 무작위 캔버스를 반환하고 캔버스 접근에 대해 허용 여부를 물을 수 있습니다. Brave는 캔버스 읽기에 작은 무작위 변형을 더해 해시가 사이트와 세션마다 바뀌게 합니다. Safari는 보이는 글꼴을 제한하고 일부 읽기를 제약합니다. Chromium 자체는 캔버스를 무작위화하지 않으며, 이를 기반으로 핑거프린트를 제어하려는 브라우저들은 각자의 패치로 처리하는데 그 패치의 품질은 제각각입니다.
노이즈는 공짜가 아닙니다. 방문할 때마다 바뀌는 캔버스 해시는 그 자체가 신호입니다. 실제 브라우저는 그렇게 동작하지 않기 때문입니다. 격리된 브라우저 프로필에 더 나은 전략은 그럴듯하면서 일관된 해시입니다. 그러면 한 시간마다 다른 컴퓨터가 아니라 하나의 평범한 컴퓨터처럼 보입니다.
진단 도구가 보여 주는 것
PowerScan은 자체적으로 작은 이미지를 그려 그 해시를 보여 줍니다. 이를 업로드하지 않으며, 값은 내 탭 안에만 존재합니다. 새로고침해도 해시는 동일해야 합니다. 그렇지 않다면 브라우저의 무언가가 노이즈를 주입하고 있다는 뜻이며, 그 프로필을 믿고 쓰기 전에 알아 둘 가치가 있습니다.


