데이터베이스에서 이름이 유출되어도 개인 식별은 불가능한, 업무에 활용 가능한 암호화 구조
요약
개인정보 유출 위험을 줄이기 위해 이름 가림 처리를 했으나, 실제 업무(제복 배포 등)에서는 전체 이름 사용이 필수적이라는 문제에 직면했습니다. 이 글은 '데이터베이스에서 이름을 제거'하는 보안 목표와 '업무상 전체 이름 사용'이라는 현실적 요구 사이의 충돌을 해결한 경험과 암호화 구조를 제시합니다.
핵심 포인트
- 보안 강화를 위해 가림 처리를 했으나, 실제 업무 흐름에 마비가 발생함.
- 개인정보 보호와 업무 연속성을 동시에 확보하는 것이 핵심 과제였음.
- 이름 복구는 세 가지 형태의 자료(암호문 등)를 분산 보관하고 비밀번호로 제어합니다.
- 생년월일 자체도 DB에서 삭제하여 본인 확인에 활용하지 않도록 설계했습니다.
※본 기사는 Zenn의 글을 전재합니다.
저는 의료기관 사무직으로서 직원들의 제복을 신청하는 웹 애플리케이션(스프레드시트 + Google Apps Script)을 만들고 운영하고 있습니다.
2년 차 검토 과정에서 보안 문제 지적을 받아 직원 이름은 가림 처리했습니다. 데이터베이스에 읽히는 이름을 두지 않겠다는 판단이었습니다.
그 결과, 업무가 마비되는 상황이 발생했습니다. 이 글은 그 경험을 바탕으로 '이름을 두지 않는 것'과 '전체 이름으로 업무를 수행하는 것'을 양립시키는 과정에 대한 내용입니다. 암호화 부분은 아직 시험 운영 중입니다.
직전 담당자로부터 인계받은 1년 차 시스템에서는 스프레드시트에 직원들의 **성명과 후리가나(발음)**가 그대로 들어가 있었습니다.
스프레드시트는 간편한 반면, 공유 설정을 한 번만 잘못해도 내용 전체가 노출될 수 있습니다. 최근에는 AI 도구에 드라이브나 시트를 읽게 하는 연결도 늘어나면서, '어디에서 읽힐 수 있는지'를 사람이 파악하기 어려워지고 있습니다.
그래서 이름을 첫 글자와 마지막 글자만 남긴 가림 처리로 저장하기로 했습니다.
| 원 이름 | 저장 형태 |
|---|---|
| 야마다 타로 (山田 太郎) | 야***로 (山**郎) |
| 사토 하나코 (佐藤 花子) | 사***코 (佐**子) |
이때, 후리가나는 제거했습니다. 후리가나가 남아 있으면 한자를 가렸더라도 이름이 거의 파악될 수 있기 때문입니다. '야***로'와 '야마다 타로(ヤマダ タロウ)'가 나란히 있으면, 가림 처리의 의미가 없어집니다.
같은 가림 처리가 되는 사람은 직원 번호로 구분합니다.
여기까지는 순조롭게 진행된 것처럼 보였습니다.
문제가 된 것은 제복을 사람에게 전달하는 상황이었습니다.
제복은 부서별로 모아서 도착하고, 부서 담당자가 한 명씩 나눠줍니다. 이때 배포 목록이 '야로', '사코'로는 현장에서 누구에게 줘야 할지 알 수 없습니다. 직원 번호를 병기하더라도, 번호만으로 동료를 기억하는 사람은 없습니다.
거점(拠点)에 따라서는 업체에 개인별 주문 목록 (1명당 1행, 전체 이름)을 보내는 방식으로 운영되었습니다. 가림 처리로는 주문 자체가 불가능했습니다.
가림 처리는 원래대로 되돌릴 수 없습니다. 후리가나도 버렸습니다. 필요할 때마다 인사 명부를 열어 대조하는 수작업이 남았습니다. 지키기 위해 가린 것이 오히려 명부를 여는 횟수를 늘리고 있었습니다.
즉, '데이터베이스에 읽히는 이름을 두지 않겠다'와 '업무에서 전체 이름을 사용하겠다'가 정면으로 충돌한 것입니다.
최종적으로, 한 사람의 이름을 세 가지 형태로 갖기로 했습니다.
| 열 | 내용 | 볼 수 있는 사람 |
|---|---|---|
| 가림 처리 | 야***로 | 누구나 (일상 화면/목록) |
| ... |
- 일상 신청 화면이나 목록은, 가림 처리 상태로 -
배포 목록이나 주문 목록을 만들 때만 관리자가 비밀번호를 입력하여 브라우저 내에서 이름을 복원 - 본인이 자신의 신청 내용을 조회할 때는 생년월일을 입력하여 '해당 생년월일로 이름이 복원되었는지'로 본인 확인. 생년월일 자체는 데이터베이스에서 삭제했습니다.
이름을 복구하는 재료는 세 군데에 나누어 보관하고 있습니다.
| 자료 | 보관 장소 |
|---|---|
| 암호문 | 스프레드시트 |
| ... | |
| 시트를 복사하거나, 실수로 공유하더라도, AI 연결을 통해 읽히더라도 보이는 것은 가림 처리와 읽을 수 없는 문자열뿐입니다. 암호화 메커니즘 자체는 다른 글(비밀번호를 변경하면 암호화된 데이터는 어떻게 되는가. 전체 재작업 없이 '열쇠를 감싸는' 구조)에 작성했습니다. |
암호화를 설계하기 전에, 로그인 없이 열 수 있는 화면이 무엇을 브라우저로 보내는지를 확인했습니다.
신청 화면은 URL만 알면 누구나 열 수 있습니다. 부서를 선택하면 해당 부서 직원의 목록이 나옵니다. 만약 여기서 전체 이름을 보여줬다면, 시트를 아무리 암호화해도 화면에서 명부가 유출될 수 있습니다.
그래서 로그인 없는 화면은 가림 처리만 하도록 했습니다. 전체 이름이 나오는 것은 비밀번호로 확인한 관리자와 생년월일로 확인한 본인뿐입니다.
항목을 암호화하기 전에, 로그인 없는 화면이 무엇을 제공하는지 보는 것이 중요합니다.
전체 이름이 포함된 Excel이나 PDF를 만들 때, 처음에는 작업용 임시 파일을 드라이브에 두었습니다. 잊어버리고 삭제하지 않으면, 그곳에 명부가 통째로 남게 됩니다.
지금은 임시 파일을 완전히 지운 후, 드라이브에 저장하지 않고 브라우저로 직접 반환하고 있습니다. 명부를 가져오기 전에 찍는 백업(숨김 시트)도 가림 처리한 후에 저장합니다. 보호해야 할 장소는 본체 시트만은 아니었습니다.
암호문이 있다면 가림 처리는 필요하지 않을까 생각했던 적도 있습니다. 결국, 남겨두었습니다.
평소 화면이나 목록에서 '대략 누가'인지는 아는 것만으로도 업무에 도움이 됩니다. 매번 비밀번호를 입력해서 이름을 복원하는 것은 배포 리스트를 만들 때 정도면 충분합니다. 평소에는 가림 처리하고, 필요할 때만 전체 이름이라는 단계를 두면서 보호와 사용 용이성의 균형을 맞출 수 있었습니다.
이름과는 별개의 이야기지만, 같은 검토에서 발견한 것이 있습니다.
지점별로 회계가 따로인데도 발주 집계가 전 지점을 합쳐서 만들고, 재고도 지점을 구분하지 않고 차감하고 있었습니다. 재고를 가지고 있는 곳은 단 하나의 지점뿐입니다.
지금은 어떤 양식도 지점을 선택해야만 생성되도록 하고, 재고는 그 재고를 가진 지점의 집계로만 차감합니다. 배포 리스트도 전 직종・전 품목을 한 장에 나열하던 것을 중단하고, 부서별 시트로 나누었으며, 해당 부서에서 신청이 있는 품목 열에만 두었습니다. 배포 단위로 시트를 분리하니 가로로 길어지지 않습니다.
- 이름을 가림 처리했더니,
배포와 주문이라는 '사람에게 전달하는' 업무가 멈췄습니다. - 가림 처리는 유지하되,
관리자용과 본인용의 두 가지 암호문을 추가하여, 필요할 때만 전체 이름으로 복원할 수 있도록 했습니다. - 후리가나(읽는 법)는 삭제합니다. 생년월일은 지웁니다. 이름을 복원하는 재료를 3군데로 나눕니다. - 암호화하기 전에,
로그인 없이 화면이 무엇을 배포하고 있는지를 확인합니다. - 임시 파일・백업・내보내기에도 이름은 남아 있습니다. 거기까지 지웁니다.
'개인정보를 남기지 않는다'는 것을 목표로만 하면 업무가 망가집니다. 누가, 어떤 상황에서, 어디까지 읽을 수 있는지부터 역으로 결정하면, 양립할 수 있는 형태가 보이기 시작했습니다.
- frontmatter에
published: true
를 적었기 때문에, zenn_publish.js
(150행目)이 승인 전에 commit → User가 Gemini 기사의 push를 했을 때 함께 공개되었습니다 - User 판단 = 이대로 공개 (2026-10-14). 공개 버전은 vault 최신 버전과 본문 차이 0을 확인
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기