pseudorandom และสุ่มตัวเลขแตกต่างกันอย่างแท้จริงอย่างไรและทำไมจึงมีความสำคัญ?


665

ฉันไม่เคยได้รับสิ่งนี้เลย เพียงแค่พูดว่าคุณเขียนโปรแกรมเล็ก ๆ ในภาษาใดก็ได้ที่หมุนลูกเต๋าบางส่วน (เพียงใช้ลูกเต๋าเป็นตัวอย่าง) หลังจาก 600,000 ม้วนแต่ละหมายเลขจะถูกม้วนประมาณ 100,000 ครั้งซึ่งเป็นสิ่งที่ฉันคาดหวัง

ทำไมถึงมีเว็บไซต์ที่ทุ่มเทให้กับ 'การสุ่มอย่างแท้จริง'? แน่นอนว่าจากการสังเกตข้างต้นโอกาสที่จะได้รับหมายเลขใด ๆ นั้นมีค่าเกือบ 1 ว่ามีกี่หมายเลขที่สามารถเลือกได้

ฉันลองใช้Python : นี่คือผลลัพธ์ของม้วน 60 ล้าน ความแปรปรวนสูงสุดเท่ากับ 0.15 ไม่ว่าจะเป็นแบบสุ่มที่จะได้รับ?

1 - 9997653 2347.0
2 - 9997789 2211.0
3 - 9996853 3147.0
4 - 10006533 -6533.0
5 - 10002774 -2774.0
6 - 9998398 1602.0

1
ลองดูที่บทความของวิกิพีเดียเกี่ยวกับฮาร์ดแวร์ที่สร้างตัวเลขสุ่มดูได้ที่ - stats.stackexchange.com/questions/32794/…
— steadyfish

21
คุณหมายถึงอะไรโดย "ทอยลูกเต๋า"? มีแขนหุ่นยนต์และกล้องติดอยู่หรือไม่?
— starblue

3
ในขณะที่ฉันเห็นด้วยกับแก่นสารทั่วไปของน้ำเสียงของคุณเรามักจะกังวลเกี่ยวกับเรื่องนี้มากเกินไป แต่มันถูกเอาเปรียบในชีวิตจริง: en.wikipedia.org/wiki/Ronald_Dale_Harris
— ผู้เล่นเกรดี้

3
ดูนี้บทความเกี่ยวกับเกมโป๊กเกอร์ออนไลน์ที่ขาดหายไปตามบุญตามกรรมที่แท้จริงว่าทำไมมันเป็นเรื่องสำคัญ
— Varaquilex

1
หากคุณวางเคาน์เตอร์ 0-5 และหมุนลูกเต๋า 666 ล้านล้านครั้งคุณก็จะได้การแจกแจงที่เท่าเทียมกัน
— jcora

คำตอบ:


1384

มาเล่นโป๊กเกอร์คอมพิวเตอร์กันเถอะแค่คุณฉันและเซิร์ฟเวอร์ที่เราทั้งคู่ไว้วางใจ เซิร์ฟเวอร์ใช้ตัวสร้างตัวเลขสุ่มหลอกซึ่งเริ่มต้นด้วยเมล็ด 32 บิตก่อนที่เราจะเล่น ดังนั้นจึงมีดาดฟ้าที่เป็นไปได้ประมาณสี่พันล้านชั้น

ฉันได้ไพ่ห้าใบในมือ - ดูเหมือนว่าเราไม่ได้เล่น Texas Hold 'Em สมมติว่าไพ่ถูกแจกให้ฉันหนึ่งใบกับคุณหนึ่งใบกับฉันหนึ่งใบให้กับคุณและอื่น ๆ ดังนั้นฉันมีไพ่ใบที่หนึ่ง, สาม, ห้า, เจ็ดและเก้าในสำรับ

ก่อนหน้านี้ฉันใช้ตัวสร้างตัวเลขสุ่มหลอกสี่พันล้านครั้งต่อหนึ่งเมล็ดและเขียนการ์ดใบแรกที่สร้างขึ้นสำหรับแต่ละการ์ดลงในฐานข้อมูล สมมติว่าไพ่ใบแรกของฉันคือราชินีแห่งโพดำ นั่นแสดงให้เห็นเพียงใบเดียวว่าเป็นบัตรใบแรกในหนึ่งใบในทุก ๆ 52 ของสำรับที่เป็นไปได้ดังนั้นเราจึงลดจำนวนสำรับที่เป็นไปได้จากสี่พันล้านเป็นประมาณ 80 ล้านหรือมากกว่านั้น

สมมติว่าไพ่ใบที่สองของฉันคือหัวใจทั้งสาม ตอนนี้ฉันใช้ RNG ของฉัน 80 ล้านครั้งโดยใช้เมล็ด 80 ล้านที่ผลิตราชินีแห่งโพดำเป็นหมายเลขแรก ใช้เวลาสองสามวินาที ฉันจดทุกสำรับที่สร้างหัวใจทั้งสามเป็นไพ่ใบที่สาม - ไพ่ใบที่สองในมือของฉัน นั่นเป็นเพียงประมาณ 2% ของดาดฟ้าดังนั้นตอนนี้เราลงไปถึง 2 ล้านชั้น

สมมติว่าไพ่ใบที่สามในมือของฉันคือ 7 ของสโมสร ฉันมีฐานข้อมูล 2 ล้านเมล็ดที่แจกไพ่สองใบของฉัน ฉันใช้ RNG ของฉันอีก 2 ล้านครั้งเพื่อค้นหา 2% ของเด็คเหล่านั้นที่ผลิต 7 ของคลับเป็นการ์ดใบที่สามและเราลงเหลือเพียง 40,000 เด็ค

คุณเห็นว่าสิ่งนี้เกิดขึ้นได้อย่างไร ฉันวิ่ง RNG ของฉัน 40000 ครั้งเพื่อหาเมล็ดทั้งหมดที่ผลิตไพ่ใบที่สี่ของฉันและนั่นทำให้เราลงไปที่ 800 ชั้นจากนั้นเรียกใช้อีก 800 ครั้งเพื่อรับเมล็ด ~ 20 ที่ผลิตไพ่ใบที่ห้าของฉันและตอนนี้ฉันแค่ สร้างไพ่ยี่สิบสำรับเหล่านั้นและฉันรู้ว่าคุณมีหนึ่งในยี่สิบมือที่เป็นไปได้ ยิ่งกว่านั้นฉันมีความคิดที่ดีมากเกี่ยวกับสิ่งที่ฉันจะวาดต่อไป

ตอนนี้คุณเห็นหรือไม่ว่าทำไมการสุ่มตัวอย่างที่แท้จริงจึงสำคัญ วิธีที่คุณอธิบายคุณคิดว่าการกระจายนั้นสำคัญ แต่การกระจายไม่ใช่สิ่งที่ทำให้กระบวนการสุ่ม ความไม่แน่นอนคือสิ่งที่ทำให้กระบวนการสุ่ม

UPDATE

จากความคิดเห็น (ตอนนี้ถูกลบเนื่องจากความไม่เป็นธรรม) พวกเขาอย่างน้อย 0.3% ของผู้ที่เคยอ่านสิ่งนี้จะสับสนในประเด็นของฉัน เมื่อผู้คนโต้เถียงกับจุดที่ฉันไม่ได้ทำหรือแย่กว่านั้นโต้เถียงกับจุดที่ฉันได้ทำบนสมมติฐานที่ว่าฉันไม่ได้ทำให้พวกเขาแล้วฉันรู้ว่าฉันต้องอธิบายให้ชัดเจนยิ่งขึ้นและระมัดระวัง

ดูเหมือนจะมีความสับสนเป็นพิเศษเกี่ยวกับการกระจายคำดังนั้นฉันจึงต้องการเรียกใช้การอย่างระมัดระวัง

คำถามในมือคือ:

  • ตัวเลขหลอกเทียมและตัวเลขสุ่มแตกต่างกันอย่างไร
  • ทำไมความแตกต่างจึงสำคัญ
  • ความแตกต่างมีบางอย่างเกี่ยวกับการกระจายเอาต์พุตของ PRNG หรือไม่?

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

TRNGขอเริ่มต้นด้วยการสมมติว่าเราได้กล่องวิเศษที่มีป้ายกำกับ เมื่ออินพุตของมันเราให้จำนวนเต็ม n มากกว่าหรือเท่ากับหนึ่งและเป็นผลลัพธ์มันให้ตัวเลขสุ่มอย่างแท้จริงระหว่างหนึ่งถึง n รวม เอาท์พุทของกล่องนั้นคาดเดาไม่ได้อย่างสมบูรณ์ (เมื่อได้รับตัวเลขอื่นที่ไม่ใช่หนึ่ง) และตัวเลขใด ๆ ระหว่างหนึ่งและ n มีโอกาสเป็นอื่น ที่จะบอกว่าการจัดจำหน่ายเป็นชุด (มีการตรวจสอบทางสถิติขั้นสูงอื่น ๆ เพิ่มเติมของการสุ่มที่เราสามารถทำได้; ฉันไม่สนใจจุดนี้เพราะมันไม่ใช่สิ่งที่ขัดแย้งกับข้อโต้แย้งของฉัน TRNG นั้นสุ่มอย่างสมบูรณ์ทางสถิติโดยการสันนิษฐาน)

เราเริ่มต้นด้วยสำรับไพ่ที่ไม่มีการสับ เราถามกล่องถึงตัวเลขระหว่างหนึ่งถึง 52 นั่นคือ, TRNG(52). ไม่ว่าจะให้เบอร์ใดเราก็นับจำนวนไพ่ที่ได้จากการเรียงไพ่ของเราและนำการ์ดนั้นออก มันจะกลายเป็นไพ่ใบแรกในสำรับสับไพ่ จากนั้นเราจะขอTRNG(51)และทำเช่นเดียวกันเพื่อเลือกไพ่ใบที่สองเป็นต้น

อีกวิธีในการดูคือ: มี 52! = 52 x 51 x 50 ... x 2 x 1 ชั้นเป็นไปได้ซึ่งเป็นประมาณ 2 226 เราได้เลือกหนึ่งในนั้นโดยการสุ่มอย่างแท้จริง

ตอนนี้เราแจกการ์ด เมื่อฉันดูไพ่ฉันไม่รู้ว่าการ์ดอะไรที่คุณมี (นอกเหนือจากความจริงที่ชัดเจนว่าคุณไม่มีการ์ดใด ๆ ที่ฉันมี) พวกเขาอาจเป็นการ์ดใดก็ได้โดยมีความน่าจะเป็นเท่ากัน

ขอผมอธิบายให้ชัดเจนนะ ขณะนี้มีการกระจายสม่ำเสมอของการส่งออกของแต่ละบุคคลของTRNG(n); แต่ละอันเลือกตัวเลขระหว่าง 1 ถึง n โดยมีความน่าจะเป็น 1 / n นอกจากนี้ผลลัพธ์ของกระบวนการนี้ก็คือเราได้เลือกหนึ่งใน 52! ชั้นไปได้ด้วยความน่าจะเป็นของ 1/52 !, เพื่อการจัดจำหน่ายที่มากกว่าชุดของชั้นที่เป็นไปได้คือยังเครื่องแบบ

เอาล่ะ

