2016-06-04 14 views
9

timing attacks को रोकने के लिए, एक निरंतर समय equals कभी-कभी आवश्यक होता है। MessageDigest.isEqual एक निरंतर समय विधि और guava HashCode.equals और अन्य होने के लिए प्रलेखित नहीं है। वे सब के सबलगातार समय

boolean areEqual = true; 
for (int i = 0; i < this.bytes.length; i++) { 
    areEqual &= (this.bytes[i] == that.getBytesInternal()[i]); 
} 
return areEqual; 

या

int result = 0; 
    for (int i = 0; i < digesta.length; i++) { 
     result |= digesta[i]^digestb[i]; 
    } 
    return result == 0; 

लेकिन की तरह कुछ करना है जो कहता है कि JIT जब अनुकूलन के एक शॉर्ट सर्किट को लागू नहीं कर सकते?

यह पता लगाना मुश्किल नहीं है कि areEqual कभी भी सच नहीं होगा और लूप तोड़ देगा। एक घर का बना Blackhole


मैं सभी इनपुट बिट्स के आधार पर एक मूल्य की गणना करने के लिए और यह भोजन करके यह a try on CR दे दी है।

उत्तर

0

एक जैसे अनुकूलन रोका जा सकता है:

int res = 0; 
for (int i = 0; i < this.bytes.length; i++) { 
    res |= this.bytes[i]^that.getBytesInternal()[i]; 
} 
Logger.getLogger(...).log(FINEST, "{0}", res); 
return res == 0; 

लेकिन मूल कोड पर:

पुराने कोड एक शायद javap साथ एकत्रित न चाहिए देखने के लिए कि कोई अनुकूलन के साथ बनाया गया था। एक अन्य जावा कंपाइलर (जैसे जावा 9) के लिए उसे दोहराने की आवश्यकता होगी।

जेआईटी देर से चलता है, लेकिन फिर आप सही हैं, अनुकूलन हो सकता है: इसे लूप में एक अतिरिक्त परीक्षण की आवश्यकता होगी (जो स्वयं प्रत्येक चक्र को धीमा कर देता है)।

तो आप सही हैं। कोई उम्मीद कर सकता है कि प्रभाव पूरे माप में लापरवाह है। और कुछ अन्य सुरक्षित गार्ड मदद करता है, अगर केवल असफलता पर यादृच्छिक देरी, असमानता, जो हमेशा एक अच्छा ठोकर ब्लॉक है।

+0

शॉर्ट सर्किट को रोकने के बाहर एक लॉग स्टेटमेंट कैसे होगा? –

+0

@SleimanJneidi परिणाम के रूप में 'res' लॉग है, इसकी गणना अंत तक की जानी चाहिए, इसलिए लूप को संक्षिप्त-सर्किट नहीं किया जा सकता है। –

+0

... जब तक आपको किसी बिंदु पर 'res == -1' नहीं मिलता है और फिर आप लूप से बाहर निकल सकते हैं। लेकिन यह एक अलग परीक्षण होगा और मैं कल्पना कर सकता हूं कि ऐसा करने वाला एक कंपाइलर नहीं है। – maaartinus

5

तुम्हें पता नहीं कर सकते हैं भविष्य

आप मौलिक या किसी भी भाषा में ऐसा नहीं हो सकता है हो सकता है कि भविष्य में क्या optimisers अनुमान नहीं लगा सकते।

भविष्य को देखने के लिए, ओएस के लिए सबसे अच्छा बाधाएं समय-समय पर निरंतर परीक्षण प्रदान करने के लिए होती हैं, इस तरह उन्हें सभी वातावरण में सही ढंग से परीक्षण और उपयोग किया जा सकता है।

यह काफी समय से पहले से चल रहा है। जैसे Libc में timingsafe_bcmp() फ़ंक्शन पहले ओपनबीएसडी 4.9 में दिखाई दिया। (मई 2011 में जारी)।

जाहिर है प्रोग्रामिंग वातावरण इन्हें चुनने और/या अपने स्वयं के कार्यों को प्रदान करने की आवश्यकता है जो वे गारंटी देते हैं कि उन्हें अनुकूलित नहीं किया जाएगा।

