암호화

암호화는 보안과 관련된 주제인 경우가 많지만 개인 정보 보호에서도 중요합니다. 암호화의 목표는 다른 사람이 암호화된 정보를 읽지 못하게 하는 것이지만 다른 사람이 사용자의 정보를 읽지 못하도록 하는 것은 정보를 비공개로 유지하는 한 가지 방법입니다. 사용자가 직접 수행할 수 있는 작업은 제한되어 있는 경우가 많지만, 사용자가 사용 중인 서비스의 제공자인 사용자의 도움을 받으면 암호화를 통해 사용자의 데이터를 유지할 수 있습니다.

사용자 개인 정보 보호를 위해 암호화를 적용하는 방법에는 전송 중 암호화, 저장 데이터 암호화, 엔드 투 엔드 암호화 등 세 가지가 있습니다.

  • 전송 중 암호화는 사용자와 사이트(즉, HTTPS) 간의 데이터 암호화를 유지합니다. 이미 사이트에 HTTPS를 설정했을 수 있지만, 사이트로 전송되는 모든 데이터가 암호화되고 있을까요? 리디렉션과 HSTS는 이러한 용도이며, 아래에 설명되어 있으며 HTTPS 설정의 일부여야 합니다.
  • 저장 데이터 암호화는 서버에 저장된 데이터의 암호화입니다. 이는 정보 유출로부터 보호하며 보안 입장에서 중요한 부분입니다.
  • 엔드 투 엔드 암호화는 클라이언트 데이터가 서버에 도달하기 전에 데이터를 암호화하는 것입니다. 이렇게 하면 개발자에게도 사용자 데이터가 보호됩니다. 사용자의 데이터를 저장할 수는 있지만 읽을 수는 없습니다. 이 방법은 구현하기 어렵고 모든 유형의 애플리케이션에 적합하지는 않지만, 본인 이외의 다른 데이터는 볼 수 없으므로 사용자 개인 정보 보호에 큰 도움이 됩니다.

HTTPS

첫 번째 이동은 HTTPS를 통해 웹 서비스를 제공하는 것입니다. 이 작업을 이미 완료했을 가능성이 매우 높지만 그렇지 않다면 중요한 단계입니다. HTTPS는 브라우저가 서버에서 웹페이지를 요청하는 데 사용하는 프로토콜인 HTTP이지만 SSL을 사용하여 암호화됩니다. 즉, 발신자 (사용자)와 수신자 (귀하) 간의 HTTPS 요청은 외부 공격자가 읽거나 방해할 수 없습니다. HTTPS 요청이 암호화되어 있으므로 읽거나 변경할 수 없기 때문입니다. 즉, 데이터가 사용자에게서 사용자에게 또는 사용자에게서 사용자에게 이동하는 동안 전송 중 암호화입니다. 또한 전송 중 HTTPS 암호화를 사용하면 사용자의 ISP 또는 사용자가 사용 중인 Wi-Fi 제공업체가 서비스와의 관계의 일환으로 사용자에게 보내는 데이터를 읽을 수 없습니다. 이는 서비스 기능에도 영향을 미칠 수 있습니다. 기존 JavaScript API를 사용할 경우 HTTPS를 통해 웹사이트를 제공해야 하는 경우가 많습니다. MDN에는 좀 더 포괄적인 목록이 있지만, 안전한 컨텍스트로 구동되는 API에는 서비스 워커, 푸시 알림, 웹 공유 및 웹 암호화, 일부 기기 API가 포함됩니다.

HTTPS를 통해 웹사이트를 제공하려면 SSL 인증서가 필요합니다. 이러한 파일은 Let's Encrypt를 통해 무료로 생성하거나 호스팅 서비스를 사용하는 경우 호스팅 서비스에서 제공할 수도 있습니다. 웹 서비스를 '프록시'하고 HTTPS는 물론 캐싱 및 CDN 서비스도 제공하는 서드 파티 서비스를 사용할 수도 있습니다. Cloudflare, Fastly 등 그와 같은 서비스의 수많은 예시가 있으며, 정확히 어떤 서비스를 사용해야 할지는 현재 인프라에 따라 달라집니다. 과거에는 HTTPS를 구현하는 데 부담이 되거나 비용이 많이 들 수 있었기 때문에 결제 페이지나 특히 안전한 출처에서만 HTTPS를 사용했었습니다. 하지만 무료로 제공되는 인증서, 표준 개선, 더 많은 브라우저 확산 덕분에 이러한 모든 장애물이 해결되었습니다.