PRNGตอนนี้ขอสมมติว่าเรามีกล่องวิเศษน้อยที่มีป้ายกำกับ ก่อนที่คุณจะสามารถใช้งานได้นั้นจะต้องได้เมล็ดมีจำนวนที่ไม่ได้ลงชื่อ 32 บิต

นอกเหนือ: ทำไม 32 ? ไม่สามารถทำการเพาะด้วยหมายเลข 64- หรือ 256- หรือ 10,000- บิต? แน่ใจ แต่ในทางปฏิบัติ (1) PRNG ส่วนใหญ่นั้นมีจำนวน 32 บิตและ (2) ถ้าคุณมีการสุ่ม 10,000 บิตเพื่อสร้างเมล็ดแล้วทำไมคุณถึงใช้ PRNG เลย? คุณมีแหล่งสุ่ม 10,000 บิตอยู่แล้ว!

อย่างไรก็ตามกลับไปที่วิธีการทำงานของ PRNG: TRNGหลังจากที่มีเมล็ดคุณสามารถใช้วิธีเดียวกันกับที่คุณใช้ นั่นคือคุณผ่านตัวเลข n และมันให้ตัวเลขกลับคืนระหว่าง 1 ถึง n รวม นอกจากนี้การกระจายตัวของการส่งออกว่าจะมากหรือน้อยเครื่องแบบ นั่นคือเมื่อเราขอPRNGตัวเลขระหว่าง 1 ถึง 6 เราจะได้ 1, 2, 3, 4, 5 หรือ 6 แต่ละครั้งประมาณหนึ่งในหกของเวลาไม่ว่าเมล็ดจะเป็นอะไรก็ตาม

ฉันต้องการเน้นจุดนี้หลายครั้งเพราะดูเหมือนว่าเป็นสิ่งที่ทำให้ผู้แสดงความคิดเห็นบางคนสับสน การกระจายตัวของ PRNG นั้นเหมือนกันอย่างน้อยสองวิธี อันดับแรกสมมติว่าเราเลือกเมล็ดเฉพาะ เราคาดหวังว่าลำดับPRNG(6), PRNG(6), PRNG(6)...ต่อล้านครั้งจะทำให้เกิดการกระจายตัวของตัวเลขอย่างสม่ำเสมอระหว่าง 1 ถึง 6 และสองถ้าเราเลือกเมล็ดที่แตกต่างกันหนึ่งล้านเมล็ดและเรียกPRNG(6) หนึ่งครั้งสำหรับแต่ละเมล็ด 6. สม่ำเสมอของ PRNG ทั่วทั้งของการดำเนินงานเหล่านี้ไม่ได้เกี่ยวข้องกับการโจมตีฉันกำลังอธิบาย

กระบวนการนี้มีการกล่าวถึงว่าเป็นการหลอกแบบสุ่มเพราะพฤติกรรมของกล่องนั้นเป็นสิ่งที่กำหนดอย่างแท้จริง มันเลือกจากหนึ่งใน 2 32พฤติกรรมที่เป็นไปได้ขึ้นอยู่กับเมล็ด นั่นคือเมื่อมันเมล็ดPRNG(6), PRNG(6), PRNG(6), ... ผลิตลำดับของตัวเลขที่มีการกระจายชุด แต่ลำดับที่ทั้งหมดถูกกำหนดโดยเมล็ด สำหรับลำดับการโทรที่กำหนดให้พูด PRNG (52), PRNG (51) ... และอื่น ๆ มีเพียง 2 32ลำดับที่เป็นไปได้ เมล็ดเป็นหลักเลือกที่เราจะได้รับ

เพื่อสร้างเด็คในขณะนี้เซิร์ฟเวอร์สร้างเมล็ด (ได้อย่างไรเราจะกลับมาที่จุดนั้น) จากนั้นพวกเขาก็โทรPRNG(52)มาPRNG(51)และอื่น ๆ เพื่อสร้างสำรับคล้ายกับก่อนหน้านี้

ระบบนี้ไวต่อการโจมตีที่ฉันอธิบาย ในการโจมตีเซิร์ฟเวอร์ก่อนอื่นให้เราคัดลอกสำเนาของกล่องของเราด้วย 0 และขอPRNG(52)และเขียนลงไป จากนั้นเราก็เติมเมล็ดด้วย 1 ขอPRNG(52)และเขียนลงไปจนถึง 2 32 -1

ทีนี้เซิร์ฟเวอร์โปกเกอร์ที่ใช้ PRNG ในการสร้างเด็คต้องทำการสร้างเมล็ดอย่างใด มันไม่สำคัญว่าพวกเขาจะทำเช่นนั้นได้อย่างไร พวกเขาสามารถเรียกTRNG(2^32)เพื่อให้ได้เมล็ดสุ่มอย่างแท้จริง หรือพวกเขาอาจใช้เวลาปัจจุบันเป็นเมล็ดพันธุ์ซึ่งแทบจะไม่สุ่มเลย ฉันรู้ว่าเวลาเท่าไหร่ที่คุณทำ จุดของการโจมตีของฉันก็คือว่ามันไม่สำคัญเพราะฉันมีฐานข้อมูลของฉัน เมื่อฉันเห็นการ์ดใบแรกของฉันฉันสามารถกำจัด 98% ของเมล็ดที่เป็นไปได้ เมื่อฉันเห็นไพ่ใบที่สองของฉันฉันสามารถกำจัดได้มากขึ้น 98% และต่อ ๆ ไปจนกระทั่งในที่สุดฉันก็สามารถลงมือหยิบเมล็ดที่เป็นไปได้และรู้ว่ามีโอกาสสูงที่คุณจะได้รับ

ตอนนี้อีกครั้งผมอยากจะเน้นว่าสมมติฐานที่นี่คือถ้าเราเรียกว่าPRNG(6)ล้านครั้งเราจะได้รับในแต่ละจำนวนประมาณหนึ่งในหกของเวลา การกระจายนั่นคือเครื่องแบบ (มากหรือน้อย) และถ้าความสม่ำเสมอของการกระจายนั่นคือสิ่งที่คุณใส่ใจนั่นก็ดี ประเด็นของคำถามคือมีอะไรอีกPRNG(6)บ้างที่การกระจายของสิ่งที่เราใส่ใจ และคำตอบคือใช่ เราใส่ใจเรื่องความคาดเดาไม่ได้เช่นกัน

อีกวิธีหนึ่งในการดูปัญหาคือแม้ว่าการกระจายการโทรหนึ่งล้านครั้งPRNG(6)อาจใช้ได้เนื่องจาก PRNG เลือกจากพฤติกรรมที่เป็นไปได้เพียง 2 32แต่ก็ไม่สามารถสร้างเด็คที่เป็นไปได้ทั้งหมด มันสามารถสร้าง 2 32จาก 2 226ดาดฟ้าที่เป็นไปได้เท่านั้น เศษเสี้ยวเล็ก ๆ ดังนั้นการกระจายตัวของฉากทั้งหมดจึงแย่มาก แต่อีกครั้งการโจมตีขั้นพื้นฐานที่นี่ขึ้นอยู่กับความสามารถของเราในการทำนายพฤติกรรมในอดีตและอนาคตของPRNGตัวอย่างผลลัพธ์ที่ได้

ขอผมใช้นี่เป็นเวลาสามหรือสี่ครั้งเพื่อให้แน่ใจว่าอ่างล้างมือนี้มีการแจกแจงสามแบบตรงนี้ ก่อนการกระจายของกระบวนการที่สร้างเมล็ดพันธุ์แบบสุ่ม 32 บิต ที่สามารถเป็นแบบสุ่มสมบูรณ์ไม่แน่นอนและสม่ำเสมอและการโจมตีจะยังคงทำงาน ประการที่สองการกระจายการโทรหนึ่งล้านPRNG(6)ครั้ง นั่นสามารถเป็นชุดที่สมบูรณ์แบบและการโจมตีจะยังคงทำงาน ประการที่สามการกระจายของสำรับที่เลือกโดยกระบวนการหลอกหลอกที่ฉันได้อธิบายไว้ การกระจายตัวนั้นแย่มาก สามารถเลือกสำรับ IRL ที่เป็นไปได้เพียงเล็กน้อยเท่านั้น การโจมตีขึ้นอยู่กับการคาดการณ์ของพฤติกรรมของ PRNG บนพื้นฐานความรู้บางส่วนของการส่งออกของ

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

กำลังเดินทางไป.

CPRNGตอนนี้ขอสมมติว่าเรามีกล่องวิเศษที่สามที่มีป้ายกำกับ PRNGมันเป็นรุ่นการเข้ารหัสลับความแข็งแรงของ ใช้เมล็ด 256 บิตแทนที่จะเป็นเมล็ด 32 บิต มันแบ่งปันกับPRNGคุณสมบัติที่เมล็ดเลือกจากหนึ่งใน 2 256พฤติกรรมที่เป็นไปได้ และเช่นเดียวกับเครื่องอื่น ๆ ของเรามันมีคุณสมบัติที่การโทรจำนวนมากเพื่อCPRNG(n)สร้างการกระจายของผลลัพธ์ที่เหมือนกันระหว่าง 1 ถึง n: แต่ละครั้งเกิดขึ้น 1 / n ของเวลา เราสามารถโจมตีมันได้หรือไม่?

โจมตีเดิมของเราเราต้องเก็บ 2 32PRNG(52)แมปจากเมล็ด แต่ 2 256เป็นจำนวนที่มากกว่า มันเป็นไปไม่ได้เลยที่จะรันCPRNG(52)หลาย ๆ ครั้งและเก็บผลลัพธ์

แต่สมมติว่ามีวิธีอื่นที่จะใช้มูลค่าของCPRNG(52)และจากการอนุมานข้อเท็จจริงเกี่ยวกับเมล็ด? เราค่อนข้างจะโง่เง่ามาก่อน เราสามารถตรวจสอบภายในกล่องเวทมนตร์คิดออกว่ามันทำงานอย่างไรและอนุมานข้อเท็จจริงเกี่ยวกับเมล็ดพันธุ์ตามผลผลิต

เลขที่มีรายละเอียดซับซ้อนเกินไปที่จะอธิบาย แต่ CPRNGs ได้รับการออกแบบอย่างชาญฉลาดเพื่อที่จะเป็นไปไม่ได้ที่จะอนุมานใด ๆ ที่ความเป็นจริงมีประโยชน์เกี่ยวกับเมล็ดพันธุ์จากผลผลิตแรกของCPRNG(52)หรือจากใดส่วนหนึ่งของการส่งออกไม่ว่าขนาดใหญ่

ตกลงดังนั้นตอนนี้สมมติว่าเซิร์ฟเวอร์ใช้CPRNGเพื่อสร้างสำรับ มันต้องการเมล็ด 256 บิต มันเลือกเมล็ดพันธุ์นั้นได้อย่างไร? ถ้ามันเลือกค่าใด ๆ ที่ผู้โจมตีสามารถคาดการณ์แล้วก็โจมตีกลายเป็นที่ทำงานได้อีกครั้ง หากเราสามารถระบุได้ว่ามีเมล็ดที่เป็นไปได้2 256เมล็ดนั้นมีเพียง 4 พันล้านรายการเท่านั้นที่มีแนวโน้มที่จะถูกเลือกโดยเซิร์ฟเวอร์ดังนั้นเราจึงกลับมาทำธุรกิจอีกครั้ง เราสามารถหยุดยั้งการโจมตีนี้ได้อีกครั้งโดยให้ความสนใจกับเมล็ดพันธุ์จำนวนเล็กน้อยที่สามารถสร้างได้

