รูปแบบสาย Tink

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

การเรียงอันดับชุดคีย์

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

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

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

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

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

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

โปรดทราบว่าคำนำหน้านี้ไม่ได้รับการตรวจสอบสิทธิ์และไม่สามารถใช้เพื่อวัตถุประสงค์ด้านความปลอดภัยได้ 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 บิต บิ๊กเอนเดียน รูปแบบ HMAC นี้เป็นไปตามร่างสำหรับ AES-CBC-HMAC จาก Mcgrew

AEAD ที่กำหนด

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

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

Streaming AEAD

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

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

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

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