의견을 제시하지

  • 모든 경우에 (선택한 방법) 서버에서 HTTPS를 사용 설정합니다.
  • Cloudflare와 같은 서버 앞에 프록시를 사용하는 것이 좋습니다. httpsiseasy.com/에서 자세히 알아보세요.
  • Let's Encrypt는 자체 Let's Encrypt SSL 인증서를 만드는 과정을 안내합니다.
  • 또는 OpenSSL을 직접 사용하여 자체 인증서를 만들어 원하는 인증 기관(CA)에서 서명하도록 합니다. HTTPS 사용 설정에서 자세한 방법을 확인할 수 있습니다.

비즈니스 장단점에 따라 접근 방식을 선택해야 합니다. 제3자가 SSL 연결을 관리하도록 하면 가장 쉽게 설정할 수 있으며 부하 분산, 캐싱, 분석과 같은 다른 이점이 있습니다. 하지만 그로 인해 제3자에게 제어 권한이 어느 정도 양도되고 제3자의 서비스에 대한 불가피한 의존이 발생하게 됩니다 (사용 중인 서비스와 트래픽 수준에 따라 결제 가능)

이전에는 인증서를 생성하고 CA에서 서명하도록 하는 것이 SSL 프로세스가 실행되었던 방식이지만, 제공업체가 지원하거나 서버 팀이 기술적으로 이를 충분히 능숙하게 사용할 수 있고 무료인 경우 Let's Encrypt를 사용하는 것이 더 쉬울 수 있습니다. 클라우드 호스팅보다 상위 수준의 항목을 사용하는 경우 제공업체가 서비스로 SSL을 제공하는 경우도 많으므로 확인해 볼 필요가 있습니다.

이유

보안은 개인 정보 보호 스토리의 일부입니다. 간섭으로부터 사용자 데이터를 안전하게 보호한다는 것을 입증하면 신뢰를 구축하는 데 도움이 됩니다. HTTPS를 사용하지 않으면 브라우저에 의해 사이트가 '안전하지 않은' 것으로 신고되며 한동안 문제가 지속됩니다. 기존 JavaScript API는 HTTPS 페이지 ('보안 출처')에서만 사용할 수 있는 경우가 많습니다. 또한 사용자의 웹 사용 시 ISP에 노출되지 않도록 사용자를 보호합니다. 이는 확실히 권장사항입니다. 현재 웹사이트에 HTTPS를 사용하지 않을 이유가 거의 없습니다.

브라우저에서 HTTP (비보안) 페이지를 표시하는 방법

Chrome 데스크톱 URL 경고 '안전하지 않음'
Chrome (데스크톱)
Firefox HTTP URL 경고
Mozilla Firefox (데스크톱)
Safari 데스크톱 HTTP URL 경고
Apple Safari (macOS 데스크톱)
Android 모바일 HTTP 경고
Chrome (Android 모바일)
Apple Safari iOS HTTP 경고
Apple Safari (iOS 모바일)

HTTPS로 리디렉션

사이트가 http: 및 https: URL에서 모두 사용 가능한 경우 모든 http URL 액세스를 https로 리디렉션해야 합니다. 이는 위의 이유 때문이며 사이트가 인기를 얻는 경우 whynohttps.com에 사이트가 표시되지 않습니다. 이를 수행하는 방법은 인프라에 따라 달라집니다. AWS에서 호스팅되는 경우 기본 또는 애플리케이션 부하 분산기를 사용할 수 있습니다. Google Cloud도 이와 유사합니다. Azure에서는 Front Door를 만들고, Express를 사용하는 노드에서 request.secure를 확인하고, Nginx에서 모든 포트 80을 포착하고 301을 반환하고, Apache에서는 RewriteRule을 사용합니다. 호스팅 서비스를 사용하는 경우 Netlify, Firebase, GitHub 페이지 등 HTTPS URL로의 리디렉션이 자동으로 처리될 가능성이 높습니다.

