รูปแบบสาย Tink

หน้านี้อธิบายรูปแบบการส่งผ่านข้อมูลของ Tink สำหรับคีย์และเอาต์พุตดั้งเดิม เอกสารนี้มีไว้สำหรับนักเข้ารหัสที่ต้องการเพิ่มภาษาอื่นๆ ลงใน Tink และผู้ดูแลรักษาไลบรารีการเข้ารหัสระดับสูงอื่นๆ ที่ต้องการโหมดที่เข้ากันได้กับสาย ไม่ได้มีไว้สำหรับผู้ชมทั่วไป

การทำให้ Keyset เป็นอนุกรม

Tink ใช้ Google protobuf เพื่อจัดรูปแบบชุดคีย์

  • ชุดคีย์ที่แปลงเป็นไบนารีคือโปรโต Keyset ที่แปลงเป็นอนุกรมซึ่งกำหนดไว้ใน tink.proto พร็อพเพอร์ตี้ค่า KeyData ของคีย์คือ โปรโตที่ซีเรียลไลซ์ของประเภทคีย์ที่เกี่ยวข้อง
  • ชุดคีย์ที่แปลงเป็นอนุกรม JSON คือ Keyset proto ที่แปลงเป็นอนุกรมในรูปแบบ JSON โปรดทราบว่าค่า KeyData ยังคงเป็นโปรโตคอลที่ซีเรียลไลซ์ไบนารี
  • ชุดคีย์ที่เข้ารหัสคือโปรโต EncryptedKeyset ที่แปลงเป็นอนุกรมซึ่งกำหนดไว้ใน tink.proto โดยมีชุดคีย์ไบนารีที่เข้ารหัสซึ่งมีการซีเรียลไลซ์ และอาจมีข้อมูลเมตา KeysetInfo ที่ไม่ได้เข้ารหัส

คำนำหน้าเอาต์พุตของ Tink

Primitive ของ Tink ส่วนใหญ่รองรับคำนำหน้าเอาต์พุต 5 ไบต์ ซึ่งประกอบด้วย

  • เวอร์ชัน 1 ไบต์: 0x01
  • คำใบ้คีย์ 4 ไบต์: นี่คือรหัสคีย์ของคีย์ที่ใช้

คีย์เดิมบางรายการอาจรองรับไบต์เวอร์ชัน 0x00 ด้วย

Primitive Prehash ใช้ไบต์เวอร์ชัน 0xff ดูค่า Prehash ของ ML-DSA ภายนอกของ Mu

โปรดทราบว่าคำนำหน้าเหล่านี้ไม่ได้รับการตรวจสอบสิทธิ์และไม่สามารถใช้เพื่อ วัตถุประสงค์ด้านความปลอดภัย Tink ใช้ค่าเหล่านี้เป็นคำใบ้เพื่อเร่งการถอดรหัสหรือ การยืนยัน หรือเพื่อเลือกคีย์การลงนามในสถานการณ์ก่อนแฮชของการลงนาม

AEAD

โดยทั่วไป Tink จะจัดรูปแบบข้อความที่เข้ารหัส AEAD ดังนี้

prefix || IV || ciphertext || tag

เว้นแต่จะระบุไว้เป็นอย่างอื่นใน RFC ที่เกี่ยวข้อง prefix จะว่างเปล่า หรือเป็นคำนำหน้าเอาต์พุต Tink ขนาด 5 ไบต์

AES-CTR-HMAC

สำหรับ AES-CTR-HMAC นั้น Tink จะคำนวณ MAC ด้วยข้อมูลที่เชื่อมโยง (AD) ดังนี้

AD || IV || ciphertext || bitlen(AD)

โดย bitlen(AD) คือความยาวของ AD ในหน่วยบิต ซึ่งแสดงเป็นจำนวนเต็มแบบไม่มีเครื่องหมาย 64 บิตแบบ Big-Endian รูปแบบ HMAC นี้เป็นไปตามร่างสำหรับ AES-CBC-HMAC จาก Mcgrew

AEAD ที่กำหนด

Tink ใช้ RFC 5297 สำหรับ AES-SIV โดยวางเวกเตอร์เริ่มต้นสังเคราะห์ (SIV) ไว้ที่จุดเริ่มต้นของข้อความที่เข้ารหัส Primitive อาจเพิ่มคำนำหน้าเอาต์พุต Tink ขนาด 5 ไบต์

แม้ว่า RFC 5297 จะรองรับรายการข้อมูลที่เชื่อมโยง แต่ Tink รองรับข้อมูลที่เชื่อมโยงเพียงรายการเดียวเท่านั้น ซึ่งสอดคล้องกับรายการที่มีองค์ประกอบ 1 รายการใน RFC 5297 ข้อมูลที่เชื่อมโยงที่ว่างเปล่าคือรายการที่มีองค์ประกอบว่างเปล่า 1 รายการ ไม่ใช่รายการว่างเปล่า