เซิร์ฟเวอร์ดังนั้นจึงควรทำผลงานเพื่อให้มั่นใจว่าจำนวน 256 บิตจะกระจายอย่างสม่ำเสมอ - นั่นคือแต่ละเมล็ดเป็นไปได้คือเลือกด้วยความน่าจะเป็นของ 1/2 256 โดยทั่วไปเซิร์ฟเวอร์ควรจะเรียกการสร้างเมล็ดพันธุ์สำหรับTRNG(2^256)-1CPRNG

ถ้าฉันสามารถแฮ็คเซิร์ฟเวอร์และตรวจสอบเพื่อดูว่ามีการเลือกเมล็ดพันธุ์อะไร ในกรณีที่ผู้บุกรุกรู้ว่าที่ผ่านมาที่สมบูรณ์และอนาคตของ CPRNG ผู้เขียนเซิร์ฟเวอร์จำเป็นต้องป้องกันการโจมตีนี้! (แน่นอนถ้าฉันสามารถประสบความสำเร็จในการโจมตีครั้งนี้ได้ฉันก็สามารถโอนเงินไปยังบัญชีธนาคารของฉันได้โดยตรงดังนั้นอาจไม่น่าสนใจประเด็นคือ: เมล็ดต้องเป็นความลับที่ยากต่อการคาดเดาและ ตัวเลข 256 บิตแบบสุ่มอย่างแท้จริงค่อนข้างยากที่จะเดา)

การย้อนกลับไปยังจุดก่อนหน้าของฉันเกี่ยวกับการป้องกันเชิงลึก: เมล็ด 256 บิตเป็นกุญแจสำคัญในระบบรักษาความปลอดภัยนี้ ความคิดของ CPRNG การให้คือระบบที่มีความปลอดภัยตราบใดที่สำคัญคือการรักษาความปลอดภัย ; แม้ว่าทุก ๆ ข้อเท็จจริงเกี่ยวกับอัลกอริทึมเป็นที่รู้จักกันตราบใดที่คุณสามารถเก็บความลับสำคัญบัตรของฝ่ายตรงข้ามไม่สามารถคาดเดาได้

ตกลงดังนั้นเมล็ดควรจะเป็นความลับและกระจายอย่างสม่ำเสมอเพราะถ้าไม่ใช่เราสามารถโจมตีได้ เรามีสมมุติฐานว่าการกระจายตัวของเอาท์พุตCPRNG(n)มีความสม่ำเสมอ สิ่งที่เกี่ยวกับการกระจายไปทั่วชุดของดาดฟ้าที่เป็นไปได้ทั้งหมดหรือไม่

คุณอาจพูดว่า: CPRNG มี 2 256ผลลัพธ์ที่เป็นไปได้ แต่มีเพียง 2 226ดาดฟ้าที่เป็นไปได้ ดังนั้นจึงมีลำดับที่เป็นไปได้มากกว่าเด็คเราจึงไม่เป็นไร เด็ค IRL ที่เป็นไปได้ทั้งหมดตอนนี้ (มีความเป็นไปได้สูง) ที่เป็นไปได้ในระบบนี้ และนั่นเป็นข้อโต้แย้งที่ดียกเว้น ...

2 226เป็นเพียงการประมาณ 52! แบ่งมันออก 2 256/52 ! ไม่สามารถเป็นจำนวนเต็มได้เพราะอย่างใดอย่างหนึ่ง 52! หารด้วย 3 แต่ไม่มีพลังของสองคือ! ตั้งแต่นี้ไม่ได้เป็นจำนวนทั้งหมดตอนนี้เรามีสถานการณ์ที่ชั้นทุกคนมีความเป็นไปได้แต่ชั้นบางมีแนวโน้มมากขึ้นกว่าคนอื่น ๆ

หากยังไม่ชัดเจนให้พิจารณาสถานการณ์ที่มีตัวเลขน้อยกว่า สมมติว่าเรามีไพ่สามใบ A, B และ C สมมติว่าเราใช้ PRNG กับเมล็ด 8 บิตดังนั้นจึงมี 256 เมล็ดที่เป็นไปได้ มีเอาต์พุตที่เป็นไปได้ 256 รายการPRNG(3)ขึ้นอยู่กับเมล็ด ไม่มีทางที่จะมีหนึ่งในสามของพวกเขาเป็น A, หนึ่งในสามของพวกเขาเป็น B และหนึ่งในสามของพวกเขาเป็น C เพราะ 256 ไม่สามารถหารได้อย่างเท่าเทียมกันโดย 3 จะต้องมีอคติเล็ก ๆ ต่อหนึ่งของพวกเขา

ในทำนองเดียวกัน 52 ไม่ได้แบ่งเท่า ๆ กันเป็น 2 256ดังนั้นจึงต้องมีอคติบางอย่างเมื่อเลือกไพ่ใบแรกและมีอคติห่างจากคนอื่น

ในระบบดั้งเดิมของเราที่มีเมล็ด 32 บิตมีอคติมากและดาดฟ้าที่เป็นไปได้ส่วนใหญ่ไม่เคยถูกสร้างขึ้นมา ในระบบนี้ชั้นทั้งหมดสามารถผลิตได้ แต่การกระจายตัวของชั้นก็ยังคงมีข้อบกพร่อง ชั้นบางคนมีมากขึ้นเล็กน้อยจะมีโอกาสมากกว่าคนอื่น ๆ

ตอนนี้คำถามคือ: เรามีการโจมตีตามข้อบกพร่องนี้หรือไม่? และคำตอบคือในทางปฏิบัติอาจจะไม่ได้ CPRNGs ได้รับการออกแบบเพื่อให้ถ้าเมล็ดเป็นแบบสุ่มอย่างแท้จริงแล้วมันเป็นไปไม่ได้คอมพิวเตอร์ที่จะบอกความแตกต่างระหว่างและCPRNGTRNG

ตกลงดังนั้นมาสรุปกัน

ตัวเลขหลอกเทียมและตัวเลขสุ่มแตกต่างกันอย่างไร

พวกเขาแตกต่างกันในระดับของการคาดการณ์ที่พวกเขาแสดง

  • ตัวเลขสุ่มที่แท้จริงไม่สามารถคาดเดาได้
  • ตัวเลขสุ่มหลอกทั้งหมดสามารถคาดการณ์ได้หากเมล็ดสามารถกำหนดหรือเดาได้

ทำไมความแตกต่างจึงสำคัญ

เนื่องจากมีการใช้งานที่การรักษาความปลอดภัยของระบบที่อิงอยู่กับการคาดการณ์

  • หากใช้ TRNG เพื่อเลือกการ์ดแต่ละใบระบบจะไม่สามารถใช้งานได้
  • หากใช้ CPRNG เพื่อเลือกการ์ดแต่ละใบระบบจะปลอดภัยหากทั้งเมล็ดไม่สามารถคาดเดาได้และไม่ทราบ
  • หากใช้ PRNG ธรรมดาที่มีพื้นที่เมล็ดขนาดเล็กระบบจะไม่ปลอดภัยไม่ว่าเมล็ดนั้นจะคาดเดาไม่ได้หรือไม่ทราบก็ตาม พื้นที่เมล็ดเล็กพอที่จะไวต่อการโจมตีที่โหดร้ายแบบที่ฉันอธิบาย

ความแตกต่างมีส่วนเกี่ยวข้องกับการกระจายเอาต์พุตของ PRNG หรือไม่?

ความสม่ำเสมอของการกระจายหรือขาดมันสำหรับการโทรของแต่ละบุคคลที่จะRNG(n)ไม่เกี่ยวข้องกับการโจมตีที่ผมได้อธิบายไว้

ดังที่เราได้เห็นทั้ง a PRNGและCPRNGสร้างการแจกแจงที่ไม่ดีของความน่าจะเป็นในการเลือกเด็คเดี่ยวของเด็คใด ๆ PRNGเป็นอย่างมากที่เลวร้ายยิ่ง แต่ทั้งสองมีปัญหา

อีกหนึ่งคำถาม:

ถ้า TRNG ดีกว่า CPRNG มากซึ่งดีกว่า PRNG มากทำไมใครใช้ CPRNG หรือ PRNG

ด้วยเหตุผลสองประการ

ครั้งแรก: ค่าใช้จ่าย การฝึกซ้อมเป็นที่มีราคาแพง การสร้างตัวเลขสุ่มอย่างแท้จริงนั้นเป็นเรื่องยาก CPRNG ให้ผลลัพธ์ที่ดีสำหรับการโทรจำนวนมากโดยไม่ตั้งใจด้วยการโทรเพียงครั้งเดียวไปยัง TRNG สำหรับเมล็ด แน่นอนว่าคุณต้องเก็บความลับเอาไว้

ประการที่สอง: บางครั้งเราต้องการการคาดการณ์และสิ่งที่เราใส่ใจคือการกระจายที่ดี หากคุณกำลังสร้างข้อมูล "สุ่ม" เป็นโปรแกรมอินพุตสำหรับชุดทดสอบและมันแสดงข้อผิดพลาดมันจะดีถ้าการใช้ชุดทดสอบนั้นสร้างข้อผิดพลาดอีกครั้ง!

ฉันหวังว่าตอนนี้ชัดเจนมากขึ้น

ท้ายที่สุดถ้าคุณชอบสิ่งนี้คุณอาจสนุกกับการอ่านเพิ่มเติมเกี่ยวกับเรื่องของการสุ่มและการเรียงสับเปลี่ยน:


20
ตกลงเด็กชายและเด็กหญิง เพียงพอสำหรับการแสดงความคิดเห็นในตอนนี้ หากคุณต้องการพูดคุยเรื่องนี้ต่อไปลองคว้าห้องแชทด้วยตัวคุณเอง kthnxbye!
— Ivo Flipse

1
@Eric แต่เมล็ดไม่ได้ถูกรีเซ็ตก่อนที่จะมีการเด็คใหม่แต่ละครั้งใช่ไหม? ดังนั้นในขณะที่คุณถูกต้องว่ามีเพียงไม่กี่วิถีที่เราสุ่มตัวอย่างจากคุณไม่ทราบว่าในวิถีที่คุณอยู่ในขณะนี้และเส้นทางตัดกัน
— AS


การรักษาที่ดี (แต่หนาแน่น) ของปัญหาที่เกี่ยวข้องอยู่ใน Knoc's TAOCP ฉบับที่ 2, ส่วนที่ 3.5“ ลำดับสุ่มคืออะไร?” (หน้า 149) เริ่มต้นด้วยคำจำกัดความที่กระจ่างของ equidistributed ลำดับ Pseudorandom ถูกกล่าวถึงใน 3.5.F (หน้า 170) ดูเพิ่มเติมเกณฑ์ pseudorandomness จากทฤษฎีความซับซ้อนและเยอรมัน BSI
— ShreevatsaR

160

อย่างที่ Eric Lippert บอกไว้ไม่ใช่เพียงแค่การแจกจ่ายเท่านั้น มีวิธีอื่นในการวัดแบบแผน

