0x인가 0s인가 — ipsec.secrets의 PSK 형식 읽기
같은 공유 비밀이라도 따옴표 안의 리터럴, 0x 뒤의 십육진수, 0s 뒤의 Base64로 쓸 수 있습니다. 접두사를 잘못 붙이면 협상이 아니라 인증이 실패합니다.
한 클라이언트는 공유 키로 인증에 성공하고 다른 쪽은 거부하는데, 붙여 넣은 문자는 양쪽에서 똑같아 보인다. 아마 같은 문자일 것이다. 차이는 파일이 그 문자에 어떤 디코딩 규칙을 적용하느냐에 있다. 따옴표로 묶은 문자열은 그대로 취급되고, 0x 로 시작하는 토큰은 십육진수로 읽히며, 0s 로 시작하는 토큰은 Base64로 읽힌다. 세 가지 표기 중 의도한 의미를 갖는 것은 하나뿐이므로, 고치는 일은 대개 더 나은 비밀번호가 아니라 변환이다.
증상은 암호가 아니라 인코딩을 가리킨다
양 끝이 서로 다른 바이트를 들고 있을 때, 협상은 그대로 성공하고 증명이 그 뒤에 실패한다. 그러면 로그는 알고리즘 불일치가 아니라 무결성 또는 HMAC 실패를 기록한다. 제안이 선택되었고 인증 단계만 맞지 않았기 때문이다. 그 줄은 비밀의 모양을 언급하지 않는다.
단계가 단서다. 선택된 제안 뒤에 오는 실패는 양쪽이 키 자료만 빼고 모두 합의했다는 뜻이고, «제안이 선택되지 않음»은 정책이나 암호 모음 쪽 문제다. 비밀번호가 맞아 보이는데 무결성 검사가 실패하는 것은 인코딩 불일치가 겉으로 드러난 모습이다.
하나의 비밀, 파일이 읽는 세 가지 방법
네 바이트 값 key1 에 대해 십육진수와 Base64는 같은 바이트의 두 가지 재인코딩이며, 앞의 문자만이 파서에게 어느 쪽을 들고 있는지 알려 준다. swanctl 자격 증명도 같은 관례를 따르므로, 두 인터페이스 사이로 옮긴 값은 접두사가 함께 이동해야만 의미를 유지한다.
10.20.0.5 %any : PSK "key1"
10.20.0.5 %any : PSK 0x6b657931
10.20.0.5 %any : PSK 0sa2V5MQ==
그 블록에서 가장 시간을 잡아먹는 것은 두 가지 세부다. 십육진수 숫자는 대소문자를 모두 받아들이므로 0x6b657931 과 0x6B657931 은 같은 값이지만, 홀수 개의 문자는 거부되지 않고 조용히 잘못 읽혀 잘린 지점 뒤의 모든 바이트가 밀린다. Base64 패딩은 값의 일부이므로 끝의 = 기호 없이 붙여 넣은 문자열은 요란하게 실패하는 대신 다른 바이트로 디코딩된다.
값을 한 번 디코딩한 프로필은 이미 변환해 버렸으므로, 다시 디코딩하면 다른 바이트가 되고 잘못된 비밀번호처럼 보이는 인증 실패가 난다. 모호한 것에는 따옴표가 안전한 방향이다. 내용이 인코딩 표식으로 시작해도 리터럴로 취급되기 때문이다.
Base64 텍스트는 어디에서 오는가
프로필 내보내기와 공급업체 포털은 키를 이미 인코딩한 채로 건네는 일이 많다. 대개 손으로 입력하라고 만든 적 없는 데이터 필드에서다. 그 값을 풀어 디코딩한 텍스트를 따옴표에 저장하거나, 표식을 앞에 둔 채 인코딩된 상태로 두어야 한다. 둘 다 반씩 하는 것이 고장의 원인이다. 어느 길이든 값 전체가 복사를 견뎌야 작동한다.
두 방향 모두 명령 하나씩이며, 저장된 값을 만든 정확한 작업으로 티켓에 남길 가치가 있다. 다음 순서로 실행한다.
printf '%s' 'a2V5MQ==' | base64 -d
printf '%s' 'key1' | base64
인코딩된 텍스트를 평문처럼 붙여 넣는 것이 비싼 실수다. 파일은 적힌 그대로 문자를 해시하고, 파생 키는 상대가 계산한 것보다 대략 삼분의 일 길어지며, 모든 시도가 경고 없이 똑같이 실패한다. 파서는 주어진 규칙을 따랐을 뿐이기 때문이다.
각 피어가 실제로 어떤 바이트를 쓰는지 확인한다
오류 문자열에서 원인을 짐작하기보다 먼저 데몬이 보는 연결 상태를, 그다음 인증 결과를 읽는다. 저장된 길이를 비교하는 것은 빠른 타당성 점검이다. 인코딩된 텍스트는 그것이 나타내는 바이트보다 길기 때문이다. 그다음 어느 신원 행이 일치했는지 확인한다. 올바른 비밀이 잘못된 피어 아래에 놓이면 틀린 것과 똑같이 실패한다. 행 순서가 그것을 결정한다. 첫 일치가 이기므로 위쪽의 넓은 %any 행이 방금 편집한 특정 행을 조용히 대체한다.
파일이 올바르면 다시 시작하지 말고 다시 읽어 들인다. ipsec rereadsecrets 는 IKE 데몬의 사본을 새로 고치고, swanctl 구성은 자체 명령으로 자격 증명을 읽어 들인다. 다시 시작하면 설정된 모든 연결이 끊기고 확인하려던 비교가 무너진다.
이 점검 중 어느 것도 비밀을 노출할 필요가 없다. 길이, 신원 선택자, 행 위치만으로 이런 실패의 대부분이 설명된다. 십육진 덤프가 필요해지기 전에.
결과를 숨기지 않고 파일을 바꾼다
파일은 데몬 계정으로 제한하고, 살아 있는 비밀은 티켓과 채팅, 스크린샷 밖에 둔다. 붙여 넣은 키는 진단이 아니라 유출이기 때문이다. 그것은 키를 만든 사건보다 오래 남는다.
설정을 직접 통제하는 클라이언트에서 시험하고, 인증이 성공하는지 확인한 다음 터널이 트래픽을 나르는지 확인한다. 핸드셰이크는 고쳤는데 라우팅이 깨진 채로 남는 다시 읽기는 다른 문제이며, 비밀이 움직이기를 멈추는 순간 드러난다.