AEAD แบบสตรีมมิง

ดู AES-CTR HMAC และ AES-GCM-HKDF

การเข้ารหัสแบบ Envelope

การเข้ารหัสซองจดหมายจะเข้ารหัสข้อมูลด้วยคีย์การเข้ารหัสข้อมูล DEK โดยใช้ Primitive AEAD ของ Tink การเข้ารหัสทำงานดังนี้

  • ระบบจะสร้าง DEK ใหม่โดยใช้เทมเพลตคีย์ (หรือพารามิเตอร์คีย์) ที่ระบุ
  • ระบบจะแปลง DEK เป็นสตริงไบต์ รูปแบบการซีเรียลไลซ์ การซีเรียลไลซ์ Protocol Buffer ของ Proto ประเภทคีย์ ตัวอย่างเช่น นี่คือ ข้อความบัฟเฟอร์โปรโตคอลAesGcmKeyที่ซีเรียลไลซ์ซึ่งกำหนดไว้ใน aes_gcm.proto สำหรับ DEK ของคีย์ประเภท AES GCM ดูวิธีซีเรียลไลซ์ Protocol Buffer ได้ที่การซีเรียลไลซ์ Protocol Buffer
  • DEK ที่แปลงเป็นอนุกรมจะได้รับการเข้ารหัสโดยผู้ให้บริการภายนอก (เช่น GCP) เป็น encrypted DEK
  • DEK ใช้เพื่อเข้ารหัสข้อความธรรมดาพร้อมข้อมูลที่เกี่ยวข้องเป็น ciphertext ดังนั้น ciphertext จึงมีรูปแบบเดียวกับ Primitive AEAD ที่สอดคล้องกับ DEK

รูปแบบเอาต์พุตของการเข้ารหัสสองชั้นมีดังนี้

encrypted DEK length || encrypted DEK || ciphertext

encrypted DEK length มีขนาด 4 ไบต์ ซึ่งจัดเก็บความยาวของ encrypted DEK เป็นจำนวนเต็มแบบ 32 บิตแบบ Big-Endian

MAC

Tink เป็นไปตาม RFC ที่เกี่ยวข้อง Primitive อาจเพิ่มเอาต์พุต Tink ขนาด 5 ไบต์ นำหน้าแท็ก

ชุด PRF

Tink เป็นไปตาม RFC ที่เกี่ยวข้อง โปรดทราบว่าสำหรับ PRF ชุดประเภทคีย์จะแตกต่าง จากประเภทคีย์ MAC ของอัลกอริทึมเดียวกันโดยไม่มีความยาวเอาต์พุต คีย์ชุด PRF จะไม่เพิ่มคำนำหน้าเอาต์พุต Tink ซึ่งจะช่วยให้มั่นใจได้ว่าเอาต์พุตเป็น PRF จริงๆ

การเข้ารหัสแบบผสม

รูปแบบการส่งผ่านข้อมูลทั่วไปสำหรับการเข้ารหัสแบบไฮบริดของ Tink มีดังนี้

prefix || encapsulated_key || encrypted_data

prefix ว่างเปล่าหรือเป็นคำนำหน้าเอาต์พุต Tink ขนาด 5 ไบต์ คีย์แต่ละประเภทจะมี ข้อมูลเกี่ยวกับจำนวนไบต์ที่จะแยกวิเคราะห์ และวิธีแยกวิเคราะห์ไบต์เหล่านั้นจาก encapsulated_key

HPKE (การเข้ารหัสคีย์สาธารณะแบบผสม)

Tink เป็นไปตามมาตรฐาน HPKE ที่กำหนดไว้ใน RFC 9180 ชุดการเข้ารหัส HPKE มีองค์ประกอบพื้นฐาน 3 อย่างต่อไปนี้

  • กลไกการห่อหุ้มข้อมูลคีย์ (KEM)
  • ฟังก์ชันการได้คีย์ (KDF)
  • การเข้ารหัสที่ตรวจสอบสิทธิ์พร้อมข้อมูลที่เชื่อมโยง (AEAD)

มาตรฐาน HPKE ไม่ได้กำหนดรูปแบบการส่งข้อมูลทั่วไปใน RFC 9180 ส่วนที่ 10 การติดตั้งใช้งาน HPKE ของ Tink ใช้ค่าต่อไปนี้ encapsulated_key และ encrypted_data

  • encapsulated_key
    • คีย์สาธารณะที่แปลงเป็นอนุกรมของผู้ส่ง
    • กำหนดเป็น enc ใน RFC 9180 ส่วนที่ 4.1
    • รูปแบบที่กำหนดโดย KEM ของ HPKE ที่เฉพาะเจาะจงที่ใช้
  • encrypted_data
    • ข้อความที่เข้ารหัสและแท็ก (เช่น ciphertext || tag โดยไม่มี IV)
    • กำหนดเป็น ct ใน RFC 9180 ส่วนที่ 4
    • รูปแบบที่กำหนดโดย HPKE AEAD ที่เฉพาะเจาะจงที่ใช้
