سؤال

إذا كنت تريد رقمًا عشوائيًا قويًا من الناحية التشفيرية في Java، فاستخدمه SecureRandom.للأسف، SecureRandom يمكن أن تكون بطيئة جدًا.إذا كان يستخدم /dev/random في نظام التشغيل Linux، يمكنه منع انتظار تراكم الإنتروبيا الكافية.كيف تتجنب عقوبة الأداء؟

وقد استخدم أي شخص الرياضيات غير المألوفة كحل لهذه المشكلة؟

هل يمكن لأي شخص أن يؤكد أن مشكلة الأداء هذه قد تم حلها في JDK 6؟

هل كانت مفيدة؟

المحلول

إذا كنت تريد بيانات عشوائية حقيقية، فعليك للأسف أن تنتظرها.وهذا يشمل البذور ل SecureRandom برنج.لا يمكن للرياضيات غير الشائعة جمع بيانات عشوائية حقيقية بشكل أسرع من SecureRandom, ، على الرغم من أنه يمكنه الاتصال بالإنترنت لتنزيل البيانات الأولية من موقع ويب معين.تخميني هو أنه من غير المرجح أن يكون هذا أسرع من /dev/random حيث يتوفر ذلك.

إذا كنت تريد PRNG، فافعل شيئًا مثل هذا:

SecureRandom.getInstance("SHA1PRNG");

ما هي السلاسل المدعومة تعتمد على SecureRandom مزود SPI، ولكن يمكنك تعدادها باستخدام Security.getProviders() و Provider.getService().

صن مغرمة بـ SHA1PRNG، لذا فهي متاحة على نطاق واسع.إنها ليست سريعة بشكل خاص مثل PRNGs، لكن PRNGs ستقوم فقط بمعالجة الأرقام، وليس منع القياس الفيزيائي للإنتروبيا.

الاستثناء هو أنه إذا لم تتصل setSeed() قبل الحصول على البيانات، سيقوم PRNG بزرع نفسه بمجرد اتصالك به لأول مرة next() أو nextBytes().وعادة ما يتم ذلك باستخدام كمية صغيرة إلى حد ما من البيانات العشوائية الحقيقية من النظام.قد يتم حظر هذه المكالمة، ولكنها ستجعل مصدر الأرقام العشوائية الخاص بك أكثر أمانًا بكثير من أي نوع مختلف من "تجزئة الوقت الحالي مع PID، وإضافة 27، والأمل في الأفضل".إذا كان كل ما تحتاجه هو أرقام عشوائية للعبة، أو إذا كنت تريد أن يكون البث قابلاً للتكرار في المستقبل باستخدام نفس البذرة لأغراض الاختبار، فإن البذرة غير الآمنة لا تزال مفيدة.

نصائح أخرى

يجب أن تكون قادرًا على تحديد /dev/urandom الأسرع ولكن الأقل أمانًا على Linux باستخدام:

-Djava.security.egd=file:/dev/urandom

ومع ذلك، هذا لا يعمل مع Java 5 والإصدارات الأحدث (جافا علة 6202721).الحل البديل المقترح هو استخدام:

-Djava.security.egd=file:/dev/./urandom

(لاحظ الاضافي /./)

في نظام التشغيل Linux، يكون التطبيق الافتراضي لـ SecureRandom يكون NativePRNG (مصدر الرمز هنا)، والذي يميل إلى أن يكون بطيئًا جدًا.في نظام التشغيل Windows، الخيار الافتراضي هو SHA1PRNG, ، والذي كما أشار آخرون يمكنك استخدامه أيضًا على Linux إذا حددته بشكل صريح.

NativePRNG يختلف عن SHA1PRNG والرياضيات غير الشائعة AESCounterRNG من حيث أنه يتلقى الإنتروبيا بشكل مستمر من نظام التشغيل (من خلال القراءة من /dev/urandom).لا تكتسب PRNGs الأخرى أي إنتروبيا إضافية بعد البذر.