HSTS

HSTS는 'HTTP Strict-Transport-Security'의 줄임말로, 브라우저에서 HTTPS를 계속 사용하도록 잠그는 방법입니다. HTTPS로의 이전이 만족스럽거나 이미 완료했다면 발신 응답에 Strict-Transport-Security HTTP 응답 헤더를 추가할 수 있습니다. 이전에 사이트에 액세스한 적이 있는 브라우저에서는 이 헤더를 확인했다고 기록하며, 이후 HTTP를 요청하더라도 자동으로 이 사이트에 HTTPS로 액세스합니다. 이렇게 하면 위와 같이 리디렉션을 거치지 않습니다. 마치 브라우저가 HTTPS를 사용하도록 서비스에 대한 모든 요청을 자동으로 '업그레이드'하는 것과 같습니다.

마찬가지로, 페이지와 함께 Upgrade-Insecure-Requests 헤더를 제공할 수 있습니다. 이는 Strict-Transport-Security와는 다르지만 관련된 것입니다. Upgrade-Insecure-Requests: 1를 추가하면 이 페이지의 다른 리소스 (이미지, 스크립트)에 대한 요청은 링크가 http인 경우에도 https로 요청됩니다. 하지만 브라우저에서는 페이지 자체를 https로 다시 요청하지 않으며 브라우저가 다음에 기억하지 않습니다. 실제로 Upgrade-Insecure-Requests는 HTTPS 링크가 많은 기존 사이트를 변환하고 콘텐츠의 링크 URL을 변환하는 것이 어려운 경우에 유용하지만 가능한 경우 콘텐츠를 변경하는 것이 좋습니다.

HSTS는 주로 보안 기능으로, 이전에 HTTPS에 접속한 적이 있는 사용자를 위해 사이트를 HTTPS로 '잠금'합니다. 그러나 위와 같이 HTTPS는 개인 정보 보호에 적합하고 HSTS는 HTTPS에 좋습니다. 마찬가지로 모든 콘텐츠를 업데이트하는 경우 Upgrade-Insecure-Requests가 실제로 필요하지는 않지만, 사이트가 항상 HTTPS가 되도록 심층 방어를 추가하는 유용한'중괄호' 접근 방식입니다.

의견을 제시하지

발신 응답에 HSTS 헤더를 추가합니다.

Strict-Transport-Security: max-age=300; includeSubDomains

max-age 매개변수는 브라우저가 HTTPS 업그레이드를 기억하고 적용해야 하는 시간(초)을 지정합니다. 여기서는 300초, 즉 5분으로 설정합니다. 결국에는 이를 2년인 6,3072,000으로 설정하게 되고 hstspreload.org에서 권장하는 수치이지만 문제가 있는 경우 복구하기가 매우 어렵습니다. 따라서 처음에는 낮은 숫자 (300)로 설정하고 테스트를 통해 손상된 항목이 없는지 확인한 다음 단계별로 숫자를 늘리는 것이 좋습니다.

발신 응답에 Upgrade-Insecure-Requests 헤더를 추가합니다.

Upgrade-Insecure-Requests: 1 Content-Security-Policy: upgrade-insecure-requests

엔드 투 엔드 암호화

사용자 데이터를 비공개로 유지하는 좋은 방법은 자신을 포함하여 다른 사람에게는 표시하지 않는 것입니다. 이는 사용자의 신뢰를 얻는 데 많은 도움이 됩니다. 사용자의 데이터가 없다면 사용자가 원하지 않는 일에는 어떤 것도 할 수 없다는 것이 분명합니다. 이렇게 하는 한 가지 방법은 모든 데이터를 클라이언트 측에 저장하여 사용자 데이터가 기기를 전혀 벗어나지 않도록 하는 것입니다. 이 방법은 효과적이지만 순수한 클라이언트 측 애플리케이션에는 제한사항이 있습니다. 브라우저 데이터 저장소의 크기가 제한될 수 있으며 일부 브라우저에서는 경고가 거의 또는 전혀 표시되지 않을 수 있습니다. 또한 노트북과 휴대전화와 같은 두 기기에서 데이터에 액세스하는 것도 어렵거나 불가능합니다. 이러한 이유로 정상적으로 서버에 데이터를 전송하되 사용자에게만 알려진 키로 데이터를 암호화하여 서버가 데이터에 액세스할 수는 없지만 (해독할 수 없으므로) 저장할 수는 있도록 하는 것이 유용할 수 있습니다.