KEM ที่อิงตาม X25519 Diffie-Hellman

สำหรับ DHKEM ของ X25519 ค่า enc คือคีย์สาธารณะ Diffie-Hellman ขนาด 32 ไบต์ของผู้ส่ง

ECIES-AEAD-HKDF

สำหรับการติดตั้งใช้งาน ECIES-AEAD-HKDF ของ Tink 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 ที่เกี่ยวข้อง Primitive อาจเพิ่มคำนำหน้าเอาต์พุต Tink ขนาด 5 ไบต์ ลงในแท็กที่สร้างขึ้น

ECDSA

รูปแบบของลายเซ็น ECDSA จะเป็น IEEE P1363 หรือ ASN.1 DER ขึ้นอยู่กับฟิลด์ EcdsaSignatureEncoding ในคีย์

รูปแบบของIEEE P1363ลายเซ็นคือ r || s โดยที่ r และ s จะมีการเพิ่ม 0 และมีขนาดเป็นไบต์เท่ากับลำดับของเส้นโค้ง เช่น สำหรับเส้นโค้ง NIST P-256 r และ s จะมีการเพิ่ม 0 เพื่อให้มีขนาด 32 ไบต์

ระบบจะเข้ารหัสลายเซ็น DER โดยใช้ ASN.1

ECDSA-Sig-Value :: = SEQUENCE { r INTEGER, s INTEGER }

โดยเฉพาะอย่างยิ่ง การเข้ารหัสมีลักษณะดังนี้

0x30 || totalLength || 0x02 || r's length || r || 0x02 || s's length || s

Tink ปฏิบัติตามแนวทางปฏิบัติแนะนำสำหรับการยืนยันลายเซ็น โดยยอมรับเฉพาะลายเซ็น ECDSA ที่เข้ารหัส DER เท่านั้น (ลายเซ็นที่เข้ารหัส BER อื่นๆ ไม่ถูกต้อง)

ซึ่งจะช่วยป้องกันการโจมตีโดยการดัดแปลงลายเซ็น ซึ่งมักจะส่งผลกระทบต่อ ระบบสกุลเงินดิจิทัล

ค่าแฮชล่วงหน้าของ Mu ML-DSA ภายนอก

Primitive Prehash จะเปลี่ยนข้อความเป็นค่า prehash ซึ่ง Primitive SignPrehash จะลงนามในภายหลัง สำหรับ ML-DSA ในโหมด External Mu ตามที่อธิบายไว้ใน RFC 9881 ค่าก่อนแฮชคือ 69 ไบต์โดยมี เลย์เอาต์ต่อไปนี้

0xff || key_id (4 bytes, big-endian) || mu (64 bytes)
  • mu คือตัวแทนข้อความ ML-DSA ซึ่งคำนวณได้เป็น SHAKE256(tr || 0x00 || 0x00 || message, 64) โดยที่ tr คือแฮช 64 ไบต์ ของคีย์สาธารณะ 0x00 ตัวแรกคือตัวคั่นโดเมน FIPS 204 สำหรับ ML-DSA แบบเพียว และ 0x00 ตัวที่สองคือความยาวของสตริงบริบท (ว่าง) เนื่องจาก tr ได้มาจากคีย์สาธารณะ mu จึงเชื่อมโยงกับคีย์ดังกล่าวด้วยการเข้ารหัส แม้ว่าการตรวจสอบการเชื่อมโยง จะต้องใช้ข้อความต้นฉบับก็ตาม
  • คำนำหน้า 5 ไบต์คือการจัดเฟรม Tink ไม่ใช่ส่วนหนึ่งของ mu โดยจะเชื่อมโยงค่าก่อนแฮชกับคีย์ที่เฉพาะเจาะจง เพื่อให้ SignPrehash รู้ว่าควรใช้คีย์ใดในการลงนาม และสามารถปฏิเสธค่าก่อนแฮชที่ไม่มีคีย์ คำนำหน้า เป็นข้อมูลเมตาธรรมดาและไม่ได้เชื่อมโยงอะไรด้วยการเข้ารหัส ทุกคนสามารถเขียน คำนำหน้านี้ใหม่ได้

การลงนามจะปฏิเสธอินพุตใดๆ ที่ไม่ใช่ 69 ไบต์พอดี ไม่ได้เริ่มต้นด้วย 0xff หรือมีรหัสคีย์ไม่ตรงกับคีย์ที่เปิดใช้ในชุดคีย์