ASP.NET Core의 하위 키 파생 및 인증된 암호화

키 링의 대부분의 키는 일종의 엔트로피를 포함하며 "CBC 모드 암호화 + HMAC 유효성 검사" 또는 "GCM 암호화 + 유효성 검사"를 나타내는 알고리즘 정보를 포함합니다. 이러한 경우 포함된 엔트로피를 이 키의 마스터 키 자료(또는 KM)라고 하며, 키 파생 함수를 수행하여 실제 암호화 작업에 사용할 키를 파생합니다.

참고

키는 추상적이며 사용자 지정 구현은 아래와 같이 작동하지 않을 수 있습니다. 키가 기본 제공 팩터리 중 하나를 사용하는 대신 IAuthenticatedEncryptor의 자체 구현을 제공하는 경우 이 섹션에 설명된 메커니즘이 더 이상 적용되지 않습니다.

추가 인증된 데이터 및 하위 키 파생

IAuthenticatedEncryptor 인터페이스는 모든 인증된 암호화 작업의 핵심 인터페이스 역할을 합니다. 해당 Encrypt 메서드는 두 개의 버퍼인 plaintext 및 AAD(additionalAuthenticatedData)를 사용합니다. 일반 텍스트 콘텐츠는 IDataProtector.Protect에 대한 호출을 변경하지 않고 흐르지만 AAD는 시스템에서 생성되고 다음 세 가지 구성 요소로 구성됩니다.

  1. 이 버전의 데이터 보호 시스템을 식별하는 32비트 매직 헤더 09 F0 C9 F0입니다.

  2. 128비트 키 ID입니다.

  3. 이 작업을 수행하는 IDataProtector를 만든 용도 체인에서 형성된 가변 길이 문자열입니다.

AAD가 세 가지 구성 요소 모두의 튜플에 대해 고유하기 때문에 모든 암호화 작업에서 KM 자체를 사용하는 대신 KM에서 새 키를 파생하는 데 사용할 수 있습니다. IAuthenticatedEncryptor.Encrypt를 호출할 때마다 다음 키 파생 프로세스가 수행됩니다.

( K_E, K_H ) = SP800_108_CTR_HMACSHA512(K_M, AAD, contextHeader || keyModifier)

여기서는 다음 매개 변수를 통해 카운터 모드에서 NIST SP800-108 KDF(NIST SP800-108, Sec. 5.1 참조)를 호출합니다.

  • KDK(키 파생 키) = K_M

  • PRF = HMACSHA512

  • 레이블 = additionalAuthenticatedData

  • 컨텍스트 = contextHeader || keyModifier

컨텍스트 헤더는 가변 길이이며 기본적으로 K_EK_H를 파생시키는 알고리즘의 지문으로 사용됩니다. 키 한정자는 Encrypt에 대한 각 호출에 대해 임의로 생성된 128비트 문자열이며, KDF에 대한 다른 모든 입력이 일정하더라도 KE와 KH가 이 특정 인증 암호화 작업에 대해 고유할 확률이 매우 높습니다.

CBC 모드 암호화 + HMAC 유효성 검사 작업의 경우 | K_E |는 대칭 블록 암호 키의 길이이며 | K_H |는 HMAC 루틴의 다이제스트 크기입니다. GCM 암호화 + 유효성 검사 작업의 경우 | K_H | = 0입니다.

CBC 모드 암호화 + HMAC 유효성 검사

위의 메커니즘을 통해 K_E가 생성되면 임의 초기화 벡터를 생성하고 대칭 블록 암호 알고리즘을 실행하여 일반 텍스트를 암호화합니다. 그런 다음, 초기화 벡터 및 암호 텍스트는 K_H 키로 초기화된 HMAC 루틴을 통해 실행되어 MAC를 생성합니다. 이 프로세스와 반환 값은 아래에 그래픽으로 표시됩니다.

CBC-mode process and return

output:= keyModifier || iv || E_cbc (K_E,iv,data) || HMAC(K_H, iv || E_cbc (K_E,iv,data))

참고

IDataProtector.Protect 구현은 호출자에게 반환하기 전에 매직 헤더 및 키 ID를 출력 앞에 추가합니다. 매직 헤더와 키 ID는 암시적으로 AAD의 일부이며 키 한정자가 KDF에 대한 입력으로 공급되기 때문에 반환된 최종 페이로드의 모든 단일 바이트가 MAC에서 인증됩니다.

Galois/카운터 모드 암호화 + 유효성 검사

위의 메커니즘을 통해 K_E가 생성되면 임의 96비트 nonce를 생성하고 대칭 블록 암호 알고리즘을 실행하여 일반 텍스트를 암호화하고 128비트 인증 태그를 생성합니다.

GCM-mode process and return

output := keyModifier || nonce || E_gcm (K_E,nonce,data) || authTag

참고

GCM은 기본적으로 AAD 개념을 지원하지만 원래 KDF에만 AAD를 공급하고 AAD 매개 변수에 대해 빈 문자열을 GCM에 전달하도록 선택합니다. 그 이유는 두 가지입니다. 첫째, 민첩성을 지원하기 위해 암호화 키로 K_M을 직접 사용하지 않습니다. 또한 GCM은 입력에 매우 엄격한 고유성 요구 사항을 부과합니다. GCM 암호화 루틴이 동일한(키, nonce) 쌍을 가진 두 개 이상의 고유 입력 데이터 세트에서 호출될 확률은 2^32를 초과하면 안 됩니다. K_E를 수정하는 경우 2^-32 제한에 따라 실행하기 전에 2^32 이상의 암호화 작업을 수행할 수 없습니다. 이 작업은 매우 많은 수의 작업처럼 보일 수 있지만 트래픽이 많은 웹 서버는 이러한 키의 정상적인 수명 내에 불과 며칠 만에 40억 개의 요청을 처리할 수 있습니다. 2^-32 확률 제한을 계속 준수하기 위해 128비트 키 한정자와 96비트 nonce를 계속 사용하여 지정된 K_M에 대해 사용 가능한 작업 수를 크게 확장합니다. 설계의 편의를 위해 CBC와 GCM 작업 간에 KDF 코드 경로를 공유하고 AAD가 이미 KDF에서 고려되므로 GCM 루틴에 전달할 필요가 없습니다.