AESCounterRNG أسرع بنحو 10 مرات من SHA1PRNG, ، والتي تعد IIRC نفسها أسرع منها مرتين أو ثلاث مرات NativePRNG.

إذا كنت بحاجة إلى PRNG أسرع يكتسب الإنتروبيا بعد التهيئة، فراجع ما إذا كان بإمكانك العثور على تطبيق Java لـ فورتونا.إن جوهر PRNG لتطبيق Fortuna مطابق لتلك المستخدمة من قبل AESCounterRNG، ولكن هناك أيضًا نظام متطور لتجميع الإنتروبيا وإعادة البذر التلقائي.

تقوم العديد من توزيعات Linux (معظمها تعتمد على Debian) بتكوين OpenJDK للاستخدام /dev/random للانتروبيا.

/dev/random هو بحكم التعريف بطيء (ويمكن حتى أن يحجب).

من هنا لديك خياران حول كيفية إلغاء الحظر:

  1. تحسين الانتروبيا، أو
  2. تقليل متطلبات العشوائية.

الخيار 1، تحسين الانتروبيا

للحصول على المزيد من الانتروبيا /dev/random, ، جرب ال هاجد الخفي.إنه برنامج خفي يجمع باستمرار HAVEGE entropy، ويعمل أيضًا في بيئة افتراضية لأنه لا يتطلب أي أجهزة خاصة، فقط وحدة المعالجة المركزية نفسها وساعة.

على أوبونتو/ديبيان:

apt-get install haveged
update-rc.d haveged defaults
service haveged start

على RHEL/CentOS:

yum install haveged
systemctl enable haveged
systemctl start haveged

الخيار 2.تقليل متطلبات العشوائية

إذا لم يساعدك الحل أعلاه لسبب ما أو كنت لا تهتم بالعشوائية القوية من حيث التشفير، فيمكنك التبديل إلى /dev/urandom بدلاً من ذلك، وهو ما يضمن عدم الحظر.

للقيام بذلك عالميًا، قم بتحرير الملف jre/lib/security/java.security في تثبيت Java الافتراضي الخاص بك للاستخدام /dev/urandom (بسبب آخر حشرة يجب تحديده كـ /dev/./urandom).

مثله:

#securerandom.source=file:/dev/random
securerandom.source=file:/dev/./urandom

ثم لن تضطر أبدًا إلى تحديده في سطر الأوامر.


ملحوظة:إذا كنت تفعل التشفير، فإنك يحتاج الانتروبيا جيدة.مثال على ذلك - مشكلة أندرويد PRNG تقليل أمان محافظ البيتكوين.

واجهت مشكلة مماثلة مع المكالمات إلى SecureRandom الحظر لمدة 25 ثانية تقريبًا في كل مرة على خادم دبيان مقطوع الرأس.لقد قمت بتثبيت haveged الشيطان للتأكد /dev/random يتم الاحتفاظ بأعلى مستوى، على الخوادم مقطوعة الرأس، تحتاج إلى شيء مثل هذا لتوليد الإنتروبيا المطلوبة.مكالماتي ل SecureRandom الآن ربما يستغرق ميلي ثانية.

إذا كنت تريد عشوائية "قوية التشفير" حقًا، فأنت بحاجة إلى مصدر إنتروبيا قوي. /dev/random بطيء لأنه يجب عليه الانتظار حتى تقوم أحداث النظام بتجميع الإنتروبيا (قراءات القرص، وحزم الشبكة، وحركة الماوس، والضغط على المفاتيح، وما إلى ذلك).

الحل الأسرع هو مولد الأرقام العشوائية للأجهزة.قد يكون لديك بالفعل واحدة مدمجة في اللوحة الأم؛تفحص ال hw_التوثيق العشوائي للحصول على إرشادات حول معرفة ما إذا كان لديك، وكيفية استخدامه.تتضمن حزمة rng-tools برنامجًا خفيًا سيغذي الإنتروبيا الناتجة عن الأجهزة /dev/random.

