하위 키 파생 및 ASP.NET Core에서 인증 된 암호화Subkey derivation and authenticated encryption in ASP.NET Core

키 링에서 대부분의 키 엔트로피 형태의 사용 될 및 "CBC 모드 암호화 + HMAC 유효성 검사" 내용의 알고리즘 정보를 갖습니다 또는 "GCM 암호화 + 유효성 검사"입니다.Most keys in the key ring will contain some form of entropy and will have algorithmic information stating "CBC-mode encryption + HMAC validation" or "GCM encryption + validation". 이러한 경우에이 키에 대 한 마스터 키 관련 자료가 (또는 KM)으로 포함 된 엔트로피를 참조 하 고 실제 암호화 작업에 사용할 키를 파생 하는 키 파생 함수를 수행 했습니다.In these cases, we refer to the embedded entropy as the master keying material (or KM) for this key, and we perform a key derivation function to derive the keys that will be used for the actual cryptographic operations.

참고

키 추상화 되어 있고 사용자 지정 구현을 아래와 같이 동작 하지 않을 수 있습니다.Keys are abstract, and a custom implementation might not behave as below. 키의 자체 구현을 제공 하는 경우 IAuthenticatedEncryptor 는 기본 제공 팩터리 중 하나를 사용 하는 대신이 섹션에서 설명 하는 메커니즘 적용 되지 않습니다.If the key provides its own implementation of IAuthenticatedEncryptor rather than using one of our built-in factories, the mechanism described in this section no longer applies.

추가 인증 된 데이터 및 하위 키 파생Additional authenticated data and subkey derivation

IAuthenticatedEncryptor 모든 인증 된 암호화 작업에 대 한 핵심 인터페이스로 사용 되는 인터페이스입니다.The IAuthenticatedEncryptor interface serves as the core interface for all authenticated encryption operations. 해당 Encrypt 메서드는 두 개의 버퍼를 사용 합니다: 일반 텍스트 및 additionalAuthenticatedData (AAD).Its Encrypt method takes two buffers: plaintext and additionalAuthenticatedData (AAD). 일반 텍스트 콘텐츠 흐름에 대 한 호출을 변경 하지 않고 IDataProtector.Protect, AAD 시스템에서 생성 되 고 세 가지 구성 요소로 이루어져 있지만:The plaintext contents flow unchanged the call to IDataProtector.Protect, but the AAD is generated by the system and consists of three components:

  1. 32 비트 magic 헤더 09 F0 C9 F0이이 버전의 데이터 보호 시스템을 식별 하는입니다.The 32-bit magic header 09 F0 C9 F0 that identifies this version of the data protection system.

  2. 128 비트 키 id입니다.The 128-bit key id.

  3. 만든 용도 체인에서 구성 되는 다양 한 길이의 문자열을 IDataProtector 이 작업을 수행 하는 합니다.A variable-length string formed from the purpose chain that created the IDataProtector that's performing this operation.

AAD가 모든 세 가지 컴포넌트의 튜플에 대 한 고유 하므로 새에서 키를 파생 KM KM 자체에서 모든 암호화 작업을 사용 하는 대신 사용할 수 있습니다.Because the AAD is unique for the tuple of all three components, we can use it to derive new keys from KM instead of using KM itself in all of our cryptographic operations. 호출할 때마다 IAuthenticatedEncryptor.Encrypt를 다음 키 파생 프로세스가 수행 됩니다.For every call to IAuthenticatedEncryptor.Encrypt, the following key derivation process takes place:

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

이때 카운터 모드에서 NIST SP800 108 KDF를 호출 하는 것 (참조 NIST SP800 108, 초로 5.1) 다음 매개 변수를 사용 하 여:Here, we're calling the NIST SP800-108 KDF in Counter Mode (see NIST SP800-108, Sec. 5.1) with the following parameters:

  • 키 파생 키 (KDK) K_M =Key derivation key (KDK) = K_M

  • PRF = HMACSHA512PRF = HMACSHA512

  • 레이블 additionalAuthenticatedData =label = additionalAuthenticatedData

  • context = contextHeader || keyModifiercontext = contextHeader || keyModifier

컨텍스트 헤더의 가변 길이 이며 기본적으로는 우리는 파생 K_E 및 K_H 알고리즘의 지문을 역할도 합니다.The context header is of variable length and essentially serves as a thumbprint of the algorithms for which we're deriving K_E and K_H. 키 한정자는 각 호출에 대해 임의로 생성 된 128 비트 문자열 Encrypt 상수는 다른 모든 KDF 입력 하는 경우에 KE 및 KH이 특정 인증 암호화 작업에 대 한 고유한 지 확률 부담을 보장 하는 데 사용 되 고 있습니다.The key modifier is a 128-bit string randomly generated for each call to Encrypt and serves to ensure with overwhelming probability that KE and KH are unique for this specific authentication encryption operation, even if all other input to the KDF is constant.