หนึ่งในเครื่องกำเนิดเลขสุ่มก่อนมีลำดับในบิตที่สำคัญน้อยที่สุด - มันสลับ 0 และ 1 ดังนั้น LSB จึงสามารถคาดเดาได้ 100% แต่คุณต้องกังวลมากกว่านั้น แต่ละบิตจะต้องทายไม่ถูก

นี่เป็นวิธีที่ดีในการคิดถึงปัญหา สมมติว่าคุณกำลังสร้างการสุ่ม 64 บิต สำหรับผลลัพธ์แต่ละรายการให้ใช้ 32 บิตแรก (A) และ 32 บิตสุดท้าย (B) และสร้างดัชนีลงในอาร์เรย์ x [A, B] ตอนนี้ทำการทดสอบหนึ่งล้านครั้งและสำหรับผลลัพธ์แต่ละรายการให้เพิ่มอาร์เรย์ที่หมายเลขนั้นเช่น X [A, B] ++;

ตอนนี้วาดไดอะแกรม 2 มิติซึ่งมีจำนวนมากขึ้นความสว่างของพิกเซลที่ตำแหน่งนั้น

หากเป็นการสุ่มอย่างแท้จริงสีควรเป็นสีเทาสม่ำเสมอ แต่คุณอาจได้รูปแบบ ใช้อินสแตนซ์ไดอะแกรมของ "randomness" นี้ในหมายเลขลำดับ TCP ของระบบ Windows NT:

วินโดวส์เอ็นที

หรือแม้แต่อันนี้จาก Windows 98:

Windows 98

และนี่คือการสุ่มของการนำ Cisco router (IOS) ไปใช้ Cisco ISO

แผนภาพเหล่านี้เป็นมารยาทของกระดาษMichał Zalewski ของ ในกรณีนี้หากใครสามารถคาดเดาได้ว่าหมายเลขลำดับ TCP จะเป็นของระบบใครสามารถปลอมตัวเป็นระบบนั้นเมื่อทำการเชื่อมต่อกับระบบอื่น - ซึ่งจะอนุญาตให้หักหลังการเชื่อมต่อการสกัดกั้นการสื่อสาร ฯลฯ และแม้ว่าเราจะ ไม่สามารถคาดเดาหมายเลขถัดไป 100% ของเวลาถ้าเราสามารถทำให้การเชื่อมต่อใหม่ถูกสร้างขึ้นภายใต้การควบคุมของเราเราสามารถเพิ่มโอกาสในการประสบความสำเร็จ และเมื่อคอมพิวเตอร์สามารถสร้างการเชื่อมต่อ 100,000 ครั้งในเวลาไม่กี่วินาทีอัตราต่อรองของการโจมตีที่ประสบความสำเร็จนั้นเกิดจากดาราศาสตร์ไปจนถึงที่เป็นไปได้หรือเป็นไปได้


30
มันยอดเยี่ยมมากมันทำให้น้ำตาของฉัน ควรมีแอพที่สร้างขึ้นสำหรับทุก OS (มือถือ / เดสก์ท็อป / เซิร์ฟเวอร์) และแพลตฟอร์ม (JVM / Javascript / ฯลฯ )
— HDave

5
ฟังก์ชั่น rand ของ Windows () ค่อนข้างดี! มันสร้างคลาวด์ที่ไม่มีรูปแบบที่ชัดเจน ดูการใช้งานของฉันเพื่อลอง (และอัลกอริทึมอื่น ๆ ) out: github.com/Zalastax/visualize_random
— Zalastax

93

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

ในแอปพลิเคชันที่มีความปลอดภัยสูงเช่นการเข้ารหัสผู้สร้างหมายเลขปลอม (PRNG) อาจสร้างค่าซึ่งแม้ว่าจะมีการสุ่มปรากฏในความเป็นจริงผู้โจมตีสามารถคาดเดาได้ คนที่พยายามถอดรหัสระบบเข้ารหัสอาจสามารถเดารหัสลับได้หากใช้ PRNG และผู้โจมตีมีข้อมูลเกี่ยวกับสถานะของ PRNG ดังนั้นสำหรับแอปพลิเคชันดังกล่าวตัวสร้างตัวเลขสุ่มซึ่งสร้างค่าที่ไม่สามารถคาดเดาได้อย่างแท้จริงจึงเป็นสิ่งจำเป็น โปรดทราบว่าPRNG บางตัวได้รับการออกแบบให้มีความปลอดภัยในการเข้ารหัสและใช้งานได้สำหรับแอปพลิเคชันที่มีความปลอดภัยสูง

ข้อมูลเพิ่มเติมเกี่ยวกับการโจมตี RNG สามารถพบได้ในบทความวิกิพีเดียนี้


9
การเข้ารหัสลับมี PRNG และใช้กันอย่างแพร่หลาย พวกเขาสามารถจากเมล็ดที่มีขนาดพอประมาณสร้างกระแสสุ่มไม่ จำกัด จำนวน มันเป็นไปไม่ได้ที่จะแยกแยะกระแสดังกล่าวจากการสุ่มตัวเลขที่แท้จริงดังนั้นจึงไม่สามารถรับข้อมูลเพิ่มเติมจากส่วนใด ๆ ของสตรีมดังกล่าวได้และเพื่อประโยชน์ในทางปฏิบัติตัวเลขก็ดีพอ ๆ กับตัวเลขสุ่มจริง
— aaaaaaaaaaaa

ฉันคิดว่าวิธีที่ง่ายที่สุดในการอธิบายสิ่งนี้คืออัลกอริทึมตัวสร้างตัวเลขแบบสุ่มต้องถูกตั้งโปรแกรมไว้ นั่นหมายถึงมีชุดคำสั่งที่กำลังปฏิบัติตาม หากมีชุดคำสั่งจะไม่สามารถสุ่มได้
— Keltari

6
@Keltari คุณไม่มีองค์ประกอบของเอนโทรปี ... RNGs ส่วนใหญ่ (อย่างน้อยคนที่เข้ารหัสลับ) รวบรวมข้อมูลจากแหล่งภายนอก (เช่นการเคลื่อนไหวของเมาส์) และใช้เป็นส่วนหนึ่งของสภาพเริ่มต้น - ดังนั้นการเปลี่ยนแปลงจากAการBเป็นโปรแกรม แต่ สถานะเริ่มต้นของA(ควร) จะไม่สามารถคาดเดาได้ ลินุกซ์/dev/randomจะคอยประมาณปริมาณเอนโทรปีที่มีอยู่และหยุดให้ตัวเลขถ้ามันต่ำเกินไป
— พื้นฐาน

จากความอยากรู้ - ทำไมโคมไฟลาวาจึงถูกพิจารณาว่าเป็น "สุ่มอย่างแท้จริง" ฉันเข้าใจว่ามันแสดงพฤติกรรมที่ไม่สามารถคาดเดาได้ แต่คนที่มีความเข้าใจอย่างเพียงพอเกี่ยวกับการเปลี่ยนแปลงของของไหลและของเหลวเหล่านั้นมีปฏิกิริยาอย่างไรในสภาพแวดล้อมแรงโน้มถ่วงของโลก แน่นอนว่าโคมไฟลาวาไม่แน่นอน แต่สำหรับฉันแล้วมันไม่ได้สุ่มเลย แต่คาดเดาได้สูง
— theGreenCabbage

1
@TheGreenCabbage: ฉันสงสัยว่าโคมไฟลาวาวุ่นวาย ด้วยรูปแบบคอมพิวเตอร์ที่ดีเพียงพอและตัวเลขที่มีความแม่นยำเพียงพอคุณสามารถ (ในหลักการ) ทำนายพฤติกรรมในขณะนั้น แต่เนื่องจากระบบไม่เป็นระเบียบโคมลาวาสองดวงที่มีการเปลี่ยนแปลงน้อยที่สุดในสภาวะเริ่มต้นจะแตกต่างอย่างรวดเร็วในพฤติกรรม (และความคิดเห็นนี้ไม่สนใจตัวดึงดูดความวุ่นวาย)
— dmm

76

ฉันลองใช้ Python: นี่คือผลลัพธ์ของม้วน 60 ล้าน ความแปรปรวนสูงสุดเท่ากับ 0.15 ไม่ว่าจะเป็นแบบสุ่มที่จะได้รับ?

ที่จริงแล้วมันก็"ดี" ไม่ดี ... คำตอบที่มีอยู่ทั้งหมดมุ่งเน้นไปที่ความสามารถในการคาดเดาได้เนื่องจากค่าเริ่มต้นเล็ก ๆ ฉันต้องการที่จะยกประเด็นอื่น:

    การกระจายของคุณมีค่าเบี่ยงเบนมาตรฐานที่น้อยกว่าการสุ่มม้วน

ทรูสุ่มเพียงแค่ไม่ได้มาค่อนข้างที่ใกล้เคียงกับค่าเฉลี่ย "เกือบตรง 1 มากกว่าวิธีการที่เคยตัวเลขหลาย ๆ คนก็สามารถเลือกได้จาก" ว่าคุณกำลังใช้เป็นตัวบ่งชี้ของการที่มีคุณภาพ

หากคุณดูที่คำถามแลกเปลี่ยนสแต็กเกี่ยวกับการแจกแจงความน่าจะเป็นสำหรับการทอยลูกเต๋าหลายครั้งคุณจะเห็นสูตรสำหรับการเบี่ยงเบนมาตรฐานของการหมุนลูกเต๋า N ลูกเต๋า

 sqrt(N * 35.0 / 12.0).

การใช้สูตรนั้นค่าเบี่ยงเบนมาตรฐานสำหรับ:

  • 1 ล้านม้วนคือ1708
  • 60 ล้านม้วนคือ13229

ถ้าเราดูผลลัพธ์ของคุณ:

  • 1 ล้านม้วน: stddev (10,00066, 999666, 1001523, 999452, 999294, 999999) คือ804
  • 60 ล้านม้วน: stddev (9997653, 9997789, 9996853, 10006533, 10002774, 9998398) คือ3827

คุณไม่สามารถคาดหวังว่าค่าเบี่ยงเบนมาตรฐานของตัวอย่าง จำกัด เพื่อให้ตรงกับสูตร แต่มันควรจะเข้าใกล้ กระนั้นที่ 1 ล้านม้วนคุณน้อยกว่าครึ่งหนึ่งของ stddev ที่ถูกต้องและ 60 ล้านคุณอยู่ในอันดับที่สาม - มันแย่ลงและนั่นไม่ใช่เรื่องบังเอิญ ....