إذا لم يكن HRNG متاحًا على نظامك، وكنت على استعداد للتضحية بقوة الإنتروبيا من أجل الأداء، فستحتاج إلى زرع PRNG جيد يحتوي على بيانات من /dev/random, ودع PRNG يقوم بالجزء الأكبر من العمل.هناك العديد من قوائم PRNG المعتمدة من NIST والمدرجة في القائمة SP800-90 والتي هي سهلة التنفيذ.

هناك أداة (على Ubuntu على الأقل) من شأنها أن تغذي العشوائية الاصطناعية في نظامك.الأمر ببساطة هو:

rngd -r /dev/urandom

وقد تحتاج إلى سودو في المقدمة.إذا لم يكن لديك حزمة rng-tools، فستحتاج إلى تثبيتها.لقد جربت هذا، وقد ساعدني بالتأكيد!

مصدر: مات مقابل العالم

لقد واجهت نفس الشيء مشكلة.بعد البحث في Google عن مصطلحات البحث الصحيحة، عثرت على هذه المقالة الرائعة حول المحيط الرقمي.

يعد hasged حلاً محتملاً دون المساس بالأمن.

أنا فقط أقتبس الجزء ذو الصلة من المقال هنا.

استنادًا إلى مبدأ HAPGE ، واستند سابقًا إلى المكتبة المرتبطة به ، يتيح توليد العشوائية بناءً على الاختلافات في وقت تنفيذ الكود على المعالج.نظرًا لأنه من المستحيل تقريبًا أن يستغرق الأمر نفس الوقت المحدد للتنفيذ ، حتى في نفس البيئة على نفس الأجهزة ، يجب أن يكون توقيت تشغيل برامج واحدة أو متعددة مناسبة لبذار مصدر عشوائي.بذور التنفيذ التي تم تنفيذها المصدر العشوائي لنظامك (عادة /ديف /عشوائي) باستخدام الاختلافات في عداد الطوابع الزمنية للمعالج (TSC) بعد تنفيذ حلقة بشكل متكرر

كيفية تثبيت هاجد

اتبع الخطوات الواردة في هذه المقالة. https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

لقد نشرته هنا

استخدم العشوائي الآمن كمصدر تهيئة للخوارزمية المتكررة؛يمكنك بعد ذلك استخدام أداة Mersenne للأعمال المجمعة بدلاً من تلك الموجودة في UncommonMath، والتي كانت موجودة منذ فترة وأثبتت أنها أفضل من غيرها من prng

http://en.wikipedia.org/wiki/Mersenne_twister

تأكد من تحديث العشوائي الآمن المستخدم للتهيئة بين الحين والآخر، على سبيل المثال، يمكن أن يكون لديك عشوائي آمن واحد يتم إنشاؤه لكل عميل، باستخدام مولد عشوائي زائف واحد لكل عميل، والحصول على درجة عالية بما يكفي من التوزيع العشوائي

باستخدام Java 8، وجدت ذلك عند الاتصال بنظام Linux SecureRandom.getInstanceStrong() سوف تعطيني NativePRNGBlocking خوارزمية.غالبًا ما يتم حظر هذا لعدة ثوانٍ لتوليد بضعة بايتات من الملح.

لقد تحولت إلى السؤال صراحةً NativePRNGNonBlocking بدلاً من ذلك، وكما هو متوقع من الاسم، لم يعد محظورًا.ليس لدي أي فكرة عن الآثار الأمنية المترتبة على ذلك.من المفترض أن الإصدار غير المحظور لا يضمن مقدار الإنتروبيا المستخدمة.

تحديث:حسنا، لقد وجدت هذا التفسير الممتاز.