CBC 모드 암호화 + HMAC 유효성 검사 작업에 대 한 | K_E | 대칭 블록 암호화 키의 길이 및 | K_H | HMAC 루틴의 다이제스트 크기가입니다.For CBC-mode encryption + HMAC validation operations, | K_E | is the length of the symmetric block cipher key, and | K_H | is the digest size of the HMAC routine. GCM 암호화 + 유효성 검사 작업 | K_H | = 0.For GCM encryption + validation operations, | K_H | = 0.

CBC 모드 암호화 + HMAC 유효성 검사CBC-mode encryption + HMAC validation

K_E 위의 메커니즘을 통해 생성 되 면 임의 초기화 벡터를 생성 하 고 일반 텍스트를 암호화 하는 대칭 블록 암호화 알고리즘을 실행 합니다.Once K_E is generated via the above mechanism, we generate a random initialization vector and run the symmetric block cipher algorithm to encipher the plaintext. 초기화 벡터 및 암호화 텍스트 K_H MAC을 생성 하기 위해 키를 사용 하 여 초기화 하는 HMAC 루틴을 통해 다음 실행The initialization vector and ciphertext are then run through the HMAC routine initialized with the key K_H to produce the MAC. 반환 값 및이 프로세스는 아래 그래픽으로 표시 됩니다.This process and the return value is represented graphically below.

CBC 모드 프로세스 및 반환

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

참고

IDataProtector.Protect 구현 됩니다 magic 머리글과 키 id 앞 호출자에 게 반환 하기 전에 출력 합니다.The IDataProtector.Protect implementation will prepend the magic header and key id to output before returning it to the caller. 매직 머리글과 키 id는 암시적으로 하기 때문에 부분 AAD, 고차원적으로 반환 된 마지막 페이로드는 MAC에서 인증 되는 키 한정자 KDF 입력으로 제공 되므로 매번 이므로 및Because the magic header and key id are implicitly part of AAD, and because the key modifier is fed as input to the KDF, this means that every single byte of the final returned payload is authenticated by the MAC.

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

K_E 위의 메커니즘을 통해 생성 되 면 임의의 96 비트 nonce를 생성 하 고 일반 텍스트를 암호화 하 고 128 비트 인증 태그를 생성 하는 대칭 블록 암호화 알고리즘을 실행 합니다.Once K_E is generated via the above mechanism, we generate a random 96-bit nonce and run the symmetric block cipher algorithm to encipher the plaintext and produce the 128-bit authentication tag.

GCM 모드 프로세스 및 반환

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

참고

GCM에서 기본적으로 AAD의 개념을 지 원하는 경우에에서는 여전히 저장 AAD 원래 KDF에만 해당 AAD 매개 변수에 대 한 GCM에 빈 문자열을 전달 하려면 선택 합니다.Even though GCM natively supports the concept of AAD, we're still feeding AAD only to the original KDF, opting to pass an empty string into GCM for its AAD parameter. 그 이유는 두 가지가 있습니다.The reason for this is two-fold. 먼저 민첩성을 지원 하기 위해 되지 K_M 암호화 키를 직접 사용 하려고 합니다.First, to support agility we never want to use K_M directly as the encryption key. 또한 GCM는 해당 입력에 대해 매우 엄격한 고유성 요구 사항을 적용합니다.Additionally, GCM imposes very strict uniqueness requirements on its inputs. GCM 암호화 루틴의 두 이전 호출 또는 보다 분명 가능성 (키, nonce) 동일한 입력된 데이터 집합 2 쌍을 초과할 수 없습니다 ^32입니다.The probability that the GCM encryption routine is ever invoked on two or more distinct sets of input data with the same (key, nonce) pair must not exceed 2^32. 2 개 수행할 수 없습니다. K_E를 해결 했습니다 ^32 암호화 작업의 2의 위반을 실행 했습니다 전에 ^-32를 제한 합니다.If we fix K_E we cannot perform more than 2^32 encryption operations before we run afoul of the 2^-32 limit. 이 작업의 매우 큰 숫자로 처럼 보일 수 있지만 트래픽이 많은 웹 서버 수 십억 4 요청을 통해 이러한 키에 대 한 일반적인 수명 내 에서도 단순한 일.This might seem like a very large number of operations, but a high-traffic web server can go through 4 billion requests in mere days, well within the normal lifetime for these keys. 2의 호환성을 유지 하려면 ^128 비트 키 한정자 및 근본적으로 지정 된 모든 K_M에 대 한 사용 가능한 작업 수를 확장 하는 96 비트 nonce를 사용 하 여 계속-32 확률 제한 합니다.To stay compliant of the 2^-32 probability limit, we continue to use a 128-bit key modifier and 96-bit nonce, which radically extends the usable operation count for any given K_M. CBC 및 GCM 작업 사이의 KDF 코드 경로 디자인의 단순성에 대 한 공유 되며 AAD KDF에서 이미 간주 되므로 GCM 루틴에 전달할 필요가 없습니다.For simplicity of design we share the KDF code path between CBC and GCM operations, and since AAD is already considered in the KDF there's no need to forward it to the GCM routine.