Pseudo-RNGs มีแนวโน้มที่จะเคลื่อนผ่านลำดับของจำนวนที่แตกต่างกันเริ่มต้นด้วยเมล็ดและไม่ได้มาหมายเลขเดิมสำหรับช่วงเวลาที่เฉพาะเจาะจง ตัวอย่างเช่นการใช้งานของrand()ฟังก์ชั่นไลบรารี C เก่ามักมีระยะเวลา 2 ^ 32 และพวกเขาจะเยี่ยมชมทุกหมายเลขระหว่าง 0 และ 2 ^ 32-1 ทุกครั้งก่อนที่จะทำซ้ำเมล็ด ดังนั้นถ้าคุณจำลองลูกเต๋า 2 ^ 32 ลูกเต๋าจะได้ pre-modulus (%) ผลลัพธ์จะรวมแต่ละหมายเลขตั้งแต่ 0 ถึง 2 ^ 32 จำนวนสำหรับแต่ละผลลัพธ์ 1-6 จะเป็น 715827883 หรือ 715827882 (2 ^ 32 ไม่ได้เป็นหลายเท่าของ 6) และค่าเบี่ยงเบนมาตรฐานจึงเบี่ยงเบนไปเหนือ 0 เท่านั้น สูตรข้างต้นค่าเบี่ยงเบนมาตรฐานที่ถูกต้องสำหรับ 2 ^ 32 ม้วนคือ 111924 อย่างไรก็ตามเมื่อจำนวนม้วนของคุณหลอกแบบสุ่มเพิ่มขึ้นคุณจะได้เข้าหา 0 ส่วนเบี่ยงเบนมาตรฐาน คาดว่าปัญหานี้จะเกิดขึ้นอย่างมีนัยสำคัญเมื่อจำนวนม้วนเป็นส่วนสำคัญของช่วงเวลา แต่การปลอมแปลง -RNG บางรายการอาจแสดงปัญหาที่เลวร้ายกว่า - หรือปัญหาแม้จะมีตัวอย่างน้อยกว่า -

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


เพื่อยกตัวอย่างที่เป็นรูปธรรม: สมมติว่านักคณิตศาสตร์บอกโปรแกรมเมอร์เครื่องโป๊กเกอร์ว่าหลังจากที่มีการจำลอง 60 ล้านม้วน - ใช้ในการกะพริบ "ไฟ" เล็ก ๆ น้อย ๆ หลายร้อยรอบหน้าจอหากมีจำนวน 10,013,229 หรือมากกว่าหกซึ่งนักคณิตศาสตร์คาดว่า ห่างจากค่าเฉลี่ย 1 stddev ควรมีการจ่ายเงินเล็กน้อย ตามกฎ 68–95–99.7 (Wikipedia)สิ่งนี้ควรเกิดขึ้นประมาณ16%ของเวลา (ประมาณ 68% อยู่ในค่าเบี่ยงเบนมาตรฐาน / มีเพียงครึ่งเดียวเท่านั้นที่อยู่เหนือ) ด้วยตัวสร้างตัวเลขสุ่มของคุณนี่มาจาก 3.5 ส่วนเบี่ยงเบนมาตรฐานเหนือค่าเฉลี่ย: มีโอกาสต่ำกว่า0.025% - แทบไม่มีลูกค้าที่ได้รับผลประโยชน์นี้ ดูตารางส่วนเบี่ยงเบนที่สูงขึ้นบนหน้าเว็บที่กล่าวถึงโดยเฉพาะ:

| Range    | In range   | Outside range | Approx. freq. for daily event  |
| µ ± 1σ   | 0.68268... | 1 in 3        | Twice a week                   |
| µ ± 3.5σ | 0.99953... | 1 in 2149     | Every six years                |

คุณกำลังเปรียบเทียบแอปเปิ้ลและส้มที่นี่ ส่วนเบี่ยงเบนมาตรฐานทั้งสองไม่มีอะไรเกี่ยวข้องกันเลย
— Jbeuh

50

ฉันเพิ่งเขียนตัวสร้างตัวเลขสุ่มนี้เพื่อสร้างลูกเต๋า

def get_generator():
  next = 1
  def generator():
    next += 1
    if next > 6:
      next = 1
    return next
  return generator

คุณใช้มันแบบนี้

>> generator = get_generator()
>> generator()
1
>> generator()
2
>> generator()
3
>> generator()
4
>> generator()
5
>> generator()
6
>> generator()
1

ฯลฯ เป็นต้นคุณมีความสุขที่จะใช้ตัวกำเนิดนี้สำหรับโปรแกรมที่รันเกมลูกเต๋าหรือไม่? โปรดจำไว้ว่าการกระจายของมันคือสิ่งที่คุณคาดหวังจากเครื่องกำเนิด "สุ่มอย่างแท้จริง"!

เครื่องกำเนิดจำนวนสุ่มหลอกทำในสิ่งเดียวกัน - สร้างตัวเลขที่คาดเดาได้ด้วยการแจกแจงที่ถูกต้อง พวกเขาไม่ดีด้วยเหตุผลเดียวกับที่ตัวสร้างตัวเลขสุ่มแบบง่าย ๆ ข้างต้นนั้นไม่ดี - พวกเขาไม่เหมาะสำหรับสถานการณ์ที่คุณต้องการความคาดเดาไม่ได้ของแท้ไม่ใช่แค่การกระจายที่ถูกต้อง


2
"ตัวสร้างตัวเลขสุ่มหลอก ... สร้างตัวเลขที่คาดเดาได้ด้วยการแจกแจงที่ถูกต้อง" - เพียงเพราะ PRNG ไม่รับประกันว่าจะมีการแจกแจงที่สมบูรณ์แบบ เหตุผลที่ระบุไว้ในคำตอบเหล่านี้) ในขณะที่พวกเขาสามารถคาดการณ์ได้รับข้อมูลที่เพียงพอ (algo ใช้เริ่มต้นเมล็ดค่าส่งออก w / e) พวกเขายังคงมีความแปรปรวน
— Brian S

3
นอกจากนี้จุดที่ฉันรู้ แต่get_generator = lambda: itertools.cycle(range(1,7)), generator = get_generator(), next(generator) # and so onเป็นเพียงหรูหราเกินไปไม่พูดถึง :)
— เจนัส Troelsen

2
@BrianS ที่จริงแล้ว PRNG ที่ล้มเหลวในการทดสอบการกระจายเมื่อเวลาผ่านไปจะสามารถทำนายได้ด้วยคำจำกัดความ ดังนั้นใน N ที่มีขนาดใหญ่ถ้าคุณได้รับแม้แต่นิดหน่อยจาก N / 2 หัวในการโยนเหรียญ N คุณสามารถเริ่มเดิมพันบนหัวและคุณสามารถชนะได้มากกว่าที่คุณแพ้ ในทำนองเดียวกันหากคุณมีการแจกแจงที่สมบูรณ์แบบของหัว v. แต่หัวมาเป็นคู่เสมอคุณจะมีสูตรในการชนะอีกครั้ง การทดสอบการกระจายเป็นวิธีที่คุณรู้ว่า PRNG นั้นดีอย่างไร
— Jon Kiparsky

1
คุณลืมnonlocal next:-)
— Kos

5
ตัวอย่างที่ดียิ่งขึ้น: Pi เชื่อว่าเป็นเรื่องปกติซึ่งหมายความว่าลำดับของตัวเลขใด ๆ ของความยาวที่กำหนดในฐานใด ๆ ไม่ปรากฏบ่อยกว่าลำดับอื่น ๆ ของความยาวนั้นในฐานนั้น อัลกอริทึมซึ่งเมื่อถามถึงบิตสุ่มnจะใช้เวลาบิตnถัดไปของ pi และส่งกลับพวกเขา ("เมล็ดพันธุ์" เป็นบิตที่คุณเริ่มต้น) ควรในระยะยาวจะสร้างการกระจายที่สมบูรณ์แบบ แต่คุณยังคงไม่ต้องการมันสำหรับเครื่องกำเนิดไฟฟ้าของคุณ - คนที่รู้ว่าบิตสุดท้ายที่คุณสร้างขึ้นสามารถหาได้ในครั้งแรกที่มีการเรียงลำดับเกิดขึ้นสมมติว่าเมล็ดของคุณอยู่ที่นั่นและน่าจะถูกต้อง
— cpast

26

การสร้างตัวเลขสุ่มที่คอมพิวเตอร์ของคุณสามารถทำได้นั้นเหมาะสำหรับความต้องการส่วนใหญ่และคุณไม่น่าจะเจอเวลาที่คุณต้องการตัวเลขสุ่มอย่างแท้จริง

การสร้างหมายเลขสุ่มที่แท้จริงนั้นมีจุดประสงค์ ในเรื่องความปลอดภัยของคอมพิวเตอร์การพนันการสุ่มตัวอย่างเชิงสถิติขนาดใหญ่ ฯลฯ

หากคุณมีความสนใจในการใช้งานของตัวเลขสุ่มตรวจสอบบทความวิกิพีเดีย


12
ปัญหาใหญ่คือเมื่อคุณต้องการตัวเลขสุ่มที่ผู้โจมตีไม่สามารถทำนายได้ด้วยเหตุผลด้านความปลอดภัย
— David Schwartz

16
คุณแน่ใจว่าเป็นนรกที่จะเจอเวลาที่คุณต้องการตัวเลขสุ่มอย่างแท้จริง ก็เพียงพอแล้วที่จะเปิดหน้าเว็บที่เริ่มต้นด้วยhttps://...
— Jan Hudec

3
@JanHudec: ดีในการใช้ชีวิตประจำวันคุณจะต้องสุ่มตัวเลขที่เชื่อถือได้ของช่วงเวลาที่คุณเปิดโปรแกรมใด ๆ ให้ดีก่อนที่คุณกำลังพิมพ์ลงในแถบที่อยู่: ดูอยู่ randomization นั่นเป็นเหตุผลว่าทำไมเรื่องแบบนี้ถึงเกิดขึ้น
— Reid

5
@JanHudec ฉันกำลังพูดเฉพาะในแง่ที่คุณจะต้องใช้เครื่องกำเนิดตัวเลขแบบสุ่มออนไลน์ ตัวเลขสุ่มจริงใช้บ่อย แต่มีคนน้อยมากที่ต้องการสร้างมัน
— Alex McKenzie

2
เครื่องสล็อตใช้ PRNG ไม่ใช่ TRNG เครื่องกำเนิดไฟฟ้าจะทำงานตลอดเวลาและจะมีการเลือกตัวเลขในเวลาที่แน่นอนว่าจะกดปุ่มหมุน ผลรวมของ PRNG และเวลากดปุ่มสุ่มอย่างแท้จริงจะเท่ากับ TRNG
— Roger Dahl

26

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

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

glibc random():
    r[i] ← ( r[i-3] + r[i-31] )  % (2^32)
    output  r[i] >> 1

ตัวสร้างตัวเลขสุ่มหลอกชนิดนี้ไม่ควรใช้ในสถานที่ปลอดภัยด้านความปลอดภัยแม้ว่าจะมีนัยสำคัญทางสถิติ

หนึ่งของการโจมตีที่มีชื่อเสียงบนปุ่มสุ่มหลอกคือการโจมตีใน802.11b WEP WEP มีคีย์ระยะยาว 104 บิตเชื่อมต่อกับ 24 บิต IV (ตัวนับ) เพื่อสร้างคีย์ 128 บิตซึ่งจะนำไปใช้กับอัลกอริทึม RC4เพื่อสร้างคีย์สุ่มหลอก

( RC4( IV + Key ) ) XOR (message)

กุญแจมีความสัมพันธ์อย่างใกล้ชิดกับอีกคนหนึ่ง ที่นี่เพียง IV เพิ่มขึ้น 1 ในแต่ละขั้นตอนและอื่น ๆ ทั้งหมดยังคงเหมือนเดิม เนื่องจากนี่ไม่ใช่การสุ่มอย่างแท้จริงมันจึงเป็นหายนะและพังทลายได้ง่าย กุญแจสามารถกู้คืนได้โดยการวิเคราะห์เฟรมประมาณ 40000 ซึ่งเป็นเวลาไม่กี่นาที หาก WEP ใช้การสุ่ม 24 บิต IV แบบสุ่มทั้งหมดอาจปลอดภัยจนกว่าเฟรมประมาณ 2 ^ 24 (เกือบ 16.8 ล้าน)