विधानसभा कोड

का निरीक्षण वहाँ optimisers here की कुछ चर्चा है। यह सी (और सी ++) दिमाग में है, लेकिन यह वास्तव में स्वतंत्र भाषा है कि आप केवल वर्तमान ऑप्टिमाइज़र क्या कर सकते हैं, भविष्य में अनुकूलक क्या कर सकते हैं, यह देख सकते हैं। वैसे भी वे सही तरीके से असेंबली कोड की जांच करने की सलाह देते हैं ताकि यह जानने के लिए कि आपका अनुकूलक क्या करता है।

जावा के लिए यह आवश्यक नहीं है कि सी या सी ++ के रूप में "आसान" के रूप में यह आवश्यक न हो, लेकिन विशिष्ट सुरक्षा कार्यों के लिए यह वास्तव में असंभव नहीं होना चाहिए कि वर्तमान वातावरण के लिए वास्तव में ऐसा प्रयास करें।

बचाव संभव

हो सकता है आप समय का दौरा पड़ने से बचने की कोशिश कर सकता है।

उदा .:

  • Double randomised HMAC verification: मूलतः यह दोनों तार तुलना करने के लिए करने के लिए एक क्रिप्टो गुणवत्ता अनियमितता कहते हैं, इनपुट के नए हैश की गणना करता है और एक सामान्य तुलना के साथ उन लोगों तुलना करती है। यहां तक ​​कि यदि अंतिम तुलना पूरी चीज को लीक करती है, तो यह तुलना कर रहा है, हैश के साथ संयुक्त क्रिप्टो स्तर यादृच्छिकता वास्तव में तुलना करना चाहता है। यहां हैश टकराव का एक स्पष्ट जोखिम है, लेकिन वे काफी दुर्लभ होना चाहिए। यह भी देखें: https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/february/double-hmac-verification/

सहज यादृच्छिक समय के अलावा करने के लिए टिंग लग सकता है, यह काम नहीं करेगा: हमलावरों को पहले से ही समय हमलों में सांख्यिकीय विश्लेषण उपयोग कर रहा है, तो आप केवल कुछ और शोर जोड़ें।

https://security.stackexchange.com/questions/96489/can-i-prevent-timing-attacks-with-random-delays

फिर भी: यह मतलब नहीं है कि आप एक समय लगातार कार्यान्वयन आपके आवेदन काफी धीमी गति से हो सकता है, अगर नहीं कर सकता। i.e .: काफी देर तक प्रतीक्षा करें। जैसे आप टाइमर को जाने के लिए इंतजार कर सकते हैं और फिर भी समय पर हमले से बचने की तुलना के परिणाम को संसाधित करना जारी रख सकते हैं।

जांच

यह अनुप्रयोगों में हमले जोखिम समय निरंतर तुलना समय के एक कार्यान्वयन का उपयोग करने का पता लगाने में लिखने के लिए संभव हो जाना चाहिए।

