이른바 「온라인 비밀번호 생성기」를 열고 생성을 누른 뒤, 개발자 도구의 Network 패널을 보세요. 요청 본문이나 쿼리에 방금 만든 문자열이 있다면 평문은 이미 기기를 떠난 겁니다. 이 단계는 브랜드 약속을 믿을 필요가 없습니다. 브라우저가 트래픽을 펼쳐 보여 줍니다.
암호화를 브라우저에서 하는 이유는 「탈중앙처럼 들리기」 때문이 아닙니다. 평문 노출 창을 기기로 압축하기 위해서입니다. 전송이 한 단계 줄고, 서버 로그가 한 벌 줄고, 운영자가 메모리 덤프를 잘못 읽을 기회도 줄어듭니다. 아래에서는 위협 모델, 직접 돌려 볼 수 있는 확인 절차, 그 한계를 정리합니다. PassAfer 도구는 이 원칙으로 설계되었습니다. 이 글은 제품 총람이 아니라, 「왜 민감 연산을 기본값으로 서버에 넘기면 안 되는지」 한 질문에만 답합니다.
서버 대행이 키우는 노출 창
평문 노출 창이란 평문(또는 이를 바로 복원할 수 있는 키)이 실제로 존재하는 지점입니다. 서버가 계산하면 그 창은 「제출을 누른 순간」으로 끝나지 않습니다. 사후에 지우기 어려운 사슬이 됩니다.
- 브라우저에서 오리진까지의 TLS 세션. 서버 프로세스가 보는 것은 복호화된 요청이지 암호문이 아닙니다.
- 리버스 프록시, WAF, APM, 오류 추적의 요청 본문 샘플링. HTTP 500 한 번이면 폼이 크래시 리포트에 들어갑니다.
- 애플리케이션 로그, 슬로 쿼리, 액세스 로그의 쿼리 문자열.
?key=에 키를 넣는 습관은 access log에 쓰는 것과 같습니다. - 데이터베이스, 오브젝트 스토리지, 임시 디스크, 백업과 원격 복사본.
- 운영·고객지원·침입자가 위 중 하나를 손에 넣는 시간. 「쓰고 바로 삭제」 약속은 이미 열린 창을 되돌리지 못합니다.
관할권과 하청은 「보지 않습니다」를 감사하기 어려운 문장으로 바꿉니다. 당신이 대조할 수 있는 것은 프로토콜과 트래픽이지, 상대 전산실의 내부 규정서가 아닙니다.
비밀번호 생성에서는 특히 아프습니다. 필요한 것은 아직 어떤 시스템에도 나타나지 않은 비밀입니다. 생성이 남의 랙에서 일어나면 첫 사본은 이미 당신 것이 아닙니다. 나중에 프로덕션 설정, CI 변수, 비밀번호 관리기에 붙여 넣어도 유출 지점에는 보이지 않는 노드가 하나 더 있습니다.
비밀번호 감사도 같습니다. 재사용 중인 비밀번호를 원격 「강도 검사」에 보내는 것은 가장 민감한 자격 증명을 제3자에게 넘기는 일입니다. 공개 유출 목록 조회는 k-anonymity 같은 프로토콜로도 만들 수 있습니다. PassAfer의 Password Audit는 더 단단한 제약을 택합니다. 검증 중인 비밀번호는 업로드하지 않고, 강도 추정과 상위 유출 목록 대조는 브라우저에서 끝냅니다. 확인할 것은 「저장하지 않는다고 주장한다」가 아니라, 요청에 그 문자열이 애초에 없다는 점입니다.
파일 암호화에서 「업로드 → 서버 암호화 → 다시 다운로드」를 하면 패스프레이즈와 파일 내용은 적어도 서버 메모리에 온전히 존재합니다. 로컬 스트리밍 암호화는 서버가 받을 평문을 주지 않습니다. 사진인지 디스크 이미지인지를 알 필요도 없습니다.
HTTPS가 곧 로컬 연산은 아닙니다
TLS가 막는 것은 경로상의 도청자이지, 맞은편 서버가 아닙니다. 서버가 암호를 계산하면 맞은편은 평문을 읽도록 되어 있습니다. 로컬 연산이 푸는 질문은 다릅니다. 맞은편은 이 재료를 보면 안 됩니다.
「로컬」이 가리키는 층
「로컬」은 슬로건이 되기 쉽습니다. 쪼개지 않으면 클라우드 드라이브의 「나만 볼 수 있음」도 클라이언트 사이드 암호화로 팔립니다.
클라우드 계정이 아니라, 이 기기의 프로세스
PassAfer가 말하는 로컬은 계산이 브라우저 탭에서 일어난다는 뜻입니다. 난수는 crypto.getRandomValues, 대칭 암호는 Web Crypto API입니다. 이 API는 보안 컨텍스트(HTTPS 또는 localhost)에서만 쓰이며 브라우저가 네이티브로 구현합니다. 키 재료는 수명이 짧은 CryptoKey에 있고 분석 필드로 나가지 않습니다. 결과는 복사, 내보내기, 디스크 저장이 가능합니다. 탭을 닫으면 메모리의 평문은 브라우저 수명을 따르며, 원격에 두 번째 사본이 남지 않습니다.
「나만 보이는 폴더에 파일을 넣는 것」과는 다릅니다. 오브젝트 스토리지는 기기에서 봉인한 뒤 암호문을 올리지 않는 한 평문을 읽는 경우가 많습니다. 로컬 우선이 묻는 것은, 사용 가능한 형태의 평문이 기기 밖에 한 번이라도 있었는가입니다.
알고리즘과 파일 한도는 대조할 수 있는 사실
초판 대칭 암호는 AES-256-GCM뿐입니다(인증 암호화. 암호문이 바뀌면 복호화가 실패합니다). 파일 암호화는 단일 파일을 스트림으로 처리하고, 한도 5 GB, 출력은 .lock(권장) 또는 .enc입니다. 긴 영상을 한 번에 메모리에 올릴 필요가 없습니다. 숫자는 요구사항에 적혀 있으며 형용사가 아닙니다. 화면에 미구현 알고리즘 전환이 보여도 제품 설명을 기준으로 삼습니다.
로컬은 「모든 도구가 공개」가 아닙니다
계산 위치와 로그인 권한은 별개입니다. 비로그인 방문자도 랜덤 문자와 패스프레이즈 생성, 복사, 내보내기를 쓸 수 있습니다. Password Audit, 프라이버시 도구, Burn-Link 생성, 파일 암호화, 비밀번호 저장소는 로그인 후 잠금 해제됩니다. 「로컬」을 「누구나 모든 도구를 쓴다」로 읽으면 권한 매트릭스와 충돌합니다.
| 기능 | 비로그인 | 민감 자료가 기본으로 업로드되는가 |
|---|---|---|
| 랜덤 / 패스프레이즈 생성 | 사용 가능 | 업로드하지 않음. 브라우저에서 생성 |
| 저장소에 추가 | 로그인 안내 | — |
| Password Audit | 로그인 안내 | 검증 비밀번호는 업로드하지 않음. 강도와 유출 목록은 로컬 |
| Clean Link / 마스킹 | 로그인 안내 | URL과 텍스트는 로컬 처리. analytics에 쓰지 않음 |
| Burn-Link 생성 | 로그인 안내 | 올라가는 것은 암호문 blob이지 원문이 아님 |
| Burn-Link 읽기 | 수신자에게 공개 | 키는 URL # 프래그먼트. HTTP로 서버에 가지 않음 |
| 파일 암호화 | 로그인 안내 | 파일과 패스프레이즈는 업로드하지 않음. 기기 내 스트림 AES-256-GCM |
Burn-Link만 서버에 잠시 보관이 필요하지만, 보관하는 것은 암호문입니다. 복호화 키는 URL의 # 뒤에 둡니다. 프래그먼트는 HTTP 요청에 실려 서버로 가지 않습니다. access log에는 보통 경로만 남습니다. 읽기 페이지는 수신자에게 공개합니다. 상대에게 먼저 가입을 시키면 일회성 비밀 공유가 성립하지 않습니다. 첫 열람 후 암호문은 설계대로 소각됩니다. 서버 제로 지식은 「아무것도 저장하지 않는다」가 아니라 「저장해도 열 수 없다」입니다. 이 글은 이 계약만 둡니다.
Network 패널로 비밀이 나갔는지 확인하기
슬로건은 스스로 증명하지 않습니다. 아래 절차는 신뢰 관계가 필요 없고, 브라우저에 딸린 개발자 도구면 충분합니다. 목표는 「지구상에 사이드 채널이 없다」를 증명하는 것이 아니라, 「한 번 클릭해 평문을 POST하는」 온라인 도구를 드러내는 것입니다.
로그인 없이 비밀번호 생성부터 시작합니다. 비밀번호 생성 페이지를 열고 로그아웃 상태를 유지합니다. 랜덤 문자와 패스프레이즈 모두 바로 생성되어야 합니다. 계정 통신과 「생성이 밖으로 나갔는지」를 분리해, 로그인 요청을 유출로 오인하지 않기 위해서입니다.
Network를 열고 Preserve log를 켭니다. Chrome / Edge / Firefox 모두 가능합니다. 먼저 Fetch/XHR, 이어서 전체 요청을 봅니다. Preserve log는 페이지가 이동해도 기록이 지워지지 않게 합니다. sendBeacon과 Service Worker가 만든 요청도 패널에 나타납니다.
알아보기 쉬운 비밀번호를 생성합니다. 길이를 조금 늘리고 메모장에 복사한 뒤, Network 검색창에 전체 문자열 또는 JS 소스에 우연히 안 나올 부분 문자열을 붙입니다.
URL, Query, Request Payload에 히트가 있는지 봅니다. 어떤 요청에도 그 부분 문자열이 없으면, 적어도 「생성」 클릭에서는 평문이 HTTP 내용으로 나가지 않은 것입니다. 정적 스크립트의 무관한 문자열은 대상이 아닙니다. 찾을 것은 방금 만든 그 한 줄입니다.
로그인 후 도구에도 같은 방법을 씁니다. Password Audit, 프라이버시 도구, 파일 암호화는 로그인이 필요합니다. 테스트 전용 가짜 비밀번호나 작은 파일로 다시 검색합니다. 감사는 검증 비밀번호를 원격으로 보내지 않고, 정리는 원문을 POST하지 않으며, 파일 암호화는 평문을 multipart로 올리지 않아야 합니다.
Burn-Link는 암호문과 프래그먼트를 봅니다. 생성(로그인 필요)에서 서버로 가는 것은 암호문이지, 입력한 원문이 아닙니다. 전체 링크에서 키는 # 뒤에 있습니다. 프래그먼트를 빼고 Network를 보면 요청 경로에 키가 없어야 합니다. 수신자는 읽기 페이지를 로그인 없이 엽니다.
이 절차가 증명하는 것과 증명하지 못하는 것
Network가 알려 주는 것은 이번 동작이 평문을 HTTP에 실었는지입니다. 동일 출처 스크립트가 메모리를 읽는 것, 악성 확장, 이미 XSS로 바뀐 페이지는 보이지 않습니다. 많은 「온라인 도구」를 드러내기에는 충분합니다. 형식 증명과 섞지 마세요.
반드시 로컬에 둘 것과, 예외를 말하는 방식
한 번 나가면 되돌릴 수 없는 재료는 기기에 둡니다. 새로 만든 비밀번호, 검증 중인 옛 비밀번호, 마스킹 전 원문, 파일 평문, 대칭 키입니다. 남의 로그에 들어가면 탭을 지워도 상대의 사본은 사라지지 않습니다.
기기를 떠나도 되는 것은 암호학적으로 서버에 쓸모없거나, 계정 체계 자체에 속하는 데이터입니다. Burn-Link 암호문 blob, 로그인에 필요한 사용자명과 로그인 비밀번호, 비밀이 없는 정적 자원입니다. 「로그인」과 「도구 평문 업로드」를 섞지 마세요. 로그인은 권한 단계입니다. 비로그인도 비밀번호를 생성할 수 있고, 감사·정리·Burn-Link 생성·파일 암호화·저장소는 로그인 후 열립니다. 로그인 자격 증명은 계정 경로를 타고, 「방금 만든 새 비밀번호가 올라갔는지」와는 다른 질문입니다.
파일 암호화의 출력은 디스크로 받는 .lock / .enc입니다. 그다음 클라우드 드라이브, USB, 메일로 나르는 것은 암호문 파일입니다. 암호문을 드라이브에 올려도 패스프레이즈와 원문은 그 스토리지에서 보이지 않습니다. 단, 패스프레이즈를 같은 전송이나 같은 메일의 평문에 쓰지 않았다는 전제입니다. 로컬 암호화가 바꾸는 것은 「저장소 관리자가 기본으로 사진을 연다」는 점이지, 물리적 보관 책임이 아닙니다.
프라이버시 도구(Clean Link와 Data Redaction)도 URL과 텍스트를 브라우저에서 처리합니다. UTM·광고 파라미터를 벗기고, 전화번호와 신분증처럼 보이는 문자열을 가린 뒤, 밖으로 보내기 전에 결과를 대조할 수 있습니다. 원문은 업로드되지 않고 analytics 이벤트 내용으로도 쓰이지 않습니다. 정리가 티켓 전문을 서버에 POST한 뒤 「마스킹됨」을 돌려주면 평문 창은 이미 서버에서 열린 것이고, 마스킹은 표시 층에 불과합니다.
브라우저 암호화의 경계와 오해
로컬 우선이 줄이는 것은 서버와 경로상의 노출입니다. 이미 악성코드가 장악한 PC는 구하지 않습니다. 경계를 기대치에 쓰는 편이 푸터에 AES 세 글자를 넣는 것보다 낫습니다.
페이지가 주입되면 알고리즘은 돕지 못합니다
XSS나 가로채인 스크립트는 입력란을 읽을 수 있습니다. Web Crypto가 지키는 것은 「정직한 페이지의 키 연산」이지, 「적대 스크립트가 이미 동일 출처에 있는」 상태가 아닙니다. 의존하는 것은 동일 출처 정책, 콘텐츠 보안 정책, 프론트엔드 공급망입니다. 「AES-256-GCM」을 보고 「그래서 XSS는 무효」라고 추론하지 마세요.
확장 프로그램, 사내 프록시, 어깨 너머
브라우저 확장과 SSL을 복호화하는 사내 프록시는 여전히 페이지 내용을 볼 수 있습니다. 회사 프록시가 루트 인증서를 넣으면 Network 패널이 보여주는 것은 그 프록시 너머의 세계입니다. 기기 분실, 화면 공유, 어깨 너머는 로컬 연산이 막지 못합니다. 엔드포인트 문제와 「서버가 평문을 가지면 안 된다」는 따로 다룹니다.
「업로드하지 않는다」는 「인터넷을 끊는다」가 아닙니다
페이지 자체, 스크립트, 로그인 요청은 나갑니다. 확인할 것은 민감 필드가 요청에 나타났는지이지, 랜선을 뽑는 것이 아닙니다. PassAfer는 검증 비밀번호, 정리 원문, 파일 내용을 분석 이벤트로도 보내지 않습니다. 이벤트에 비밀 자체를 넣지 않습니다.
능력을 넘어 쓰지 마세요
초판 알고리즘은 AES-256-GCM입니다. 화면의 전환 가능한 RSA나 아직 없는 국산 암호 옵션을 기대하지 마세요. Burn-Link 읽기 페이지를 로그인 필수로 쓰지 마세요. 서버가 평문이나 키를 볼 수 있다고 주장하지 마세요. 그것은 제품 사실과 반대입니다. 로컬 우선의 정직한 문장은, 민감 연산은 브라우저에서 끝나고, 평문·키·파일은 기본으로 업로드되지 않으며, Burn-Link 서버는 암호문만 잠시 보관한다는 것입니다.
직접 확인하려면 어디서 시작할지
「생성 한 번이 밖으로 나갔는지」만 먼저 알고 싶다면 비밀번호 생성기가 가장 맞습니다. 로그인 없이 랜덤 문자와 패스프레이즈가 기기에서 끝나고, 복사와 내보내기도 같습니다. Network를 열고 위 절차로 방금 만든 문자열을 검색하세요. 비용이 가장 낮고 「평문 노출 창」의 직감도 생깁니다.
흔한 대체 수단의 한계는 구체적입니다. 평문 메일과 메신저는 양쪽 기록, 서버 보관, 기기 백업에 키를 남깁니다. 클라우드 드라이브는 기기에서 먼저 암호화하지 않으면 제공자가 읽습니다. 키를 쿼리 파라미터에 넣으면 거의 항상 access log에 들어갑니다. 불편함의 문제가 아니라, 평문 창이 설계에 들어가 있습니다.
드라이브에 그대로 올리기 어려운 파일을 백업하려면 로그인한 뒤 파일 암호화를 쓰세요. 브라우저에서 AES-256-GCM 스트림 암호화, 단일 파일 5 GB까지, .lock 또는 .enc를 받습니다. 그 과정을 캡처해 원본 파일이 POST되지 않았는지 확인할 수 있습니다. 짧은 비밀을 동료에게 한 번만 넘기고 키가 서버 로그에 남기 싫다면 Burn-Link입니다. 로컬에서 암호화하고, 키는 # 뒤, 서버는 암호문만, 읽기 페이지는 상대 가입이 필요 없습니다. 이 글이 묻는 답은 하나입니다. 이 클릭 이후, 평문은 아직 당신 탭 안에 있습니까.
PassAfer의 문구는 「로컬 암호화, 어디서나 안전」입니다. 어디서나의 전제는, 계산이 지금 보고 있는 이 탭에서 일어나고, 브라우저에 이미 있는 패널로 그것을 한 번 대조할 수 있다는 점입니다.