Score:1

ความยาวเอาต์พุต AES ไม่ใช่ผลคูณของ 16 เสมอไป

ธง ng

ฉันมีโซลูชัน C# ที่เข้ารหัสข้อมูลขนาดเล็กจำนวนมากโดยใช้ AES

        // นี่คือวิธีที่ฉันกำหนดค่าวัตถุ Aes
        var aes = Aes สร้าง ();
        aes.Mode = CipherMode.CBC;
        aes.KeySize = 256;
        aes.Padding = PaddingMode.PKCS7;

จากนั้นฉันเขียนไบต์ไซเฟอร์เท็กซ์ดิบไปยังคอลัมน์ SQL Server VARBINARY

การสอบถามความยาวของคอลัมน์ข้อความรหัส VARBINARY เหล่านี้ฉันคาดว่ามันจะเป็นผลคูณของ 16 ไบต์เสมอ อย่างไรก็ตามนั่นดูเหมือนจะไม่เป็นเช่นนั้นที่นี่

ฉันพยายามอ่านเกี่ยวกับเรื่องนี้ทางออนไลน์และคำถามเดียวที่ฉันพบคือถามว่าทำไม AES ciphertext ถึงบุดมากถึง 16 บล็อกไบต์ ดังนั้นฉันคิดว่าฉันจะถามเกี่ยวกับคำถามผกผันที่นี่

หมายเหตุ:

  • ฉันทดสอบการถอดรหัสหนึ่งในข้อความเข้ารหัสที่มีขนาดผิดปกติเหล่านี้ และมันก็ใช้ได้ดี ดังนั้นข้อความเข้ารหัสจึงไม่ผิดรูปแบบ
  • ฉันสังเกตเห็นว่ามันไม่ได้เกิดขึ้นบ่อยๆ ในรอบเดียวมันเกิดขึ้น 19 ครั้งจาก 5,828 ครั้ง
  • เมื่อมันเกิดขึ้น มันจะออกทีละหนึ่งเสมอ (31 แทนที่จะเป็น 32, 767 แทนที่จะเป็น 768 ฯลฯ..)

ฉันมีความคิดว่าบางทีมาตรฐาน AES อาจตัดทอน cipher-bytes ที่เป็นศูนย์ (หรือตัวเลขอื่น ๆ ที่รู้จักกันดี) จากจุดสิ้นสุดของเอาต์พุตเนื่องจากตัวถอดรหัสสามารถสร้างใหม่ได้ แต่ชอบการชี้แจง

Score:4
ธง my

คุณถูก; AES-CBC มาตรฐาน (ไม่มีการขโมยข้อความรหัส) มีเอาต์พุตที่มีความยาวหลายเท่าของ 16 ไบต์เสมอ

ความเป็นไปได้อย่างหนึ่งที่เกิดขึ้นกับฉันคือหากการใช้งาน AES ของคุณมีข้อผิดพลาดคือหากไบต์สุดท้ายเป็น 0x00 ก็จะไม่แสดงผลจริง (และในทิศทางการถอดรหัส หากข้อความเข้ารหัสสั้นเพียงหนึ่งไบต์ ก็จะ โดยปริยายเพิ่ม 0x00)

หากสมมติฐานนี้เป็นจริง ในกรณีทดสอบ 5,828 รายการของคุณ เราคาดว่าจะเห็นไซเฟอร์เท็กซ์ไบต์สุดท้ายเป็น 0 (และด้วยเหตุนี้จึงถูกตัดทอน) เท่ากับ 22.8 เท่าตามที่คาดไว้ 19 ครั้งอยู่ในค่าเบี่ยงเบนมาตรฐาน ดังนั้นมันจึงเป็นไปได้...

Maarten Bodewes avatar
in flag
โปรดทราบว่าในกรณีนั้น คุณอาจมี off-byte สองครั้งใน 65536 (ซึ่งเป็นไปได้ว่าคุณยังไม่เคยพบมัน) ลดลง 3 ครั้งใน ~4 พันล้าน เป็นต้น แค่บอกว่าเพราะการเพิ่มหนึ่งไบต์อาจไม่สามารถแก้ไขได้ ปัญหา (หากจำเป็นต้องแก้ไข) ฉันยังพบปัญหามากมายเกี่ยวกับการทดสอบขนาดไบนารี เช่น การเรียกข้อมูลไบนารีแล้วทดสอบขนาดโดยใช้ฟังก์ชันแบบสตริง (เช่น `strlen` ใน C) อันที่จริง ฉันคิดว่ามันเป็นไปได้มากกว่าข้อผิดพลาดในรูทีนการเข้ารหัส/ถอดรหัส แม้ว่าการใช้งานใน DB ส่วนใหญ่จะแย่มากเช่นกัน
ng flag
ฉันดึงหนึ่งในค่าที่ SQL Server อ้างสิทธิ์คือ 31 ไบต์ แต่ค่าที่ส่งคืนคือ 32 hexpairs ดังนั้นฉันคิดว่า @MaartenBodewes ถูกต้องและ SQL Server รายงานความยาวผิดจริง ๆ เมื่อฉันใช้ฟังก์ชัน LEN สิ่งที่ฉันพบว่าน่าสนใจกว่าคือไบต์สุดท้ายในสิ่งเหล่านี้ทั้งหมดไม่ใช่ 00 แต่เป็น 20 ซึ่งฉันเชื่อว่าเป็นอักขระเว้นวรรค ASCII LEN อาจถือว่ามันเป็นสตริงและพยายามตัดสตริงอัตโนมัติหรือไม่ ไม่ว่าในกรณีใด ฉันคิดว่านี่ไม่ใช่คำถามเกี่ยวกับการเข้ารหัสลับอีกต่อไป แก้ไข: เพิ่งเรียนรู้เกี่ยวกับฟังก์ชัน DATALENGTH ซึ่งเป็นสิ่งที่ฉันควรใช้
Score:0
ธง ng

ตกลง อย่างที่คนอื่นๆ ระบุว่ามาตรฐานจะสร้างข้อความไซเฟอร์เท็กซ์ที่มีความยาวหลายเท่าของ 16 ไบต์เสมอ ปัญหาคือเมื่อฉันวัดความยาว ฉันใช้ฟังก์ชัน T-SQL LEN ซึ่งดูเหมือนว่าจะตัด 0x20 ไบต์ออกจากจุดสิ้นสุดของลำดับไบนารีเมื่อวัดความยาว

ตอนนี้ฉันได้เรียนรู้ว่าฉันควรใช้ฟังก์ชัน DATALENGTH ซึ่งไม่ได้ทำการตัดส่วนนี้ และเมื่อฉันลองใช้ค่าทั้งหมดจะเป็นทวีคูณของ 16

ขอโทษสำหรับความสับสน!

Morrolan avatar
ng flag
เพื่อชี้แจง - นั่นคือแม้แต่พฤติกรรม ** ที่คาดไว้ ** (แม้ว่าจะแปลกประหลาด) ของ T-SQL: "LEN ไม่รวมช่องว่างต่อท้าย" ตามตัวอย่าง [เอกสารอย่างเป็นทางการ](https://docs.microsoft.com/en-us/sql/t-sql/functions/len-transact-sql?view=sql-server-ver15#remarks)
ng flag
ใช่นั่นสมเหตุสมผลกว่ามาก ขอบคุณ @Morrolan

โพสต์คำตอบ

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