이 페이지에서는 키 및 기본 출력에 관한 Tink의 와이어 형식을 설명합니다. 이 문서는 Tink에 추가 언어를 추가하려는 암호화 전문가와 와이어 호환 모드를 원하는 기타 상위 수준 암호화 라이브러리 유지관리자를 대상으로 합니다. 일반 시청자를 대상으로 하지 않습니다.
키 세트 직렬화
Tink는 Google protobuf를 사용하여 키 세트를 직렬화합니다.
- 바이너리 직렬화 키 세트는 tink.proto에 정의된 직렬화된 키 세트 프로토입니다. 키의 KeyData 값 속성은 해당 키 유형의 직렬화된 프로토입니다.
- JSON 직렬화 키 세트는 JSON 형식으로 직렬화된 키 세트 프로토입니다. KeyData 값은 여전히 바이너리 직렬화된 프로토입니다.
- 암호화된 키 세트는 tink.proto에 정의된 직렬화된 EncryptedKeyset 프로토입니다. 암호화된 바이너리 직렬화 키 세트와 선택적으로 암호화되지 않은 KeysetInfo 메타데이터가 포함되어 있습니다.
Tink 출력 접두사
대부분의 Tink 기본 요소는 다음으로 구성된 5바이트 출력 접두사를 지원합니다.
- 1바이트 버전:
0x01 - 4바이트 키 힌트: 사용된 키의 키 ID입니다.
일부 기존 키는 버전 바이트 0x00도 지원할 수 있습니다.
이 접두사는 인증되지 않았으며 보안 목적으로 사용할 수 없습니다. Tink는 이를 복호화 또는 확인 속도를 높이기 위한 힌트로 사용합니다.
AEAD
일반적으로 Tink는 AEAD 암호문을 다음과 같이 형식화합니다.
prefix || IV || ciphertext || tag
해당 RFC에 달리 명시되지 않는 한 prefix는 비어 있거나 5바이트 Tink 출력 접두사입니다.
AES-CTR-HMAC
AES-CTR-HMAC의 경우 Tink는 다음과 같이 연결된 데이터 (AD)로 MAC을 계산합니다.
AD || IV || ciphertext || bitlen(AD)
여기서 bitlen(AD)는 AD의 길이(비트)이며 64비트 빅 엔디안 부호 없는 정수로 표현됩니다. 이 HMAC 스키마는 Mcgrew의 AES-CBC-HMAC 초안을 따릅니다.
결정적 AEAD
Tink는 AES-SIV에 RFC 5297을 구현하여 합성 초기화 벡터 (SIV)를 암호문의 시작 부분에 배치합니다. 원시 유형은 5바이트 Tink 출력 접두사를 추가할 수 있습니다.
RFC 5297은 연결된 데이터 목록을 지원하지만 Tink는 정확히 하나의 연결된 데이터만 지원합니다. 이는 RFC 5297의 요소가 하나인 목록에 해당합니다. 빈 연결 데이터는 빈 목록이 아닌 빈 요소가 하나 있는 목록입니다.
스트리밍 AEAD
AES-CTR HMAC 및 AES-GCM-HKDF를 참고하세요.
봉투 암호화
봉투 암호화는 Tink의 AEAD 기본 요소를 사용하여 데이터 암호화 키 DEK로 데이터를 암호화합니다. 암호화는 다음과 같이 작동합니다.
- 지정된 키 템플릿 (또는 키 매개변수)을 사용하여 새
DEK가 생성됩니다. DEK이 바이트 문자열로 직렬화됩니다. 키 유형 proto의 프로토콜 버퍼 직렬화의 직렬화 형식입니다. 예를 들어 이는 키 유형 AES GCM의 DEK에 대해 aes_gcm.proto에 정의된 직렬화된AesGcmKey프로토콜 버퍼 메시지입니다. 프로토콜 버퍼를 직렬화하는 방법은 프로토콜 버퍼 직렬화를 참고하세요.- 직렬화된
DEK는 외부 제공업체 (예: GCP)에 의해encrypted DEK로 암호화됩니다. DEK는 연결된 데이터가 포함된 일반 텍스트를ciphertext로 암호화하는 데 사용됩니다. 따라서ciphertext의 형식은DEK에 해당하는 AEAD 기본 요소와 정확히 동일합니다.
봉투 암호화의 출력 형식은 다음과 같습니다.
encrypted DEK length || encrypted DEK || ciphertext
encrypted DEK length는 4바이트이며 encrypted DEK의 길이를 32비트 빅 엔디안 정수로 저장합니다.
MAC
Tink는 해당 RFC를 따릅니다. 원시 요소는 태그에 5바이트 Tink 출력 접두사를 추가할 수 있습니다.
PRF 세트
Tink는 해당 RFC를 따릅니다. PRF의 경우 키 유형은 출력 길이를 포함하지 않으므로 동일한 알고리즘의 MAC 키 유형과 다릅니다. PRF 설정 키는 Tink 출력 접두사를 추가하지 않습니다. 이렇게 하면 출력이 실제로 PRF가 됩니다.
하이브리드 암호화
Tink 하이브리드 암호화의 일반적인 와이어 형식은 다음과 같습니다.
prefix || encapsulated_key || encrypted_data
prefix는 비어 있거나 5바이트 Tink 출력 접두사입니다. 각 키 유형에는 파싱할 바이트 수와 encapsulated_key에서 이러한 바이트를 파싱하는 방법에 관한 정보가 포함되어 있습니다.
HPKE (하이브리드 공개 키 암호화)
Tink는 RFC 9180에 정의된 HPKE 표준을 따릅니다. HPKE 암호화 스위트에는 다음 세 가지 기본 요소가 포함됩니다.
- 키 캡슐화 메커니즘 (KEM)
- 키 파생 함수 (KDF)
- 연관 데이터로 인증된 암호화 (AEAD)
HPKE 표준은 RFC 9180, 섹션 10에 일반 와이어 형식을 정의하지 않습니다. Tink의 HPKE 구현은 다음 encapsulated_key 및 encrypted_data 값을 사용합니다.
encapsulated_key- 발신자의 직렬화된 공개 키
- RFC 9180, 섹션 4.1에
enc로 정의됨 - 사용된 특정 HPKE KEM에 따라 결정되는 형식
encrypted_data- 암호문과 태그 (즉,
ciphertext || tag(IV 제외) - RFC 9180, 섹션 4에
ct로 정의됨 - 사용된 특정 HPKE AEAD에 따라 형식이 결정됨
- 암호문과 태그 (즉,
X25519 디피-헬만 기반 KEM
X25519 DHKEM의 경우 값 enc은 전송자의 32바이트 Diffie-Hellman 공개 키입니다.
ECIES-AEAD-HKDF
Tink의 ECIES-AEAD-HKDF 구현에서 encapsulated_key는 키 캡슐화 메커니즘 (KEM)의 출력이고 encrypted_data는 데이터 캡슐화 메커니즘 (DEM)의 출력입니다.
KEM
키 유형에 따라 Tink는 RFC 8422/ANSI.X9-62.2005 인코딩 표준에 따라 압축된 타원 곡선 점과 압축되지 않은 타원 곡선 점을 사용합니다. 압축되지 않은 점의 경우 바이트 0x04 뒤에 x 및 y 좌표가 고정 크기 정수로 옵니다. 압축된 좌표의 경우 바이트 0x02 또는 0x03과 x 좌표가 고정 크기 정수로 사용됩니다. X25519의 경우 RFC 7748 정의가 사용됩니다 (x 좌표가 고정 크기 정수임).
DEM
encrypted_data의 경우 Tink는 AEAD와 동일한 형식을 사용합니다. 여기에는 IV 지정이 포함됩니다.
키 파생
먼저 공유 지점의 x 좌표 x_ss가 계산됩니다. 그러면 AEAD의 키가 다음과 같이 설정됩니다.
HKDF(ikm = encapsulated_key || x_ss, salt = salt_of_key, info = context_info, length = dem_key_size)
여기서 encapsulated_key은 전체 KEM 출력을 바이트로 나타낸 것입니다.
디지털 서명
Tink는 해당 RFC를 따릅니다. 원시 요소는 생성된 태그에 5바이트 Tink 출력 접두사를 추가할 수 있습니다.
ECDSA
키의 EcdsaSignatureEncoding 필드에 따라 ECDSA 서명의 형식은 IEEE P1363 또는 ASN.1 DER입니다.
IEEE P1363 서명의 형식은 r || s입니다. 여기서 r와 s는 0으로 패딩되고 곡선의 순서와 바이트 크기가 동일합니다. 예를 들어 NIST P-256 곡선의 경우 r 및 s은 32바이트로 0 패딩됩니다.
DER 서명은 ASN.1을 사용하여 인코딩됩니다.
ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }
특히 인코딩은 다음과 같습니다.
0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s
Tink는 DER 인코딩 ECDSA 서명만 허용하여 서명 확인 권장사항을 따릅니다 (대체 BER 인코딩 서명은 유효하지 않음).
이를 통해 암호화폐 시스템에 자주 영향을 미치는 서명 변경 공격을 방지할 수 있습니다.
외부 Mu ML-DSA 사전 해시 값
Prehash 기본 요소는 메시지를 prehash 값으로 변환하며, SignPrehash 기본 요소는 이 값을 서명합니다. RFC 9881에 설명된 대로 외부 Mu 모드의 ML-DSA의 경우 사전 해시 값은 다음 레이아웃으로 69바이트입니다.
0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
mu는 ML-DSA 메시지 대표이며SHAKE256(tr || 0x00 || 0x00 || message, 64)로 계산됩니다. 여기서tr는 공개 키의 64바이트 해시이고, 첫 번째0x00는 순수 ML-DSA의 FIPS 204 도메인 구분자이며, 두 번째0x00는 (빈) 컨텍스트 문자열의 길이입니다.tr는 공개 키에서 파생되므로mu는 해당 키에 암호화 방식으로 바인딩됩니다. 바인딩을 확인하려면 원래 메시지가 필요합니다.- 5바이트 접두사는 Tink 프레이밍이며
mu의 일부가 아닙니다. 미리 해시된 값을 하나의 특정 키와 연결하여 SignPrehash가 서명할 키를 알고 키가 없는 미리 해시된 값을 거부할 수 있습니다. 접두사는 일반 메타데이터이며 암호화 방식으로 바인딩되지 않습니다. 누구나 다시 쓸 수 있습니다.
서명은 정확히 69바이트가 아니거나 0xff로 시작하지 않거나 키 ID가 키 세트의 사용 설정된 키와 일치하지 않는 입력을 거부합니다.