기본 원리

이 접근 방식은 메시지 애플리케이션에서 자주 사용되며 '엔드 투 엔드 암호화' 또는 'e2e'라고 합니다. 이렇게 하면 서로의 키를 알고 있는 두 사람이 메시지를 서로 암호화하고 복호화하고 메시지 제공업체를 통해 메시지를 보낼 수 있지만 메시지 제공자 (키가 없는)는 메시지를 읽을 수 없습니다. 대부분의 애플리케이션은 메시지 앱이 아니지만 클라이언트 측 데이터 저장소만을 사용하는 두 가지 접근 방식 및 클라이언트에 알려진 키를 사용한 데이터 암호화라는 두 가지 접근 방식을 결합하여 데이터를 로컬에 저장하고 암호화된 데이터를 서버에 전송할 수도 있습니다. 이 접근 방식에는 한계가 있다는 점을 인지하는 것이 중요합니다. 모든 서비스에서 이 방식을 사용할 수 있는 것은 아니며, 특히 서비스 제공업체로서 사용자가 저장하는 항목에 액세스해야 하는 경우에는 이를 사용할 수 없습니다. 이 시리즈의 2부에서 설명한 것처럼 데이터 최소화 원칙을 준수하는 것이 가장 좋습니다. 가능하다면 데이터 수집은 가급적 피하세요. 사용자에게 데이터 스토리지가 필요하지만 개발자가 서비스 제공을 위해 해당 데이터에 액세스할 필요가 없다면 엔드 투 엔드 암호화가 유용한 대안입니다. 서비스를 제공하기 위해 사용자가 저장하는 항목을 볼 수 있어야 하는 서비스를 제공하는 경우 엔드 투 엔드 암호화는 적합하지 않습니다. 하지만 암호화하지 않으면 웹 서비스의 클라이언트 측 JavaScript가 서버로 전송하는 모든 데이터를 암호화하고 수신된 데이터를 복호화하도록 할 수 있습니다.

예: Excalidraw

Excalidraw는 이를 수행하는 방법과 블로그 게시물에서 방법을 설명합니다. 이 앱은 서버에 그림을 저장하는 벡터 그리기 앱으로, 무작위로 선택한 키로 암호화됩니다. Excalidraw가 비교적 적은 코드로 이 엔드 투 엔드 암호화를 구현할 수 있는 이유 중 하나는 이제 암호화 라이브러리가 모든 최신 브라우저에서 지원되는 JavaScript API 집합인 window.crypto를 사용하여 브라우저에 빌드되기 때문입니다. 암호화는 어려운 일이며 알고리즘을 구현하려면 극단적인 사례가 많이 발생합니다. 여기서 복잡한 작업을 브라우저가 처리하도록 하면 웹 개발자가 암호화에 더 쉽게 액세스할 수 있으므로 암호화된 데이터를 통해 개인 정보 보호를 더 쉽게 구현할 수 있습니다. Excalidraw가 작성한 글에서 설명했듯이 암호화 키는 URL 프래그먼트의 일부이므로 클라이언트 측에 유지됩니다. 브라우저에서 URL https://example.com/path?param=1#fraghere를 방문하면 URL의 경로 (/path)와 매개변수 (param=1)는 서버(example.com)로 전달되지만 프래그먼트 (fraghere)는 전달되지 않으므로 서버에서는 알 수 없습니다. 즉, 암호화된 데이터가 서버를 통과하더라도 암호화 키는 암호화되지 않으므로 데이터에 엔드 투 엔드 암호화가 적용되므로 개인 정보가 유지됩니다.

제한사항

