2016-07-21 4 views
3

MVC 기반 서버 애플리케이션을 마이그레이션하고 REST-ful API를 사용하여 호출을 처리하는 중입니다.OAuth : 자바 스크립트에서 API Secret Key를 숨기는 방법

나는 AES 암호화 및 OAuth2를 위로 읽고 다음과 같이 그 개념을 형성 성장하는 솔루션 구현하기로 결정했습니다 :

  1. 클라이언트는 사용자 ID 또는 이메일을 제공하는 로그인 요청을 보냅니다. 이 요청은 API 비밀 키를 사용하여 HMAC되었습니다.
  2. 서버는 UserID/Email이 기존 계정과 일치하는지 확인하고 발견 한 경우 응답의 일부로 클라이언트에 보내는 서버 논스를 생성하고 저장합니다.
  3. 클라이언트는 자신의 클라이언트 넌스 (nonce)를 생성하고 API 비공개 키와 두 nonces 모두에서 새 임시 키를 만듭니다. 그런 다음이 임시 키를 사용하여 암호가 암호화 된 로그인 요청을 보냅니다. [엔트로피를 추가하고 암호를 일반 텍스트로 보내지 않으려면].
  4. 서버는이 플랫폼에서이 클라이언트에 대해 저장 한 최신 nonce (모바일과 웹 클라이언트는 고유 한 고유 번호 및 세션을 가질 수 있음)와 암호화되지 않은 상태로 전송 된 클라이언트 nonce를 사용하여 암호와 HMAC를 암호 해독합니다. HMAC가 체크 아웃하면 데이터베이스 [PBKDF2 해시 및 소금]에 대한 암호를 확인합니다.
  5. 요청이 유효하고 암호와 사용자 ID가 레코드와 일치하면 해당 플랫폼에서 해당 사용자 ID에 대한 새 세션 비밀 키가 만들어지고이 비밀 키가 클라이언트로 보내지고 HMAC는 모든 API 요청에서 클라이언트에게 사용됩니다 금후.
  6. 새로운 로그인하지 않은 요청에는 세션 비밀 키와 무작위 화 된 IV에서 계산 된 HMAC 서명이 포함됩니다.

모든 통신은 TLS를 통해 처리되므로 보안이 강화되고 방어선이 추가되지 않습니다.

모바일 앱에서 모바일 앱의 비밀 키를 설정 파일에 숨길 수 있기 때문에 보안에 대한 적절한 측정 값을 제공합니다. [아마도 많이는 아니지만] 우리가 시도한다면 우리 웹 페이지의 모든 요청을이 형식으로 변환하면 클라이언트 측 AES 암호화 및 인증을 처리하기 위해 자바 스크립트를 사용한다는 의미입니다. well as this article clearly explains "자바 스크립트 웹 앱에 API 키를 저장하면 인쇄 할 수도 있습니다 전 세계가 이제 브라우저의 개발 도구를 통해 액세스 할 수 있기 때문에 홈페이지 전체에 걸쳐 대담한 글씨로 표시됩니다. "

나는 API 비밀 키로 nonces 만 사용할 수 있습니다. 또는 이러한 요청에 대해 AES 암호화를 사용하지 않고 CSRF 토큰과 같은 다른 방법을 통해 유효성을 검사하고 모든 요청이 Google의 프런트 엔드에서 만들어 지도록 할 수 있습니다. 어떤 방식 으로든 - 다른 페이지 나 서비스와 통합 할 수있는 API를 만들고 싶다면 클라이언트의 비밀 세션 키를 어떻게 확보 할 수 있습니까?

이 기사에서는 일회용 쿠키를 토큰으로 생성 할 것을 제안했지만 이는 포스터 서비스에는 사용할 수 있지만 제한되지는 않습니다. 사용자가 만료 및 재설정 할 수있는 사용자 별 키를 사용하여 전송하는 모든 요청을 HMAC에서 처리 할 수 ​​있기를 원합니다. 서비스가 결국 돈을 처리 할 것이므로 요청 인증을 엄격하게 잠그고 싶습니다.

내 옵션은 무엇입니까?

is doomed 이후 Javascript를 그냥 사용합니까? 비밀 키를 .js 스크립트에 하드 코딩 된 날에 공개하지 않고 저장하는 방법이 있습니까? 로그인 호출에만 사용되는 새로운 임시 비밀 키를 생성하고 서버 nonce를 요청할 때이를 사용자에게 보내야합니까?

또한 링크 된 게시물은 쿠키를 사용하여 클라이언트의 세션 키를 저장 한 다음 JS에서 키에 액세스하도록 제안합니다. 이게 괜찮습니까? 아니면 물개보다 더 많은 구멍을 제공합니까?

답변

1

어떤 보안 대책이 어떤 보안 구멍을 막는 지 알아 두는 것이 좋습니다.

비밀을 저장할 수있는 곳이 없기 때문에 JavaScript가 암호화에 적합하지 않다는 것이 맞습니다. 자바 스크립트에서 암호화를해서는 안되기 때문에 좋은 암호화 라이브러리도 없습니다.