ดังนั้นหนึ่งควรไปกับเครื่องกำเนิดตัวเลขบริสุทธิ์ในประเด็นความปลอดภัยที่เป็นไปได้


3
ฉันจะตำหนิสิ่ง WEP ในโปรโตคอลที่ออกแบบมาไม่ดีโดยใช้ตัวเลขที่อ่อนแอ ด้วยยันต์กระแสอันทันสมัยคุณสามารถใช้ตัวนับเป็น IV
— CodesInChaos

2
ปัญหาหลักของ WEP คือการทำซ้ำกุญแจในเฟรม 2 ^ 24 (เกือบ 16 ล้าน) มันยิ่งแย่ลงไปกว่านี้ด้วยกุญแจที่เกี่ยวข้องซึ่งทำให้สามารถถอดรหัสรหัสได้ประมาณ 40000 เฟรม จุดหลักที่นี่คือกุญแจไม่ได้สุ่ม มันมีความสัมพันธ์กันอย่างใกล้ชิดดังนั้นมันจึงแตกง่าย
— Prabhu

1
หลอกแบบแผนคือไม่ดีในการเข้ารหัสเฉพาะเมื่อมีการสร้างคีย์การเข้ารหัสลับ มันสมบูรณ์แบบดีกว่านั้น แท้จริงแล้ว RC4 นั้นเป็นเครื่องกำเนิดตัวเลขแบบหลอกเทียมที่มีการขยายตัวของคีย์ XOR ที่ 128 บิตลงบนข้อความธรรมดา
— แมตต์

12

ความแตกต่างคือตัวเลขที่สร้างขึ้นแบบสุ่มสามารถคาดเดาได้ (ทำซ้ำ) หลังจากระยะเวลาหนึ่งซึ่งไม่มีการสุ่มตัวเลขจริง ความยาวที่ใช้ในการทำซ้ำขึ้นอยู่กับความยาวของเมล็ดซึ่งใช้สำหรับการสร้าง

นี่เป็นวิดีโอที่ดีเกี่ยวกับหัวข้อนั้น: http://www.youtube.com/watch?v=itaMNuWLzJo


Predictability! = การทำซ้ำ Mersenne Twister เป็นตัวอย่างที่ดีของสิ่งนั้น ในการติดตั้งส่วนใหญ่หลังจาก 624 Int32 คุณสามารถทำนายหมายเลขถัดไปทั้งหมด แต่ลำดับ Mersenne Twister นั้นยาวกว่านั้นมาก (2 ^ 19937 - 1)
— HoLyVieR

ฉันไม่เข้าใจว่าทำไมคำตอบนี้ไม่ได้ทำให้เกิดสแต็คเพราะฉันคิดว่านี่เป็นคำตอบที่ถูกต้องและรัดกุมสำหรับคำถามอย่างน้อยบางส่วน ตัวเลขสุ่มหลอกสามารถทำนายได้อย่างง่ายดายหลังจากการจับรางวัลจำนวนการจับคู่ที่แตกต่างกันกับอัลกอริธึมหลอกหลอก "คุณภาพ" การเลือกอัลกอริทึม "ดี" กำลังมองหาที่ด้านต่างๆ: 1. ทุกค่าถูกวาดด้วยความถี่เท่ากัน (การกระจาย) 2. ใช้เวลา "นาน" ในการรีสตาร์ทลำดับที่จุดเริ่มต้นและเริ่มวาดตัวเลขเดียวกันใน คำสั่งเดียวกัน
— นาที

"ตัวเลขสุ่มจริงไม่ใช่ [คาดเดาได้]" สำหรับวันนี้มันเป็นเรื่องจริง ทีนี้ถ้าเราเชื่อในทฤษฎีบิ๊กแบงและเรามีพลังมากมายในการคำนวณสถานะของจักรวาลในเวลาใดก็ได้หลังจาก BB ตามฟิสิกส์แล้ว ... เราสามารถทำนายอนาคตรวมถึงข้อเท็จจริงที่ว่า ฉันกำลังเขียนความคิดเห็นที่แน่นอนมากนี้ ขวา?
— นาที

นั่นเป็นความจริงตามสมมุติฐานอย่างไรก็ตามเมื่อพิจารณาถึงระดับของเอนโทรปีที่เกี่ยวข้องกับการกระทำจริงของร่างกายจริง ๆ พลังการคำนวณที่จำเป็นจะยิ่งใหญ่อย่างน่าขัน คิดว่าทวีปครอบคลุมในคอมพิวเตอร์ นอกจากนี้เนื่องจากการพึ่งพารัฐก่อนหน้านี้สถานะของร่างกายทุกคนในจักรวาลในทุกจุดในเวลาจะต้องถูกเก็บไว้ซึ่งตามคำนิยามจะต้องมีพื้นที่ว่างมากกว่าที่มีอยู่ในจักรวาลที่เต็มไปด้วยอุปกรณ์หน่วยความจำ
— TheEnvironmentalist

@TheEnvironmentalist - อ้า! "ทวีปที่กล่าวถึงในคอมพิวเตอร์" ... ไม่ใช่หรือสิ่งที่ "คู่มือโบกรถของกาแล็กซี่" เกี่ยวกับ? ;-)
— ysap

10

สมมติว่าทุกคนก่อนที่มันจะถูกสร้างขึ้นเดาตัวเลขสุ่มหลอก

สำหรับแอปพลิเคชั่นเล็ก ๆ น้อย ๆ การสุ่มหลอกก็ดีเช่นเดียวกับตัวอย่างของคุณคุณจะได้รับเปอร์เซ็นต์ที่ถูกต้อง (ประมาณ 1 ใน 6 ของชุดผลลัพธ์ทั้งหมด) โดยมีการเปลี่ยนแปลงเล็กน้อย (ซึ่งคุณจะเห็นว่าคุณจะกลิ้งลูกเต๋า 600k ครั้ง);

อย่างไรก็ตามเมื่อพูดถึงเรื่องความปลอดภัยของคอมพิวเตอร์ จำเป็นต้องมีการสุ่มตัวอย่างที่แท้จริง

ตัวอย่างเช่นอัลกอริทึม RSA เริ่มต้นด้วยคอมพิวเตอร์ที่เลือกตัวเลขสุ่มสองตัว (P และ Q) จากนั้นทำหลายขั้นตอนกับตัวเลขเหล่านั้นเพื่อสร้างหมายเลขพิเศษที่รู้จักกันในชื่อกุญแจสาธารณะและกุญแจส่วนตัวของคุณ (ส่วนสำคัญของคีย์ส่วนตัวคือเป็นส่วนตัวและไม่มีใครรู้เลย!)

หากผู้โจมตีสามารถรู้ว่า 'สุ่ม' สองหมายเลขใดที่คอมพิวเตอร์ของคุณกำลังจะเลือกพวกเขาสามารถทำตามขั้นตอนเดียวกันเพื่อคำนวณคีย์ส่วนตัวของคุณ (หมายเลขที่คนอื่นไม่ควรรู้!)

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

นั่นคือสิ่งที่จำเป็นต้องมีการสุ่มตัวอย่างที่แท้จริง (เช่นไม่สามารถเดา / คำนวณ)


10

ตัวเลขสุ่มตัวแรกที่ฉันเคยใช้มีคุณสมบัติที่ยอดเยี่ยมของตัวเลขสุ่มสองตัวติดต่อกันหมายเลขที่สองนั้นใหญ่กว่าด้วยความน่าจะเป็นที่ 0.6 ไม่ใช่ 0.5 และอันที่สามใหญ่กว่าวินาทีด้วยความน่าจะเป็น 0.6 และอื่น ๆ คุณสามารถจินตนาการได้ว่าวิธีเล่นความเสียหายด้วยการจำลอง

บางคนไม่เชื่อว่านี่เป็นไปได้แม้จะมีการแจกแจงตัวเลขแบบสุ่ม แต่ก็เห็นได้ชัดว่าถ้าคุณดูลำดับ (1, 3, 5, 2, 4, 1, 3, 5, 2, 4, ... ) โดยที่สองของตัวเลขสองตัวมีค่ามากกว่าความน่าจะเป็น 0.6

ในทางกลับกันสำหรับการจำลองเป็นสิ่งสำคัญที่จะสามารถทำซ้ำตัวเลขสุ่ม สมมติว่าคุณทำการจำลองการรับส่งข้อมูลและต้องการทราบว่าการดำเนินการบางอย่างที่คุณอาจทำได้สามารถปรับปรุงปริมาณการใช้งานได้อย่างไร ในกรณีนี้คุณต้องการที่จะสร้างข้อมูลการจราจรเดิมซ้ำอีกครั้ง (เช่นผู้ที่พยายามเข้าเมือง) ด้วยการกระทำที่แตกต่างกันซึ่งคุณพยายามปรับปรุงการจราจร


8

คำตอบสั้น ๆ ก็คือคนมักจะต้องการ "การสุ่มอย่างแท้จริง" ด้วยเหตุผลที่ไม่ดีนั่นคือพวกเขาไม่มีความเข้าใจในการเข้ารหัส

การเข้ารหัสดั้งเดิมเช่นstream ciphersและCSPRNGsถูกใช้เพื่อสร้างกระแสข้อมูลจำนวนมากของบิตที่ไม่สามารถคาดเดาได้เมื่อพวกมันได้รับการป้อนบิตที่ไม่สามารถคาดเดาได้สองสามตัว

ตอนนี้ผู้อ่านที่ระวังจะรู้ว่ามีปัญหาเรื่อง bootstrapping ที่นี่: เราต้องรวบรวมเอนโทรปีสองสามตัวเพื่อเริ่มต้นมันทั้งหมด จากนั้นสามารถป้อนเข้าสู่CSPRNGซึ่งจะให้บิตที่คาดเดาไม่ได้ทั้งหมดที่เราต้องการอย่างมีความสุข ดังนั้นRNG ฮาร์ดแวร์จะต้องเมล็ด CSPRNG นี่เป็นกรณีเดียวที่จำเป็นต้องใช้เอนโทรปีในความจริง

(ฉันคิดว่าสิ่งนี้ควรถูกโพสต์ในการรักษาความปลอดภัยหรือการเข้ารหัส)

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

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

แก้ไข: ดังนั้นเพื่อรวมทั้งหมดนี้ ... เอนโทรปีจำเป็นต้องมีการเพาะ CSPRNG เมื่อดำเนินการเสร็จ CSPRNG จะจัดหาบิตที่คาดเดาไม่ได้ทั้งหมดที่เราต้องการสำหรับแอปพลิเคชันความปลอดภัยเร็วกว่าที่เราสามารถรวบรวมเอนโทรปีได้มาก หากไม่จำเป็นต้องคาดเดาไม่ได้เช่นสำหรับการจำลอง Mersenne Twister จะให้ตัวเลขที่มีคุณสมบัติทางสถิติที่ดีในอัตราที่สูงขึ้นมาก