باختصار، لتجنب الحجب، استخدم new SecureRandom().يستخدم هذا /dev/urandom, ، وهو لا يحظر وهو آمن بشكل أساسي مثل /dev/random.من المنشور:"المرة الوحيدة التي تريد فيها الاتصال بـ /dev/random هي عندما يتم تشغيل الجهاز لأول مرة، ولم تتراكم الإنتروبيا بعد".

SecureRandom.getInstanceStrong() يمنحك أقوى RNG على الإطلاق، ولكنه آمن للاستخدام فقط في المواقف التي لن تؤثر عليك فيها مجموعة من عمليات الحظر.

المشكلة التي أشرت إليها /dev/random ليس مع SecureRandom الخوارزمية، ولكن مع مصدر العشوائية التي تستخدمها.الاثنان متعامدان.يجب عليك معرفة أي واحد من الاثنين يبطئك.

تشير صفحة الرياضيات غير الشائعة التي قمت بربطها صراحةً إلى أنها لا تعالج مصدر العشوائية.

يمكنك تجربة موفري JCE مختلفين، مثل BouncyCastle، لمعرفة ما إذا كان تنفيذهم أم لا SecureRandom أسرع.

نبذه يبحث يكشف أيضًا عن تصحيحات Linux التي تستبدل التطبيق الافتراضي بـ Fortuna.لا أعرف الكثير عن هذا الأمر، لكن مرحبًا بك للتحقيق فيه.

يجب أن أذكر أيضًا أنه على الرغم من خطورة استخدام تطبيق تم تنفيذه بشكل سيء SecureRandom الخوارزمية و/أو مصدر العشوائية، يمكنك تشغيل موفر JCE الخاص بك من خلال تنفيذ مخصص لـ SecureRandomSpi.سوف تحتاج إلى إجراء عملية مع Sun للحصول على توقيع مقدم الخدمة الخاص بك، ولكن الأمر في الواقع بسيط جدًا؛إنهم فقط يحتاجون منك أن ترسل لهم عبر الفاكس نموذجًا يوضح أنك على علم بقيود التصدير الأمريكية على مكتبات التشفير.

لم أواجه هذه المشكلة بنفسي، لكنني قمت بإنشاء سلسلة رسائل عند بدء البرنامج والتي تحاول على الفور إنشاء بذرة، ثم تموت.الطريقة التي تستدعيها من أجل Randoms سوف تنضم إلى هذا الخيط إذا كانت حية، لذا يتم حظر المكالمة الأولى فقط إذا حدثت في وقت مبكر جدًا من تنفيذ البرنامج.

تجربتي كانت فقط مع التهيئة البطيئة لـ PRNG، وليس مع توليد بيانات عشوائية بعد ذلك.جرب استراتيجية تهيئة أكثر حماسًا.نظرًا لأن إنشائها مكلف، تعامل معها كقطعة مفردة وأعد استخدام نفس المثيل.إذا كان هناك الكثير من تنافس سلسلة المحادثات لمثيل واحد، فقم بتجميعها أو جعلها سلسلة رسائل محلية.

لا تتنازل عن توليد الأرقام العشوائية.الضعف هناك يعرض للخطر كل أمنك.

لا أرى الكثير من المولدات المعتمدة على الاضمحلال الذري COTS، ولكن هناك العديد من الخطط المتوفرة لها، إذا كنت تحتاج حقًا إلى الكثير من البيانات العشوائية.أحد المواقع التي تحتوي دائمًا على أشياء مثيرة للاهتمام للنظر إليها، بما في ذلك HotBits، هو مختبر فورميلاب لجون ووكر.

يبدو أنك يجب أن تكون أكثر وضوحًا بشأن متطلبات RNG الخاصة بك.أقوى متطلبات RNG المشفرة (كما أفهمها) هي أنه حتى لو كنت تعرف الخوارزمية المستخدمة لتوليدها، وتعرف جميع الأرقام العشوائية التي تم إنشاؤها مسبقًا، فلن تتمكن من الحصول على أي معلومات مفيدة حول أي من الأرقام العشوائية التي تم إنشاؤها في المستقبل، دون إنفاق قدر غير عملي من قوة الحوسبة.