세션 키는 인증 키의 역할을 할 수 있습니다. TLS를 사용하는 경우 연결이 안전하며 공격자가 세션 키를 알 수 없습니다. 또한 JavaScript는 세션 키를 알 필요가 없습니다. 쿠키는 기본적으로 모든 요청과 함께 전송됩니다. 그리고 쿠키를 http 전용 쿠키로 설정할 수 있습니다. 이 있어야하지만 다른 보안 계층이 추가됩니다.

본질적으로 비밀 API 키처럼 작동하도록 세션 쿠키의 유효 기간을 매우 길게 지정할 수 있습니다. 브라우저는 쿠키를 안전하게 저장합니다. 새로운 세션이 시작될 때마다 그리고 인증 정보가 변경 될 때 (예 : 비밀번호 재설정) 세션 키를 자주 회전시키는 것이 좋습니다.

CSRF- 토큰은 재생 공격을 방지합니다. CSRF 토큰으로 수정 요청을 안전하게하는 것이 좋습니다. 모든 요청에 ​​대해 CSRF 점검을하지 않아도되며 중요한 정보 (예 : 로그인 자격 증명 또는 경우에 따라 트랜잭션)를 수정하는 요청 만 필요합니다. CSRF 토큰의 경우 세션 키와 동일한 접근 방식을 사용할 수 있습니다.이를 쿠키에 저장합니다.

핵심 부분은 JavaScript가 이것에 대해 알 필요가 없다는 것입니다.

당신이 알고있는 것 중 하나 중요한 사실은 생성하는 모든 키 또는 nonces가 암호로 안전해야한다는 것입니다. 낮은 엔트로피 기능을 사용하지 마십시오.

그래서 :

당신은 사용자 ID 또는 이메일을 암호화 할 필요가 없습니다
  1. , TLS가 당신을 위해 이미 않습니다. 또한 암호를 보낼 수도 있습니다. 별도로 3 단계에서 보내지 않아도됩니다. JavaScript에서는 암호화를하지 않습니다. 모든 암호화는 TLS/HTTPS만으로 처리됩니다.

  2. 별도의 인증 서버 (예 : 단일 사인온)가있는 경우이 방법을 사용하는 것이 좋습니다. 그렇지 않으면이 단계를 건너 뛸 수 있습니다.

  3. 필요하지 않습니다.

  4. 서버에서 아무 것도 해독 할 필요가 없으며 암호화는 TLS에서 처리됩니다. 패스워드를 저장하는 방법은 그 자체에 관한 주제이지만 당신이 가지고 있다고 생각합니다.

  5. 확인. 다시 말하지만 클라이언트는 아무 것도 암호화하지 않아야합니다.

  6. 세션 키만 보냅니다. 그 정도면 충분합니다.개정

입니다 :

  1. 클라이언트 로그인 자격 증명을 보냅니다. 연결은 안전해야합니다.

  2. 서버는 자격 증명을 확인하고 쿠키로 인증 토큰을 보내고 세션 토큰 인 인증 토큰을 추적합니다. 모든 요청에 ​​대해

:

  • 클라이언트 인증 토큰이 포함되어 있습니다. 쿠키를 사용하면 자동으로 발생합니다.

  • 서버는 인증 토큰을 확인하고 클라이언트가 사용할 토큰을 생성합니다.

+0

그래서 클라이언트가 쿠키로 세션 키를 가져 와서 HMAC 서명이 필요 없다고 말하는 것입니까? 개정 된 인증 패턴으로 재생 공격으로부터 보호하려면 어떻게해야합니까? – ConnorU

+0

CSRF 토큰은 재생 공격을 방지합니다. 1. 클라이언트는'/ change_password'를 요청합니다 2. 서버는 CSRF 토큰을 생성하고 토큰리스트에 합당한 만료 시간으로 저장합니다. CSRF 토큰은 다음과 같이 포함됩니다 : (예 :'action = "/ do_password_change? csrf = [token]"형태의)'/ change_password'의 내용 3. 클라이언트는 요청과 함께 CSRF 토큰을 보낸다 4. 서버는 CSRF 토큰을 검사하여 토큰리스트 이것은 CSRF 토큰의 두 번째 사용이 유효하지 않은 요청 (서버가 사용되었다는 것을 알고 있음)을 산출하기 때문에 재생 공격을 방지합니다. – Halcyon

+0

CSRF에서 약간의 mroe를 읽으 려합니다. 답을 표시하기 전에 기다리고 싶습니다. 누군가가 더 많은 의견이나 제안을 할 수있는 경우에 받아 들여졌습니다. 감사합니다! – ConnorU

1

모바일 앱은 public clients으로 간주됩니다. 이것은 그들이 어떤 비밀도 저장해서는 안된다는 것을 의미합니다. 어떤 암호화 알고리즘을 사용하든간에 클라이언트 자격 증명이 손상되는 것을 막는 것은 없습니다.

OAuth2 Framework 프로토콜이 공개 클라이언트 상호 작용을 허용하고 클라이언트 인증을 필요로하지 않는 Implicit grant type 흐름을 정의하는 이유입니다. 액세스 토큰 발급을 보호하기 위해 RFC7636을 고려할 수도 있습니다.

관련 문제