randomSeed(analogRead(x))
কেবলমাত্র 255 সংখ্যার সিক্যুয়েন্স তৈরি করবে, যা সমস্ত কম্বো চেষ্টা করে তাত্পর্যপূর্ণ করে এমন একটি ওরাকল তৈরি করে যা আপনার আউটপুট প্রবাহকে দম্পতি করতে পারে, সমস্ত আউটপুট 100% পূর্বাভাস দেয়। আপনি যদিও সঠিক পথে রয়েছেন এটি কেবল একটি সংখ্যার খেলা এবং এগুলির জন্য আপনাকে আরও অনেক বেশি প্রয়োজন। উদাহরণস্বরূপ, ৪ টি এডিসি থেকে ১০০ টি এনালগ রিড নেওয়া, সেগুলির সমস্ত সংক্ষিপ্ত করে নেওয়া এবং খাওয়ানো randomSeed
আরও ভাল। সর্বাধিক সুরক্ষার জন্য আপনার অপ্রত্যাশিত ইনপুট এবং অ-নিরোধক উভয়ই মিশ্রণের প্রয়োজন।
আমি কোনও ক্রিপ্টোগ্রাফার নই, তবে আমি হার্ডওয়্যার এবং সফ্টওয়্যার এলোমেলো জেনারেটর নিয়ে গবেষণা এবং বিল্ডিংয়ের জন্য কয়েক হাজার ঘন্টা ব্যয় করেছি, তাই আমি যা শিখেছি তার কিছু ভাগ করে নিই:
অপ্রত্যাশিত ইনপুট:
- অ্যানালগ রিড () (ভাসমান পিনগুলিতে)
- GetTemp ()
সম্ভাব্য অপ্রত্যাশিত ইনপুট:
- মাইক্রো () (ডাব্লু / একটি অ-ডিস্ট্রিমেন্টিক নমুনা সময়কাল)
- ক্লক জিটার (লো ব্যান্ডউইথ, তবে ব্যবহারযোগ্য)
- রিডভিসিসি () (ব্যাটারি চালিত না হলে)
বাহ্যিক অপ্রত্যাশিত ইনপুট:
- অস্থায়ী, আর্দ্রতা এবং চাপ সেন্সর
- মাইক্রোফোনের
- এলডিআর ভোল্টেজ ডিভাইডার
- বিপরীত পক্ষপাত ট্রানজিস্টর শব্দ
- কম্পাস / ত্বরণ জিটার
- esp8266 ওয়াইফাই হটস্পট স্ক্যান (এসএসডি, ডিবি, ইত্যাদি)
- esp8266 সময়সীমা (পটভূমি ওয়াইফাই কাজগুলি নির্ধারিত মাইক্রো তৈরি করে () অনির্দিষ্ট করে তোলে)
- esp8266 HWRNG -
RANDOM_REG32
অত্যন্ত দ্রুত এবং অবিশ্বাস্য, একটি 1-স্টপ
সংগ্রহ
আপনি শেষ কাজটি করতে চান এন্ট্রপি যেমন হয় আসে। এক বালতি মুদ্রার চেয়ে কয়েন ফ্লিপ অনুমান করা আরও সহজ। সামিং ভাল। unsigned long bank;
তাহলে পরে bank+= thisSample;
ভাল; এটি ঘূর্ণায়মান হবে। bank[32]
আরও ভাল, পড়ুন। আপনি আউটপুট প্রতিটি অংশের জন্য ইনপুট এর কমপক্ষে 8 টি নমুনা সংগ্রহ করতে চান, আদর্শভাবে আরও অনেক কিছু।
বিষের বিরুদ্ধে সুরক্ষা
যদি বোর্ডটি গরম করার ফলে নির্দিষ্ট সর্বাধিক ঘড়ির ঝাঁকুনির সৃষ্টি হয় তবে এটি আক্রমণ আক্রমণকারী। অ্যানালগ রিড () ইনপুটগুলির দিকে আরএফআই ব্লাস্টিংয়ের সাথে একই। অন্য এক সাধারণ আক্রমণটি ইউনিটকে কেবল প্লাগ ইন করে রাখে এবং এইভাবে সমস্ত জমে থাকা এনট্রপি ডাম্প করে। এমনকি গতি ব্যয়ে এমনকি এটি করা নিরাপদ না হওয়া অবধি আপনার সংখ্যা আউটপুট করা উচিত নয়।
এজন্য আপনি EEPROM, SD ইত্যাদি ব্যবহার করে দীর্ঘমেয়াদে কিছুটা ইন্ট্রপিকে রাখতে চান, ফরচুনা পিআরএনজি দেখুন , যা 32 টি ব্যাঙ্ক ব্যবহার করে, প্রতিটি তার আগের হিসাবে প্রায় অর্ধেক আপডেট হয়। এটি যুক্তিসঙ্গত সময়ে সমস্ত 32 টি ব্যাঙ্ককে আক্রমণ করা শক্ত করে তোলে।
প্রসেসিং
একবার আপনি "এন্ট্রপি" সংগ্রহ করার পরে, আপনাকে এটিকে পরিষ্কার করতে হবে এবং কঠোর-বিপরীত পথে ইনপুট থেকে ডিভোর্স দিতে হবে। এসএএএ / 1/256 এটির জন্য ভাল। আপনার কাছে একটি সরলপাঠের দুর্বলতা না থাকায় আপনি গতির জন্য SHA1 (বা এমনকি MD5 এমনকি) ব্যবহার করতে পারেন। ফসল কাটাতে কখনই পুরো এনটপি ব্যাঙ্ক ব্যবহার করবেন না এবং কোনও এনট্রপি ব্যাঙ্ক পরিবর্তন না করে অভিন্ন ফলাফলকে প্রতিরোধ করতে সর্বদা আউটপুটটিতে সর্বদা একটি "নুন" যুক্ত করুন: output = sha1( String(micros()) + String(bank[0]) + [...] );
শে ফাংশন দু'টি আউটপুট এবং সাদা রঙের আউটপুট আড়াল করে দুর্বল বীজের বিরুদ্ধে রক্ষা করে, কম জমে থাকা এনটি, এবং অন্যান্য সাধারণ সমস্যা।
টাইমার ইনপুটগুলি ব্যবহার করতে, আপনাকে সেগুলি নির্বিচারবাদী করতে হবে। এটি একটি সাধারণ হিসাবে delayMicroseconds(lastSample % 255)
; যা সময়ের একটি অপ্রত্যাশিত পরিমাণকে বিরতি দেয় এবং "ক্রমাগত" ঘড়িটি অ-ইউনিফর্মের সাথে পার্থক্য করে making আধা-নিয়মিত করুন, যেমন if(analogRead(A1)>200){...}
, সরবরাহিত A1 শোরগোলযুক্ত বা গতিশীল ইনপুটটিতে আবদ্ধ। আপনার প্রবাহের প্রতিটি কাঁটাচামচ নির্ধারণের পরিবর্তে তৈরি করা পচে যাওয়া / ছিঁড়ে যাওয়া আউটপুটটিতে ক্রিপটোয়ানালাইসিসকে আটকাবে।
আসল সুরক্ষা হ'ল যখন আক্রমণকারী আপনার পুরো সিস্টেমটি জানে এবং এখনও এটি অতিক্রম করতে অসহায় থাকে।
সবশেষে, আপনার কাজ পরীক্ষা করুন। ENT.EXE (নিক্স / ম্যাকের জন্য উপলব্ধ) এর মাধ্যমে আপনার আউটপুট চালান এবং দেখুন এটি কোনও ভাল কিনা। সর্বাধিক গুরুত্বপূর্ণ হ'ল চি বর্গ বিতরণ, যা সাধারণত 33% এবং 66% এর মধ্যে হওয়া উচিত। আপনি যদি 1.43% বা 99.999% বা এর মতো কিছু পেয়ে থাকেন তবে একের পর এক পরীক্ষার বেশি, আপনার এলোমেলো কর্কশ। আপনি অবশ্যই এনট্রপি ইএনটি প্রতিবেদন হিসাবে বাইট প্রতি 8 বিটের কাছাকাছি,> অবশ্যই 7.9 নিশ্চিত করতে চান।
টিএলডিআর: সবচেয়ে সহজ বোকা-প্রমাণ উপায় হল ESP8266 এর এইচডব্লিউআরএনজি N এটি দ্রুত, অভিন্ন এবং অনুমানযোগ্য। আর্ডুনিও কোর চলমান কোনও ESP8266 এ এর মতো কিছু চালান, এবং AVR এর সাথে কথা বলার জন্য সিরিয়াল ব্যবহার করুন:
// ESP8266 Arduino core code:
void setup(){
Serial.begin(9600); // or whatever
}
void loop() {
// Serial.write((char)(RANDOM_REG32 % 256)); // "bin"
Serial.print( String(RANDOM_REG32, HEX).substring(1)); // "hex"
}
** সম্পাদনা করুন
এখানে একটি খালি বোর্ডের এইচডব্লিউআরএনজি স্কেচ আমি কিছুক্ষণ আগে লিখেছিলাম, এটি কেবল একজন সংগ্রাহক হিসাবে নয়, পুরো সিএসপিআরএনজি সিরিয়াল বন্দরের বাইরে থুতু ফেলে। এটি একটি প্রো-মিনি জন্য নির্মিত তবে অন্য বোর্ডগুলির সাথে সহজেই মানিয়ে নেওয়া উচিত। আপনি কেবল ভাসমান অ্যানালগ পিনগুলি ব্যবহার করতে পারেন তবে তাদের মধ্যে স্টাফ যুক্ত করা ভাল, পছন্দমত ভিন্ন জিনিস। মাইক্রোফোন, এলডিআর, থার্মিস্টর (ঘরের টেম্পের চারপাশে সর্বাধিক ছড়িয়ে ছাঁটাই) এবং এমনকি দীর্ঘ তারগুলি আপনার মাঝারি শব্দ থাকলেও এটি ইএনটিতে বেশ ভাল করে does
স্কেচটি আমার উত্তর এবং ফলো-আপ মন্তব্যগুলিতে আমি উল্লেখ করেছি এমন কয়েকটি ধারণাকে একীভূত করেছে: এনট্রপি সংগ্রহ করা, কম-আদর্শ-আদর্শ এনট্রোপি (ভন নিউম্যান বলেছিল এটি দুর্দান্ত) ওভার স্যাম্পলিং দ্বারা প্রসারিত, এবং অভিন্নতা অর্জনের জন্য। এটি এনট্রপি মানের অনুমানটি "সম্ভবত গতিময় কোনও কিছু" গেমের পক্ষে এবং কোনও ক্রিপ্টোগ্রাফিক আদিম ব্যবহার করে মেশানোর পক্ষে যায়।
// AVR (ardunio) HWRNG by dandavis. released to public domain by author.
#include <Hash.h>
unsigned long read[8] = {0, 0, 0, 0, 0, 0, 0, 0};
const int pincount = 9; // adjust down for non pro-mini boards
int pins[9] = {A0, A1, A2, A3, A4, A5, A6, A7, A0}; // adjust for board, name analog inputs to be sampled
unsigned int ticks = 0;
String buff = ""; // holds one round of derivation tokens to be hashed.
String cache; // the last read hash
void harvest() { // String() slows down the processing, making micros() calls harder to recreate
unsigned long tot = 0; // the total of all analog reads
buff = String(random(2147483647)) + String(millis() % 999);
int seed = random(256) + (micros() % 32);
int offset = random(2147483647) % 256;
for (int i = 0; i < 8; i++) {
buff += String( seed + read[i] + i + (ticks % 65), HEX );
buff += String(random(2147483647), HEX);
tot += read[i];
}//next i
buff += String( (micros() + ticks + offset) % 99999, HEX);
if (random(10) < 3) randomSeed(tot + random(2147483647) + micros());
buff = sha1( String(random(2147483647)) + buff + (micros()%64) + cache); // used hash to uniform output and waste time
Serial.print( buff ); // output the hash
cache = buff;
spin();
}//end harvest()
void spin() { // add entropy and mix
ticks++;
int sample = 128;
for (int i = 0; i < 8; i++) { // update ~6/8 banks 8 times
read[ read[i] % 8] += (micros() % 128);
sample = analogRead( pins[i] ); // a read from each analog pin
read[ micros() % 8] += ( read[i] % 64 ); // mix timing and 6LSBs from read
read[i] += sample; // mix whole raw sample
read[(i + 1) % 8] += random(2147483647) % 1024; // mix prng
read[ticks % 8] += sample % 16; // mix the best nibble of the read
read[sample % 8] += read[ticks % 8] % 2147483647; // intra-mix banks
}
}//end spin()
void setup() {
Serial.begin(9600);
delay(222);
int mx = 2028 + ((analogRead(A0) + analogRead(A1) + analogRead(A2) + analogRead(A3)) % 256);
while (ticks < mx) {
spin();
delay(1);
randomSeed(read[2] + read[1] + read[0] + micros() + random(4096) + ticks);
}// wend
}// end setup()
void loop() {
spin();
delayMicroseconds((read[ micros() % 8] % 2048) + 333 );
delay(random(10));
//if (millis() < 500) return;
if ((ticks % 16) == (millis() % 16) ) harvest();
}// end loop()