ईथर: कि initialisation

  • सामान्य कार्यों के एक भाग के रूप में एक ही परीक्षण नियमित रूप से चलाया जाता है के दौरान

    • कुछ परीक्षण।

    फिर से ऑप्टिमाइज़र को निपटने के लिए मुश्किल हो रही है क्योंकि यह (और कभी-कभी) चीजों के निष्पादन के क्रम को भी बदल सकती है। लेकिन उदा। इनपुट का उपयोग करके प्रोग्राम में उसके कोड (जैसे बाहरी फ़ाइल) नहीं है, और इसे दो बार चला रहा है: एक बार सामान्य तुलना और समान तारों के साथ, एक बार पूरी तरह से अलग तारों (xored eg) के साथ और फिर फिर उन इनपुट के साथ निरंतर समय की तुलना करें। अब आपके पास 4 समय हैं: सामान्य तुलना समान नहीं होनी चाहिए, निरंतर समय की तुलना धीमी और समान होनी चाहिए। यदि यह विफल रहता है: एप्लिकेशन के उपयोगकर्ता/रखरखाव को चेतावनी दें कि उत्पादन के उपयोग में निरंतर समय की सामग्री टूट जाती है।

    • एक सैद्धांतिक विकल्प वास्तविक समय स्वयं को रिकॉर्ड करना है (रिकॉर्ड विफल/सफलता भी) और सांख्यिकीय रूप से उनका विश्लेषण करें। लेकिन अभ्यास में प्रदर्शन करना मुश्किल होगा क्योंकि आपके माप को बेहद सटीक होने की आवश्यकता होगी क्योंकि आप इसे कुछ मिलियन बार लूप नहीं कर सकते हैं, आप केवल एक तुलना को मापने के साथ काम कर रहे हैं और इसे सटीक रूप से पर्याप्त मापने के लिए संकल्प नहीं होगा। ..
  • 5

    JIT न केवल अनुमति इस तरह के अनुकूलन करने के लिए है, लेकिन यह वास्तव में ऐसा कभी कभी होता है।

    यहां a sample bug है जो मैंने जेएमएच में पाया है, जहां शॉर्ट सर्किट ऑप्टिमाइज़ेशन के परिणामस्वरूप अस्थिर बेंचमार्क स्कोर हुए। के बजाय के बजाय bool1 और bool2 को volatile घोषित किया गया था, इसके बावजूद के मूल्यांकन को अनुकूलित किया गया है।

    जेआईटी इस बात पर कोई गारंटी नहीं देता है कि यह अनुकूलित करता है और यह क्या नहीं करता है। यहां तक ​​कि यदि आप सत्यापित करते हैं कि यह आपके काम के अनुसार काम करता है, तो भविष्य के जेवीएम संस्करण इन धारणाओं को तोड़ सकते हैं। आदर्श रूप से ऐसे महत्वपूर्ण सुरक्षा प्राइमेटिव्स के लिए मूल जेडीके पुस्तकालयों में अंतर्निहित विधियां होनी चाहिए।

    आप कुछ तकनीकों द्वारा अवांछित अनुकूलन से बचने का प्रयास कर सकते हैं, उदा।

    • अस्थिर क्षेत्रों को शामिल करता है;
    • वृद्धिशील संचय लागू करें;
    • उत्पादन दुष्प्रभाव, उदाहरण के लिए, साझा स्मृति आदि

    को लिखने लेकिन वे भी% नहीं 100 बुलेट प्रूफ हैं, तो आप उत्पन्न विधानसभा कोड को सत्यापित करने और प्रत्येक प्रमुख जावा अद्यतन के बाद यह rewview करने के लिए है ।

    1

    वास्तव में आप भविष्यवाणी नहीं कर सकते कि एक अनुकूलक क्या करेगा। फिर भी, इस मामले में आप उचित रूप से निम्न कार्य कर सकते हैं:

    1. अनन्य-या तुलना की जाने वाली मानों की गणना करें। लिया गया समय केवल मूल्यों की लंबाई पर निर्भर करता है।
    2. परिणामी बाइट्स के हैश की गणना करें। एक हैश फ़ंक्शन का उपयोग करें जो एक एकल पूर्णांक देता है।
    3. एक्सक्लूसिव- या प्रीकंप्यूटेड हैश के बराबर लंबाई अनुक्रम के साथ इस हैश।

    मुझे लगता है कि यह एक बहुत ही सुरक्षित शर्त है कि हैश फ़ंक्शंस कुछ ऐसा नहीं है जिसे अनुकूलित किया जा रहा है। और परिणाम के बावजूद एक विशेष-या पूर्णांक के बीच एक ही गति है।

    +2

    'int' लौटने से '2 ** - 32', यानी' 2.3e-10' की संभावना के साथ टकराव हो सकता है, जो सुरक्षा-संवेदनशील किसी भी चीज़ के लिए बहुत अधिक है। टक्कर का अनुमान लगाने के लिए आप रहस्य का अनुमान लगा सकते हैं ('2 ** - 256', यानी असंभव) जैसे मौका। +++ 'long' का उपयोग करना बेहतर होगा (और 64-बिट JVM पर स्थिर समय भी), लेकिन अभी भी पर्याप्त नहीं है। – maaartinus

    संबंधित मुद्दे