แก้ไข: ทุกคนยินดีที่จะเข้าใจปัญหาการสร้างหมายเลขสุ่มที่ปลอดภัยควรอ่าน: http://www.cigital.com/whitepapers/dl/The_Importance_of_Reliable_Randomness.pdf


2
มันไม่จำเป็นต้องเป็นคำถามเพื่อความปลอดภัย ฉันคิดว่ามีเหตุผลที่จะใช้ตัวเลขสุ่มที่ไม่เกี่ยวข้องกับความปลอดภัย ถ้าฉันกำลังทำการวิจัยทางวิทยาศาสตร์ที่ขึ้นอยู่กับตัวเลขสุ่มและด้วยเหตุผลใดก็ตามที่สำคัญว่าตัวเลขนั้นสุ่มที่สุดฉันจะใช้ประโยชน์จากฮาร์ดแวร์ RNG อย่างแน่นอนดังนั้นฉันจึงมั่นใจได้ว่าคุณสมบัติที่สังเกตเห็นจะไม่ครบกำหนด ถึงนิสัยใจคอของ RNG
— Kef Schecter

3
@KefSchecter มันเป็นฮาร์ดแวร์ PRNGs ของพวกเขาได้ยินโดยทั่วไปมีลำเอียงและ / หรือผลผลิตที่มีความสัมพันธ์ พวกเขาต้องการขั้นตอนการโพสต์เพื่อเปลี่ยนเป็นเอาท์พุทอิสระสม่ำเสมอ ไม่มีเหตุผลที่เชื่อได้ว่าขั้นตอนการโพสต์นี้มีความน่าเชื่อถือมากกว่าการเข้ารหัสสตรีมที่ทันสมัย แน่นอนฉันจะเชื่อกระแสข้อมูลตัวเลขเพิ่มเติม ในฐานะโบนัสพิเศษมันสามารถทำซ้ำได้ซึ่งมีคุณค่าทางวิทยาศาสตร์
— CodesInChaos

ตกลงยุติธรรมพอ แต่แอปพลิเคชันการเข้ารหัสจะไม่เหมือนกันหรือไม่ แม้แต่คำตอบที่นี่ก็บอกว่าคุณต้องการฮาร์ดแวร์ RNG เพื่อเพาะเมล็ด CSPRNG
— Kef Schecter

2
@KefSchecter ใช่แล้วแอปพลิเคชัน crypto ต้องการตัวเลขสุ่มจริง ๆ เพื่อเริ่มต้น CSPRNG แต่สำหรับทุกอย่างเราสามารถใช้ CSPRNG นั้นได้
— CodesInChaos

@KefSchecter: แอพพลิเคชั่นการเข้ารหัสต้องการให้โลกไม่สามารถทำซ้ำกระแสข้อมูลได้ ในทางวิทยาศาสตร์การใช้ความสามารถในการแสดงให้เห็นว่าตัวเลข "สุ่ม" ที่ใช้ไม่ได้ถูกเลือกเพื่อแสดงการวิเคราะห์ในแง่ดีนั้นมีประโยชน์ ตัวอย่างเช่นหากมีการประกาศหลังจากประกาศวิธีการหนึ่งว่าจะสร้างข้อมูลในรูปแบบที่แน่นอนโดยใช้หมายเลขล็อตเตอรี่ของรัฐในวันถัดไปผู้อ่านสามารถมั่นใจได้ว่าจะไม่ได้รับผลการค้นหาแม้ว่าการวาดในวันธรรมดา บิตของเอนโทรปี
— supercat

7

PRNG ไม่เหมาะสำหรับการใช้งานทุกประเภท ตัวอย่างเช่น Java.util.SecureRandom ใช้แฮช SHA1 ซึ่งมีขนาดเอาต์พุต 160 บิต นั่นหมายความว่ามีสตรีมสุ่มตัวเลขที่เป็นไปได้2 160สตรีที่มาจากมัน เรียบง่ายเหมือนที่ คุณไม่สามารถรับค่าภายในมากกว่า 2 160ค่าของสถานะภายใน ดังนั้นคุณจะไม่สามารถรับ หมายเลขสุ่มที่เป็นเอกลักษณ์มากกว่า 2 160 รายการจากเมล็ดเดี่ยวไม่ว่าเมล็ดของคุณจะมาจากที่ใด Windows CryptGenRandom เชื่อว่าใช้สถานะแบบ 40 ไบต์มีตัวเลขสุ่มได้ถึง320 320ตัว

หลายวิธีที่จะสับเปลี่ยนดาดฟ้า 52 ใบมาตรฐานคือ 52 !, ซึ่งมีประมาณ 2 226 ดังนั้นโดยไม่คำนึงถึงการเพาะคุณไม่สามารถใช้ Java.util.SecureRandom เพื่อสับไพ่ได้ มีประมาณ 2 66สับที่เป็นไปได้ที่มันไม่สามารถผลิตได้ แน่นอนเราไม่รู้ว่าพวกเขาเป็นใคร ...

ดังนั้นถ้าฉันมีแหล่งที่มาของการพูดแบบสุ่ม 256 บิต (เช่นจากการ์ด Quantis RNG) ฉันสามารถหว่าน PRNG เช่น CryptGenRandom () ด้วยเมล็ดนั้นแล้วใช้ PRNG เพื่อสับชั้นของ บัตร ถ้าฉันสุ่มด้วยการสุ่มแบบสุ่มแต่ละครั้งจะดี: สุ่มไม่แน่นอนและมีสถิติ ถ้าฉันทำสิ่งเดียวกันกับ Java.util.SecureRandom จะมี shuffles ที่ไม่สามารถผลิตได้เพราะมันไม่สามารถ seed ด้วยเอนโทรปี 256 บิตและสถานะภายในของมันไม่สามารถเป็นตัวแทนของ shuffles ที่เป็นไปได้ทั้งหมด

โปรดทราบว่าผลลัพธ์ java.util.SecureRandom จะเป็นทั้งการคาดเดาไม่ได้และการสุ่มทางสถิติ ไม่มีการทดสอบทางสถิติที่จะระบุปัญหา! แต่ผลลัพธ์ของ RNG นั้นไม่ใหญ่พอที่จะครอบคลุมโดเมนทั้งหมดของผลลัพธ์ที่เป็นไปได้ทั้งหมดที่จำเป็นในการจำลองสำรับไพ่

และจำไว้ว่าถ้าคุณเพิ่มนักเลงเข้าไปก็คือ 54! ที่คุณต้องครอบคลุมซึ่งต้องมีความเป็นไปได้ประมาณ 2 238


2
ทำไมคุณถึงสนใจว่าสับบางอย่างไม่สามารถเกิดขึ้นได้? ข้อ จำกัด นั้นไม่มีผลที่สังเกตได้
— CodesInChaos

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

1
แต่มันตรวจจับได้ ฉันตรวจพบโดยใช้กระบวนการที่ทราบ: การตรวจทานซอร์สโค้ดและความรู้เกี่ยวกับโดเมนปัญหา นั่นคือสิ่งที่น่าทึ่ง ฉันไม่สามารถใช้การวิเคราะห์ทางสถิติอัตโนมัติ มันสามารถตรวจพบได้เหมือนคนที่ใช้ java.util.Random หรือ Mersenne Twister การวิเคราะห์เชิงสถิติไม่ใช่กลไกการตรวจสอบที่ถูกต้องเพียงอย่างเดียวสำหรับ RNG / ปัญหาโดเมนไม่ตรงกัน ความล้มเหลวที่ผ่านการตรวจจับนั้นไม่ประสบความสำเร็จตามคำจำกัดความ
— Paco Hope

1
ฉันไม่เคยเห็นด้วยกับข้อความนั้น สิ่งที่ฉันพูดคือการวิเคราะห์ทางสถิตินั้นไม่สามารถพิสูจน์ได้ว่า RNG / PRNG นั้นถูกต้อง นี่คือตัวอย่างของการลบที่ผิดพลาด มันควรจะไม่ถูกต้อง แต่การทดสอบผลลัพธ์ทางสถิติจะผ่านมัน ถ้าฉันใช้ SHA1 (1), SHA1 (2), SHA1 (3) ... SHA1 (n) เป็น "RNG" ของฉันที่จะผ่านการทดสอบทางสถิติด้วย มันก็ผิด คำจำกัดความของการแก้ไขที่ถูกต้องขยายเกินคำจำกัดความของ "ผ่านการทดสอบทางสถิติ" จำเป็นต้องผ่านการทดสอบทางสถิติ แต่ไม่เพียงพอ
— Paco Hope

4
@CodesInChaos: อาร์กิวเมนต์ "เราไม่ทราบว่ามีการโจมตีที่สามารถใช้ประโยชน์จากความจริงที่ว่าส่วนใหญ่ที่เป็นไปได้ - IRL - shuffles จะไม่ถูกผลิต" ไม่ได้หมายความว่าการโจมตีดังกล่าวเป็นไปไม่ได้เพียงแค่ว่าเราไม่ ไม่รู้ว่ามันคืออะไรหรือจะป้องกันอย่างไร ทัศนคติที่ถูกต้องในกรณีนั้นคือการกำจัดความเป็นไปได้ของการโจมตีโดยกำจัดเงื่อนไข: สร้าง RNG ที่มีคุณภาพเพียงพอที่จริงสามารถสร้างสำรับที่เป็นไปได้ทั้งหมด
— Eric Lippert

6

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


6

ความแตกต่างระหว่างตัวเลขสุ่ม "จริง" และ "หลอก" คือความสามารถในการคาดการณ์ คำตอบนี้มีให้แล้ว

อย่างไรก็ตามความสามารถในการคาดการณ์ไม่จำเป็นต้องเป็นสิ่งที่แย่เหมือนตัวอย่างส่วนใหญ่ที่แสดง นี่คือตัวอย่างการใช้งานจริงของหนึ่งในกรณีที่หายากซึ่งการคาดการณ์ได้ดี: ระบบกำหนดตำแหน่งทั่วโลก

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


2

สำหรับการตรวจสอบแบบสุ่มอย่างรวดเร็วคุณจะได้คะแนนด้วยการสุ่มพิกัดใน [0; 1) จากนั้นใส่มันลงในคิวบ์คิว - มิติ จากนั้นคุณทำโพรซีเดอร์เพื่อแบ่งลูกบาศก์นี้เป็น subcubes - แต่ละวอลุ่มของ subcube (หรือ subsphere) ต้องถูกวัดอย่างถูกต้องโดยโพรซีเดอร์นี้พร้อมกับความผันผวนตามทฤษฎีบทที่รู้จักกันดี

คุณภาพของการสุ่มเป็นสิ่งสำคัญที่คุณพบ ...

  1. วัตถุประสงค์ด้านความปลอดภัย เมื่อคุณสร้างตัวเลขเพื่อใช้เป็นพารามิเตอร์สำหรับการสร้างคีย์ของคุณและสามารถคาดเดาได้ดี - ศัตรูจะพบว่ามันมีความน่าจะเป็น 100% และทำให้ฟิลด์สำหรับการค้นหามีขนาดเล็กลงมาก

  2. วัตถุประสงค์ทางวิทยาศาสตร์ ในทางวิทยาศาสตร์คุณจะต้องไม่เพียง แต่มีค่าเฉลี่ยอยู่ในสภาพดี แต่ยังต้องกำจัดความสัมพันธ์ระหว่างตัวเลขสุ่มต่างๆด้วย ดังนั้นหากคุณใช้ (a_i - a) (a_ {i + 1} -a) และค้นหาการแจกแจงมันต้องสอดคล้องกับสถิติ

