LabHub
学习 学习路径 课程

银行现场的语言

证明是谁提高了额度

在 LabHub 中继续学习

한국어 원문으로 표시합니다.

목표

제자리 UPDATE 로 사라진 증거를 숫자로 드러내고, 정규 직렬화와 해시 사슬로 추가만 되는 감사 기록을 만든 뒤, 협력사 반출본의 변조를 찾아내고 HMAC 과 상관 ID 까지 붙여 증적 묶음을 냅니다.

왜 중요한가

감사에서 다투는 것은 값이 아니라 경위입니다. 현재 한도만 저장하는 시스템은 "누가 언제 왜 올렸나" 에 답할 수 없고, 그 답이 없으면 맞는 값도 설명할 수 없는 값이 됩니다. 해시 사슬은 기록을 고칠 수 없게 만드는 장치가 아니라 고치면 드러나게 만드는 장치입니다. 그래서 같은 사건이 늘 같은 바이트가 되는 정규 직렬화가 먼저 필요하고, 사슬을 통째로 다시 계산하는 위조를 막으려면 열쇠가 필요합니다. 채점기는 여러분이 적어 낸 해시를 믿지 않습니다. 원본에서 처음부터 다시 계산해 대조하고, 실행마다 다른 난수 벡터와 새로 만든 사슬로 여러분의 도구를 시험합니다.

단계

  1. 재료 스크립트를 /root/audit/gen_audit.py 로 저장해 실행하고 /root/audit/core.db/root/audit/vendor_chain.jsonl 을 만듭니다.
  2. 월초 스냅샷과 현재 한도를 대사해 사라진 증거를 /root/audit/lost.txt 에 changed·ticketed·untraceable·mismatched·raised_total 로 적습니다.
  3. /root/audit/canon.py 를 만들어 표준 입력의 JSON 줄마다 정규 직렬화한 바이트의 sha256 을 한 줄씩 냅니다.
  4. /root/audit/build_chain.py 로 app_log 400줄을 /root/audit/audit.db 의 audit_log 표에 해시 사슬로 옮깁니다.
  5. /root/audit/verify_chain.py 로 협력사 반출본을 검증하고 찾은 자리를 /root/audit/tamper.txt 에 적습니다.
  6. /root/audit/hmac.key/root/audit/mac_chain.py 로 사슬 위에 MAC 을 얹어 /root/audit/audit_mac.jsonl 을 만듭니다.
  7. 상관 ID 로 사건을 요청 단위로 되묶어 /root/audit/corr.txt 에 적습니다.
  8. /root/audit/evidence/manifest.json/root/audit/audit_report.md 로 증적 묶음을 냅니다.

참고

한도 스냅샷과 협력사 반출본 만들기

재료 스크립트를 /root/audit/gen_audit.py 로 저장해 실행하고 /root/audit/core.db/root/audit/vendor_chain.jsonl 을 만드세요.

먼저 /root/audit 를 만들고 그 안에서 python3 로 실행합니다. 표는 limit_opening, customer_limit, change_ticket, app_log 네 개이고 협력사 사슬은 399줄입니다.

제자리 UPDATE 가 지운 것을 세기

월초 스냅샷과 현재 한도를 대사해 /root/audit/lost.txt 에 changed·ticketed·untraceable·mismatched·raised_total 을 적으세요.

limit_opening 과 customer_limit 을 customer_id 로 이어 한도가 다른 고객을 셉니다. 그 중 change_ticket 이 없는 건이 아무도 설명할 수 없는 변경이고, 신청서의 new_limit 과 지금 값이 다른 건은 승인과 반영이 갈라진 자리입니다.

같은 사건을 늘 같은 바이트로 만들기

/root/audit/canon.py 를 만들어 표준 입력의 JSON 줄마다 정규 직렬화한 바이트의 sha256 을 한 줄씩 내게 하세요.

키 정렬, 공백 없는 구분자, 비ASCII 를 이스케이프하지 않는 UTF-8 세 가지가 전부입니다. 파이썬 json.dumps 의 sort_keys, separators, ensure_ascii 를 보세요. 중첩된 객체의 키도 함께 정렬되어야 합니다.

로그 400줄을 해시 사슬로 묶기

/root/audit/build_chain.py 로 app_log 를 /root/audit/audit.db 의 audit_log 표에 옮기고 prev_hash·entry_hash 를 채우세요.

컬럼은 seq·ts·corr_id·actor·action·target·amount·prev_hash·entry_hash 입니다. entry_hash 는 앞의 일곱 값과 prev_hash 를 묶은 객체를 정규 직렬화한 바이트의 sha256 이고, 첫 항목의 prev_hash 는 0 예순네 개입니다. 채점기는 core.db 에서 다시 계산해 대조합니다.

협력사 반출본에서 손이 탄 자리 찾기

/root/audit/verify_chain.py 로 vendor_chain.jsonl 을 검증하고 /root/audit/tamper.txt 에 content_bad_seq·link_bad_seq·missing_seq·total_lines 를 적으세요.

협력사 사슬의 해시는 prev_hash·seq·ts·actor·action·target·amount 를 세로막대로 이은 문자열의 sha256 입니다. 내용을 고친 자리는 그 줄의 entry_hash 가 어긋나고, 항목이 빠진 자리는 다음 줄의 prev_hash 가 어긋납니다. 두 증상은 다릅니다.

사슬 위에 열쇠를 얹기

/root/audit/hmac.key(16진수 64글자, 권한 600)와 /root/audit/mac_chain.py/root/audit/audit_mac.jsonl 을 만드세요.

열쇠는 openssl rand -hex 32 로 만들고 chmod 600 합니다. MAC 은 entry_hash·prev_mac·seq 세 키를 정규 직렬화한 바이트에 HMAC-SHA256 이고, 첫 줄의 prev_mac 은 0 예순네 개입니다. 열쇠 문자열이 기록 파일 안에 들어가면 안 됩니다.

사건 하나를 요청 하나로 되묶기

상관 ID 로 사건을 되묶어 /root/audit/corr.txt 에 no_corr·corr_groups·corr_of_seq140·target_of_seq140·events_in_group·actors_in_group 을 적으세요.

corr_id 가 빈 문자열인 줄은 나중에 어떤 요청의 일부였는지 복원할 수 없습니다. seq 140 은 협력사 반출본에서 내용이 어긋났던 바로 그 자리입니다. 그 사건의 corr_id 로 app_log 를 다시 훑어 몇 개 시스템을 거쳤는지 보세요.

증적 묶음과 보고서 내기

/root/audit/evidence/manifest.json 에 files·chain·verified·vendor_findings 를 담고, /root/audit/audit_report.md 에 다섯 절의 보고서를 쓰세요.

manifest 의 files 는 path·sha256·bytes 를 가진 객체 배열이고 audit.db·audit_mac.jsonl·vendor_chain.jsonl 이 모두 들어가야 합니다. chain 에는 rows·genesis·head 를 적습니다. 채점기는 적힌 해시를 실물에서 다시 계산해 대조합니다. 보고서 절 제목은 확인한 것, 증거가 사라진 자리, 사슬과 검증, 협력사 반출본, 권고 입니다.