[security] OAuth 토큰 생성에 대한 모범 사례?

OAuth 사양 은 ConsumerKey, ConsumerSecret, AccessToken, RequestToken, TokenSecret 또는 Verifier 코드의 출처에 대해 아무것도 지정하지 않는다는 것을 알고 있지만 상당히 안전한 토큰 (특히 Token / 비밀 조합).

내가보기에 토큰을 생성하는 방법에는 몇 가지가 있습니다.

  1. 임의의 바이트를 사용하고 소비자 / 사용자와 관련된 DB에 저장
  2. 일부 사용자 / 소비자 특정 데이터를 해시하고 소비자 / 사용자와 관련된 DB에 저장
  3. 사용자 / 소비자 별 데이터 암호화

(1)의 장점은 데이터베이스가 가장 안전 해 보이는 유일한 정보 소스라는 것입니다. (2) 또는 (3)보다 공격을 실행하는 것이 더 어려울 것입니다.

실제 데이터 (2)를 해싱하면 이미 알려진 데이터에서 토큰을 다시 생성 할 수 있습니다. 어쨌든 저장 / 조회가 필요하기 때문에 (1)에 실제로 이점을 제공하지 않을 수 있습니다. (1)보다 CPU 집약적입니다.

실제 데이터 (3)를 암호화하면 암호를 해독하여 정보를 알 수 있습니다. 이것은 (1) & (2)보다 적은 저장 공간과 잠재적으로 더 적은 조회를 필요로하지만 잠재적으로 덜 안전합니다.

고려해야 할 다른 접근 방식 / 장점 / 단점이 있습니까?

편집 : 또 다른 고려 사항은 토큰에 일종의 임의의 값이 있어야한다는 것입니다. 새로운 토큰을 만료 및 재발행 할 수있는 능력이 있어야하므로 실제 데이터로만 구성되어서는 안됩니다.

후속 질문 :

암호화 보안을 상당히 강화하기위한 최소 토큰 길이가 있습니까? 내가 이해했듯이 더 긴 토큰 비밀은 더 안전한 서명을 생성합니다. 이 이해가 맞습니까?

해싱 관점에서 특정 인코딩을 다른 인코딩보다 사용하면 이점이 있습니까? 예를 들어, 16 진수 인코딩 (예 : GUID 문자열)을 사용하는 많은 API가 있습니다. OAuth 서명 알고리즘에서 토큰은 문자열로 사용됩니다. 16 진수 문자열을 사용하면 사용 가능한 문자 집합이 Base64 인코딩보다 훨씬 작습니다 (예측 가능). 길이가 같은 두 문자열의 경우 더 큰 문자 집합을 가진 문자열이 더 좋고 / 넓은 해시 분포를 갖는 것 같습니다. 이것은 보안을 향상시킬 것 같습니다. 이 가정이 맞습니까?

OAuth 사양은 11.10 Entropy of Secrets 에서 바로이 문제를 제기합니다 .



답변

OAuth는 관련된 비밀이 있다는 것을 제외하고는 토큰에 대해 아무것도 말하지 않습니다. 그래서 당신이 언급 한 모든 계획이 작동 할 것입니다. 우리의 토큰은 사이트가 커짐에 따라 진화했습니다. 이전에 사용한 버전은 다음과 같습니다.

  1. 첫 번째 토큰은 사용자 이름, 토큰 비밀 및 만료 등이 포함 된 암호화 된 BLOB입니다. 문제는 호스트에 기록이 없으면 토큰을 취소 할 수 없다는 것입니다.

  2. 그래서 우리는 모든 것을 데이터베이스에 저장하도록 변경했고 토큰은 단순히 데이터베이스의 키로 사용되는 임의의 숫자입니다. 사용자 이름 색인이 있으므로 사용자의 모든 토큰을 쉽게 나열하고 취소 할 수 있습니다.

  3. 해킹 활동이 거의 없습니다. 난수를 사용하면 토큰이 유효한지 데이터베이스로 이동해야합니다. 그래서 우리는 다시 암호화 된 BLOB로 돌아갔습니다. 이번에는 토큰에 암호화 된 키 값과 만료 만 포함됩니다. 따라서 데이터베이스로 이동하지 않고도 유효하지 않거나 만료 된 토큰을 감지 할 수 있습니다.

도움이 될만한 구현 세부 정보,

  1. 토큰에 버전을 추가하면 기존 형식을 깨지 않고 토큰 형식을 변경할 수 있습니다. 모든 토큰에는 첫 번째 바이트가 버전으로 있습니다.
  2. URL 안전 버전의 Base64를 사용하여 BLOB를 인코딩하면 URL 인코딩 문제를 처리 할 필요가 없습니다. 이렇게하면 삼중 인코딩 된 basestring이 표시 될 수 있으므로 OAuth 서명으로 디버깅이 더 어려워집니다.

답변