사용자 데이터를 암호화하는 이 접근 방식이 완벽한 것은 아닙니다. 이는 사용자를 위한 개발자의 신뢰에 기여하지만 이를 완전히 대체할 수는 없습니다. 사용자는 여전히 서비스를 신뢰해야 합니다. 언제든지 클라이언트 측 JavaScript를 데이터를 암호화하지 않는 미묘하게 유사한 자바스크립트로 바꿀 수 있기 때문입니다. 사용 중인 웹사이트가 이러한 작업을 수행했는지 여부를 사용자가 감지할 수는 있지만, 이는 매우 어렵습니다. 실제로 사용자는 서비스를 악의적으로 판독하지 못한다고 믿고 제공자가 악의적이지 않음을 보여주지 않을 것이라는 사실을 신뢰할 수 있어야 합니다.

또한 엔드 투 엔드 암호화의 목표 중 하나는 사이트 소유자가 데이터를 읽을 수 없도록 하는 것임을 기억해야 합니다. 이는 개인 정보 보호에 도움이 되지만 문제가 발생한 경우 도움을 줄 수 없다는 의미이기도 합니다. 기본적으로 엔드 투 엔드 암호화를 사용하는 서비스는 암호화 키에 대한 책임이 사용자에게 있습니다. (명확하거나 명백하지 않을 수도 있지만, 누군가 키를 보유해야 하며, 데이터가 비공개로 유지된다면 사용자가 다른 것이 아닙니다.) 해당 키를 분실하면 어떻게 할 수 있는 것이 없고, 해당 키로 암호화된 모든 데이터도 손실될 수 있습니다. 여기에는 개인 정보 보호와 사용성 사이에서 세밀한 균형이 필요합니다. 암호화를 사용하여 모든 사용자로부터 데이터를 비공개로 유지하는 동시에 사용자가 안전한 방식으로 자체 키를 관리하는 암호화 전문가가 될 필요가 없도록 해야 합니다.

저장 데이터 암호화

사용자의 전송 중인 데이터를 암호화하는 것뿐만 아니라 서버에 저장한 데이터도 암호화하는 것도 중요합니다. 이렇게 하면 저장된 데이터에 무단으로 액세스하는 사람이 암호화된 데이터를 갖게 되어 복호화할 수 있는 키를 가지게 되므로 정보 유출을 방지하는 데 도움이 됩니다. 저장 데이터 암호화에는 사용자가 추가하는 암호화와 클라우드 스토리지 제공업체가 추가하는 암호화 (클라우드 스토리지 제공업체를 사용하는 경우)라는 두 가지 상호 보완적인 방식이 있습니다. 스토리지 제공업체 암호화는 소프트웨어를 통한 정보 유출로부터 강력한 보호 기능을 제공하지는 않지만 (스토리지 제공업체 암호화는 일반적으로 서비스 사용자에게 투명하기 때문) 제공업체의 인프라에서 발생하는 침해를 방지하는 데 도움이 됩니다. 대부분의 경우 간단하게 사용 설정할 수 있으므로 고려해 볼 필요가 있습니다. 이 분야는 빠르게 변화하므로 보안팀 (또는 팀의 보안 전문 엔지니어)이 이에 대해 조언하는 것이 가장 좋지만, 모든 클라우드 스토리지 제공업체는 Azure Storage, Google Cloud Storage를 설정하는 방식으로 블록 스토리지 Amazon S3에 대한 저장 데이터 암호화, 데이터베이스 데이터 스토리지 AWS RDS, Azure SQLGoogle Cloud SQL{/1에 대한 기본 데이터 암호화 기능을 제공합니다. 클라우드 스토리지 제공업체를 사용하는 경우 제공업체에 문의하세요. 저장 데이터의 암호화를 직접 처리하여 정보 유출로부터 사용자 데이터를 보호하는 것은 더 어렵습니다. 암호화 키를 안전하게 관리하고 공격자에게 제공하지 않고도 코드에 제공할 수 있도록 하는 물류가 까다롭기 때문입니다. 이 수준의 보안 문제에 대해서는 이곳에서 조언을 얻는 것이 가장 좋습니다. 보안에 능통한 엔지니어나 전담 팀이나 외부 보안 대행사에 문의하세요.