전자서명에서 nonce와 transactionId가 필요한 이유
유효한 서명이 현재의 업무 요청을 위한 것인지 확인하며
전자서명 결과가 유효하다는 사실만으로 업무를 처리할 수 있을지 검토하다가 한 가지 문제가 남았습니다.
서명 원문과 업무 요청이 같고 서명 자체도 정상이라면 충분해 보입니다. 하지만 이전에 정상적으로 생성된 서명 결과가 다시 전달된다면 서버는 이를 어떻게 구분할 수 있을까요.
유효한 서명인지 확인하는 것과 지금 처리하려는 요청을 위해 만들어진 서명인지 확인하는 것은 다른 문제였습니다.
같은 내용에는 같은 서명을 다시 사용할 수 있었습니다
서명 대상이 계좌, 상품, 금액 같은 업무 데이터로만 구성되어 있다면 같은 조건의 요청은 동일한 형태를 가질 수 있습니다.
서버가 서명의 유효성과 데이터 일치 여부만 확인하면 과거 요청에서 생성된 서명이 다시 사용되는 상황을 구분하기 어렵습니다.
업무가 이미 처리되었는지 별도로 확인할 수 있더라도, 모든 업무가 동일한 중복 처리 기준을 가지는 것은 아닙니다. 서명 단계 자체에서 현재 요청과의 관계를 식별할 수 있어야 했습니다.
transactionId로 업무 흐름을 연결했습니다
transactionId는 서명 요청부터 실제 업무 처리까지 하나의 흐름을 식별하는 값입니다.
서버는 업무 요청을 시작할 때 식별자를 발급하고 서명 대상 데이터와 연결합니다. 전자서명 결과가 돌아오면 같은 식별자에 속한 요청인지 확인합니다.
이 식별자를 기준으로 요청 상태도 관리할 수 있습니다. 서명 대기, 서명 완료, 업무 처리 완료처럼 현재 단계가 어디인지 확인하고 이미 완료된 요청의 재처리를 막을 수 있습니다.
단순한 화면 추적용 값이 아니라 서버가 현재 업무의 생명주기를 판단하는 기준으로 사용해야 의미가 있었습니다.
nonce는 서명 원문을 요청마다 다르게 만들었습니다
nonce는 한 번의 요청을 위해 생성하는 예측하기 어려운 값입니다.
같은 업무 데이터라 하더라도 nonce를 서명 대상에 포함하면 요청마다 다른 원문이 만들어집니다. 이전 서명 결과를 새로운 요청에 그대로 사용하는 것을 어렵게 만들 수 있습니다.
서버는 자신이 발급한 nonce인지 확인하고, 서명 검증이 성공한 뒤에는 다시 사용할 수 없도록 처리합니다. 유효시간을 함께 두면 오래된 요청이 뒤늦게 처리되는 상황도 제한할 수 있습니다.
nonce를 클라이언트가 임의로 생성하거나 전달한 값을 그대로 신뢰하면 재사용 방지 기준이 약해질 수 있습니다. 생성과 사용 여부 판단은 서버가 책임지는 편이 현재 구조에 맞았습니다.
발급, 사용, 만료를 함께 관리해야 했습니다
식별자를 추가하는 것만으로 재사용 방지가 완성되지는 않습니다.
서버에는 어떤 업무 데이터에 발급했는지, 사용되었는지, 유효시간이 지났는지 확인할 상태가 필요합니다. 동시에 들어온 두 요청이 같은 값을 사용하는 상황도 원자적으로 막아야 합니다.
업무 처리에 실패했을 때 같은 서명을 다시 허용할지도 정해야 합니다. 기술적으로 재시도할 수 있다는 이유만으로 무제한 허용하기보다 업무의 특성과 고객 흐름에 맞는 정책이 필요했습니다.
유효한 서명을 현재 요청과 연결하는 기준
전자서명의 목적은 서명 결과를 받는 데서 끝나지 않았습니다.
그 결과가 어떤 업무를 위해, 언제 만들어졌고, 이미 사용되지는 않았는지 설명할 수 있어야 했습니다.
transactionId는 서명과 업무 처리의 흐름을 연결하고, nonce는 요청마다 고유한 서명 원문을 만드는 데 도움을 줍니다.
이 두 값은 보안을 위한 부가 필드가 아니라 유효한 서명을 현재의 단 한 번의 업무 요청과 연결하기 위한 기준이었습니다.