ความสัมพันธ์ของคู่นั้นเรียกว่า "การสุ่มแบบอ่อนแอ" หากคุณต้องการการสุ่มที่แท้จริงคุณต้องมีความสัมพันธ์ลำดับสูงกับความแปรปรวนมากกว่า 2

ทุกวันนี้มีเพียงผู้สร้างกลศาสตร์ควอนตัมเท่านั้นที่ให้การสุ่มอย่างแท้จริง


1

เหตุใดการสุ่มตัวอย่างที่แท้จริงจึงสำคัญ

โดยทั่วไปมีสองสาเหตุหลักที่ทำให้การสุ่มตัวอย่างเป็นสิ่งจำเป็น:

  1. หากคุณกำลังใช้ RNG สำหรับการเข้ารหัส (รวมถึงสิ่งต่าง ๆ เช่นการพนันด้วยเงินจริงและการจับสลาก) PRNG จะทำให้คุณรู้สึกอ่อนแอกว่าการวิเคราะห์ทางคณิตศาสตร์ (ซึ่งถือว่า TRNG) จะทำให้คุณเชื่อ PRNG จะไม่ถูกสุ่ม แต่มีรูปแบบ - ฝ่ายตรงข้ามสามารถใช้ประโยชน์จากรูปแบบเพื่อถอดรหัสตัวเลขที่ควรจะแยกไม่ออก
  2. หากคุณกำลังใช้ RNG เพื่อจำลองอินพุต "สุ่ม" เช่นการทดสอบข้อผิดพลาดหรือการจำลองดังนั้น PRNG ทำให้วิธีการของคุณอ่อนแอ เมื่อคุณค้นพบข้อผิดพลาดใด ๆ จะมีข้อสงสัยที่จู้จี้: มีข้อบกพร่องที่ไม่ได้สังเกตเห็นด้วยรูปแบบของ PRNG ของฉัน แต่จะมีขึ้นถ้าฉันใช้ TRNG เท่านั้น? การค้นพบแบบจำลองของฉันอธิบายความจริงได้อย่างถูกต้องหรือว่าปรากฏการณ์ที่ฉันค้นพบเป็นเพียงสิ่งประดิษฐ์ของรูปแบบของ PRNG หรือไม่?

นอกพื้นที่เหล่านี้มันไม่สำคัญจริงๆ Caveat: ถ้า PRNG ของคุณแย่มากมันอาจไม่เหมาะสม - คุณไม่ต้องการสร้างเกม Craps ที่ลูกเต๋าขึ้นมาเสมอผู้เล่นของคุณจะไม่ชอบ

PRNG ของ Python ไม่ดีพออย่างไร

ไม่น่าเป็นไปได้มากที่คุณจะสามารถตรวจสอบข้อผิดพลาดของ PRNG จริงโดยใช้วิธีการง่าย ๆ ดังกล่าว การวิเคราะห์ทางสถิติของ RNGs เป็นศาสตร์ในสาขาของตนเองและการทดสอบที่ซับซ้อนบางอย่างนั้นมีให้ใช้เพื่อทำการเปรียบเทียบ "อัลกอริทึม" ของอัลกอริทึม สิ่งเหล่านี้ก้าวหน้ากว่าความพยายามอย่างง่ายของคุณ

นักพัฒนาซอฟต์แวร์ทุกคนที่สร้างไลบรารี่ในโลกแห่งความจริงเช่นนักพัฒนา Python ใช้การทดสอบทางสถิติเหล่านี้เป็นเครื่องมือวัดเพื่อดูว่าการใช้งาน PRNG ของพวกเขาดีพอหรือไม่ ดังนั้นยกเว้นกรณีการกำกับดูแลนักพัฒนาที่เกิดขึ้นจริงมันไม่น่าเป็นไปได้มากที่คุณจะสามารถตรวจสอบรูปแบบใน PRNG ที่ใช้งานจริงได้อย่างง่ายดาย นั่นไม่ได้หมายความว่าไม่มีรูปแบบ - PRNG มีรูปแบบตามคำนิยาม


0

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

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

ผ่านการทดสอบแบบสุ่มบางอย่างเท่านั้นหมายความว่าคุณมี PRNG ที่ดี (ตัวสร้างตัวเลขสุ่มหลอก) ซึ่งจะเป็นประโยชน์สำหรับแอปพลิเคชันที่ไม่ได้มีการรักษาความปลอดภัย

หากการรักษาความปลอดภัยมีส่วนเกี่ยวข้อง (เช่นการเข้ารหัสการสร้างกุญแจสำคัญการสร้างหมายเลขแบบสุ่มสำหรับการพนัน ... ) ไม่เพียงพอที่จะมี PRNG ที่ดีซึ่งจำเป็นต้องมีคุณสมบัติเพิ่มเติมเช่นฟังก์ชั่นเอาท์พุทที่ไม่ได้คาดเดาได้ง่ายจากผลลัพธ์ก่อนหน้า ฟังก์ชั่นจะต้องมีค่าใช้จ่ายในการคำนวณที่ต้องการ (จำกัด เพียงพอที่จะใช้งานได้ แต่สูงพอที่จะกำจัดความพยายามบังคับใช้สัตว์เดรัจฉานได้) ฮาร์ดแวร์ที่ใช้งานฟังก์ชั่น - หรืออุปกรณ์ในกรณีแปลก ๆ วันนี้มันเป็นอุปกรณ์อะนาล็อก - ไม่ควร ดัดแปลงได้อย่างง่ายดาย ฯลฯ

การมี PRNG ที่ดีจะมีประโยชน์ในเกมเพื่อสร้างรูปแบบใหม่และคาดเดาไม่ได้และในการเข้ารหัส - ยุ่งยากเกินกว่าที่จะอธิบายในโพสต์เดียวแค่คิดว่าเป็นบทบาทของหัวแม่มือสิ่งที่ออกจากกระบวนการเข้ารหัสควรหลอกแบบสุ่มไม่แสดงรูปแบบ ที่สามารถเชื่อมโยงข้อมูลที่เข้ารหัสไว้ก่อนหน้านี้กับข้อมูลที่เข้ารหัสดังต่อไปนี้หรือเชื่อมโยงข้อมูลข้อความธรรมดากับข้อมูลที่เข้ารหัสหรือเชื่อมโยง ciphertexts ที่แตกต่างกันสองรายการ (ดังนั้นสามารถทำการเดาบนข้อความธรรมดา) ....


-5

เรื่องสั้น:

สร้างเมล็ดพันธุ์แบบสุ่มโดยใช้ไมโครวินาทีปัจจุบันของระบบ

เคล็ดลับนี้ค่อนข้างเก่าและยังใช้งานได้อยู่

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

สมมติว่าตัวอย่างฉันสามารถกำหนดเมล็ดพันธุ์ที่ใช้โดยใช้เพียง 10 ค่า ดังนั้นรู้เมล็ดฉันสามารถเดาค่าต่อไป

ถ้าฉันจะใช้เมล็ด = 1 แล้วฉันจะได้รับลำดับต่อไป:

1, 2, 3, 4, 5, 6, 7, 8, 9 ... (และฉันหักว่าเมล็ดใช้ id 1 และค่าถัดไป 10)

แต่จะเกิดอะไรขึ้นถ้าหากเปลี่ยนการส่งทุกค่า "nth" การเปลี่ยน seed โดยไมโครวินาทีปัจจุบันเป็นเล่ห์เหลี่ยมถูก (นั่นคือมันไม่ต้องใช้รอบ CPU มาก)

ดังนั้นตอนนี้ลำดับคือ: (เมล็ด = 1) 1, 2, 3, 4, 5, (เมล็ด = 2), 7, 9, 11, 13 ... (15?)

ในกรณีนี้:

a) ฉันไม่สามารถหักเมล็ดที่ใช้

b) เออร์โกฉันไม่สามารถเดาค่าต่อไปได้

c) การเดาเดียวที่ฉันทำได้คือการหักว่าเมล็ดต่อไปอาจเป็นจำนวนมาก

อย่างไรก็ตามอัลกอริธึมเครื่องกำเนิดแบบสุ่มที่ทันสมัยที่สุดใช้เทคนิคนี้ภายใต้ประทุน

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


2
นี่เป็นความคิดที่ไม่ดีและเป็นแหล่งที่มาของความเสี่ยงสำหรับสิ่งที่ต้องการลำดับที่ไม่สามารถคาดเดาได้ หากคุณใช้เวลาไมโครวินาทีคุณมีความเป็นไปได้เพียง 10 ^ 6 ของเมล็ดที่ค่อนข้างต่ำ
— HoLyVieR

@HoLyVieR: มันเป็นความคิดที่ดีถ้าคุณใส่ใจเรื่องความปลอดภัย แต่ก็ไม่เลวเท่าที่คุณทำ: โดยปกติคุณจะใช้ไมโครวินาทีตั้งแต่เริ่มระบบ (หรือยูนิกซ์ยุค .... ) ซึ่งเพิ่มช่วงของค่าที่เป็นไปได้อย่างมาก
— mikera

1
@mikera มันไม่ได้ดีไปกว่านี้เวลาที่ประมวลผลคำขอนั้นสามารถคาดเดาได้ เป็นช่องโหว่ของเวกเตอร์สำหรับฟังก์ชันการรีเซ็ตรหัสผ่านจำนวนมาก สคริปต์เหล่านั้นสร้างโทเค็น "สุ่ม" ด้วยเทคนิคของคุณและผู้โจมตีสามารถค้นหาโทเค็นที่สร้างขึ้นตั้งแต่การค้นหาเวลาที่ถูกประหารชีวิตค่อนข้างไม่สำคัญ ... ในเวลาเดียวกันกับที่ส่งคำขอรีเซ็ตรหัสผ่าน + - 150ms
— HoLyVieR

แน่นอนว่าสถานการณ์นั้นแย่มาก แต่สถานการณ์ที่สถานะเริ่มต้นเมื่อระบบเริ่มต้นและผู้โจมตีไม่มีวิธีที่ดีในการคาดเดาว่าเวลาเริ่มต้นจะไม่เลวร้ายนัก คุณอาจมีไมโครวินาทีที่เป็นไปได้ 10 ^ 12 ที่สามารถเลือกได้ซึ่งทำให้การโจมตีบางประเภทเป็นไปไม่ได้ ต้องมีความชัดเจน: การแก้ปัญหาทั้งหมดเหล่านี้จะสวยไม่ดีจากมุมมองของการเข้ารหัสลับ แต่ค่าคงที่สำคัญ
— mikera

สำหรับเซิร์ฟเวอร์ออนไลน์ข้อมูลสถานะการออนไลน์ของระบบบางครั้งจะถูกนำเสนอสู่สาธารณะ หรือคุณสามารถรับได้จากหน้าสถานะ "เหตุการณ์เกิดขึ้นอีกครั้ง" หรือคุณสามารถปิงรอสักครู่ใหญ่และสังเกตว่ามันอาจเป็นการรีบูตเครื่อง (ซึ่งจะให้เวลาหลายร้อยล้านครั้งในการตรวจสอบซึ่งค่อนข้างต่ำ)
— Dereckson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.