إذا لم تكن بحاجة إلى هذا الضمان الكامل للعشوائية، فمن المحتمل أن تكون هناك مقايضات مناسبة للأداء.وأود أن أميل إلى الاتفاق مع رد دان داير حول AESCounterRNG من Uncommons-Maths، أو Fortuna (أحد مؤلفيها هو Bruce Schneier، وهو خبير في التشفير).لم أستخدم أيًا منهما أبدًا ولكن الأفكار تبدو جيدة للوهلة الأولى.

أود يفكر أنه إذا كان بإمكانك إنشاء بذرة عشوائية أولية بشكل دوري (على سبيل المثال.مرة واحدة في اليوم أو الساعة أو أي شيء آخر)، يمكنك استخدام تشفير دفق سريع لإنشاء أرقام عشوائية من أجزاء متتالية من الدفق (إذا كان تشفير الدفق يستخدم XOR، فما عليك سوى تمرير دفق من القيم الخالية أو الحصول على بتات XOR مباشرةً).تشفير البث الإلكتروني يحتوي المشروع على الكثير من المعلومات الجيدة بما في ذلك معايير الأداء.لن يحافظ هذا على الإنتروبيا بين النقاط الزمنية التي تجددها، لذلك إذا عرف شخص ما أحد الأرقام العشوائية والخوارزمية التي استخدمتها، فمن الناحية الفنية قد يكون من الممكن، مع الكثير من القوة الحاسوبية، كسر تشفير الدفق و تخمين حالتها الداخلية لتتمكن من التنبؤ بالأرقام العشوائية المستقبلية.لكن عليك أن تقرر ما إذا كان هذا الخطر وعواقبه كافيين لتبرير تكلفة الحفاظ على الإنتروبيا.

يحرر:وهنا بعض ملاحظات دورة التشفير على RNG لقد وجدت على شبكة الإنترنت التي تبدو وثيقة الصلة بهذا الموضوع.

إذا كان جهازك يدعم ذلك فحاول باستخدام جافا RdRand المساعدة الذي أنا المؤلف.

انها تقوم على إنتل RDRAND التعليمات وهو أسرع بحوالي 10 مرات من SecureRandom ولا توجد مشكلات في النطاق الترددي للتنفيذ بكميات كبيرة.


لاحظ أن هذا التنفيذ يعمل فقط على وحدات المعالجة المركزية (CPU) التي توفر التعليمات (أي.عندما rdrand تم تعيين علامة المعالج).تحتاج إلى إنشاء مثيل له بشكل صريح من خلال RdRandRandom() البناء؛لا محددة Provider وقد تم تنفيذ.

شيء آخر يجب النظر إليه هو الخاصية Securerandom.source في الملف lib/security/java.security

قد تكون هناك فائدة في الأداء لاستخدام /dev/urandom بدلاً من /dev/random.تذكر أنه إذا كانت جودة الأرقام العشوائية مهمة، فلا تقدم على حل وسط يخرق الأمان.

يمكنك تجربة مشروع Apache commons Math، الذي يحتوي على بعض تطبيقات الخوارزميات المعروفة:

https://commons.Apache.org/proper/commons-math/userguide/random.html

ومع ذلك، كن حذرا مع الأداء.المنشئ الافتراضي لـ RandomDataGenerator ينشئ مثيلًا مخصصًا لـ Well19937c, ، وهي عملية مكلفة للغاية.

وفقا للوثائق، هذه الفئة ليس مؤشر ترابط آمن، ولكن إذا كان بإمكانك ضمان وصول مؤشر ترابط واحد فقط إلى هذه الفئة، فيمكنك تهيئة مثيل واحد فقط لكل مؤشر ترابط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top