পাসওয়ার্ডের জন্য স্ট্রিংয়ের চেয়ে চর [] কেন পছন্দ করা হয়?


3420

সুইং-এ, পাসওয়ার্ড ক্ষেত্রে সাধারণ getPassword()(রিটার্ন char[]) পদ্ধতির পরিবর্তে একটি getText()(রিটার্ন String) পদ্ধতি থাকে। তেমনি, আমি Stringপাসওয়ার্ডগুলি হ্যান্ডেল না করার জন্য একটি পরামর্শ পেয়েছি ।

Stringপাসওয়ার্ড এলে কেন সুরক্ষার জন্য হুমকি তৈরি করে? এটি ব্যবহার করতে অসুবিধা বোধ করে char[]

উত্তর:


4287

স্ট্রিংগুলি অপরিবর্তনীয় । এর অর্থ একবার তৈরি করার পরে String, যদি অন্য কোনও প্রক্রিয়া মেমরি ডাম্প করতে পারে তবে কোনও উপায় নেই ( প্রতিচ্ছবি বাদ দিয়ে ) আবর্জনা সংগ্রহের আগে ডেটা থেকে মুক্তি পেতে পারেন ।

একটি অ্যারে দিয়ে আপনি সম্পূর্ণরূপে ডেটা শেষ করার পরে স্পষ্টভাবে মুছতে পারেন। আপনি নিজের পছন্দ মতো কিছুতে অ্যারে ওভাররাইট করতে পারেন এবং আবর্জনা সংগ্রহের আগেও পাসওয়ার্ড সিস্টেমে কোথাও উপস্থিত হবে না।

সুতরাং হ্যাঁ, এটি একটি সুরক্ষা উদ্বেগ - তবে এমনকি এটি ব্যবহার করা char[]কেবল আক্রমণকারীর জন্য সুযোগের উইন্ডো হ্রাস করে এবং এটি কেবলমাত্র এই নির্দিষ্ট ধরণের আক্রমণের জন্য।

মন্তব্যে উল্লিখিত হিসাবে, এটি আবশ্যক যে আবর্জনা সংগ্রহকারী দ্বারা অ্যারে স্থানান্তরিত করা হবে মেমরিতে ডেটার ভ্রূক প্রতিলিপিগুলি ছেড়ে দেবে। আমি বিশ্বাস করি এই হল বাস্তবায়ন-নির্দিষ্ট - আবর্জনা সংগ্রাহক পারে সব স্মৃতি পরিষ্কার যেমন যায়, আর এই সাজানোর এড়ানো। এমনকি যদি তা হয় তবে এখনও সময় আছে যার মধ্যে char[]আক্রমণটির উইন্ডো হিসাবে প্রকৃত অক্ষর রয়েছে।


2
যদি কোনও প্রক্রিয়াটিতে আপনার অ্যাপ্লিকেশনটির স্মৃতি অ্যাক্সেস থাকে তবে এটি ইতিমধ্যে একটি সুরক্ষা লঙ্ঘন, তাই না?
ইয়েতি

5
@ ইয়েতি: হ্যাঁ, তবে এটি কালো এবং সাদা রঙের মতো নয়। যদি তারা কেবল মেমরির একটি স্ন্যাপশট পেতে পারে তবে আপনি স্ন্যাপশটটি কতটা ক্ষতি করতে পারে তা হ্রাস করতে বা উইন্ডোটি হ্রাস করতে চাইলে সেই সময়ে সত্যই গুরুতর স্ন্যাপশট নেওয়া যেতে পারে।
জন স্কিটি

11
একটি সাধারণ আক্রমণ পদ্ধতি হ'ল এমন একটি প্রক্রিয়া চালানো যা প্রচুর মেমরি বরাদ্দ করে এবং তারপরে পাসওয়ার্ডের মতো দরকারী ডেটার জন্য স্ক্যান করে। প্রক্রিয়াটির অন্য প্রক্রিয়ার মেমরি স্পেসে কোনও যাদুকরী অ্যাক্সেসের প্রয়োজন নেই; এটি কেবল সংবেদনশীল ডেটা পরিষ্কার না করেই মারা যাওয়ার অন্যান্য প্রক্রিয়াগুলির উপর নির্ভর করে এবং ওএস এটি কোনও নতুন প্রক্রিয়াতে উপলব্ধ করার আগে মেমরি (বা পৃষ্ঠা বাফার) সাফ করে না। char[]অবস্থানগুলিতে সঞ্চিত পাসওয়ার্ডগুলি সাফ করার ফলে আক্রমণটির লাইনটি কেটে যায়, এমন কিছু যা ব্যবহারের সময় সম্ভব নয় String
টেড হপ

অপারেটিং সিস্টেমের অন্য কোনও প্রক্রিয়া দেওয়ার আগে ওএস যদি মেমরি পরিষ্কার না করে তবে ওএসের সুরক্ষার বড় সমস্যা রয়েছে! তবে, প্রযুক্তিগতভাবে ক্লিয়ারিংটি প্রায়শই সুরক্ষিত মোড ট্রিক্স দিয়ে করা হয় এবং সিপিইউটি যদি ভাঙা হয় (যেমন ইন্টেল মেলডাউন) এটি পুরানো মেমরির সামগ্রীগুলি পড়া এখনও সম্ভব।
মিক্কো রেন্টালাইনেন

1221

যদিও এখানে অন্যান্য পরামর্শগুলি বৈধ বলে মনে হচ্ছে, অন্য একটি ভাল কারণ রয়েছে। সাধারণ কারণে Stringআপনার লগ , মনিটর বা অন্য কোনও সুরক্ষিত জায়গায় দুর্ঘটনাক্রমে পাসওয়ার্ড মুদ্রণের অনেক বেশি সম্ভাবনা রয়েছে । char[]কম ঝুঁকিপূর্ণ।

এই বিবেচনা:

public static void main(String[] args) {
    Object pw = "Password";
    System.out.println("String: " + pw);

    pw = "Password".toCharArray();
    System.out.println("Array: " + pw);
}

ছাপে:

String: Password
Array: [C@5829428e

39
@ ভু, তবে আমি সন্দেহ করি আপনি সরাসরি স্ট্রিম এবং কনটেনটেশনে লেখার মাধ্যমে লগ করেছেন। লগিং কাঠামোটি
চরটি

41
@ Thr4wn এর ডিফল্ট বাস্তবায়ন toStringহচ্ছে classname@hashcode[Cউপস্থাপন করে char[], বাকিটি হেক্সাডেসিমাল হ্যাশ কোড।
কনরাড গারুস 20'12

15
আকর্ষণীয় ধারণা। আমি উল্লেখ করতে চাই যে এটি স্কালায় স্থানান্তরিত করে না যা অ্যারেগুলির জন্য একটি অর্থপূর্ণ টু স্ট্রিং রয়েছে।
mauhiz

37
আমি এটির Passwordজন্য একটি ক্লাস টাইপ লিখতাম। এটি কম অস্পষ্ট এবং দুর্ঘটনাক্রমে কোথাও পাস করা আরও শক্ত।
ফেব্রুয়ারী 15'15

8
কেউ কেন ধরে নিবে যে চরটি অ্যারেটিকে অবজেক্ট হিসাবে কাস্ট করা হবে? আমি নিশ্চিত নই যে প্রত্যেকেরই এই উত্তরটি কেন পছন্দ করে। ধরুন আপনি এটি করেছেন: System.out.println ("পাসওয়ার্ড"। ​​টোচরআরে ());
GC_

680

একটি সরকারী নথিতে উদ্ধৃত করার জন্য, জাভা ক্রিপ্টোগ্রাফি আর্কিটেকচার নির্দেশিকা সম্পর্কে এই বলে char[]বনাম Stringপাসওয়ার্ড (প্রায় পাসওয়ার্ড ভিত্তিক এনক্রিপশন, কিন্তু এই কোর্সের পাসওয়ার্ড সম্পর্কে আরো সাধারণভাবে হয়):

এটি কোনও ধরণের বস্তুতে পাসওয়ার্ড সংগ্রহ এবং সংরক্ষণ করা যৌক্তিক বলে মনে হয় java.lang.String। তবে, সাবধানবাণীটি এখানে রয়েছে: Objectধরণের ধরণের Stringপরিবর্তনযোগ্য, অর্থাত্ এমন কোনও পদ্ধতি নির্ধারিত নেই যা আপনাকে পরিবর্তনের (ওভাররাইট) অনুমতি দেয় বা String ব্যবহারের পরে কোনও বিষয়বস্তু শূন্য করে দেয় । এই বৈশিষ্ট্যটি Stringব্যবহারকারীর পাসওয়ার্ডের মতো সুরক্ষা সংবেদনশীল তথ্য সংরক্ষণের জন্য অবজেক্টগুলিকে অনুপযুক্ত করে তোলে । charপরিবর্তে আপনার পরিবর্তে একটি অ্যারেতে সুরক্ষা সংবেদনশীল তথ্য সবসময় সংগ্রহ এবং সঞ্চয় করা উচিত ।

জাভা প্রোগ্রামিং ল্যাঙ্গুয়েজ, সিকিউর কোডিং গাইডলাইনসের ২-২ নির্দেশিকা, সংস্করণ ৪.০ এও একই রকম কিছু বলেছেন (যদিও এটি মূলত লগিংয়ের প্রসঙ্গে):

গাইডলাইন 2-2: অত্যন্ত সংবেদনশীল তথ্য লগ করবেন না

সামাজিক সুরক্ষা নম্বর (এসএসএন) এবং পাসওয়ার্ডগুলির মতো কিছু তথ্য অত্যন্ত সংবেদনশীল। এই তথ্যটি প্রয়োজনের চেয়ে বেশি সময়ের জন্য রাখা উচিত নয় বা এটি কোথায় দেখা যায়, এমনকি প্রশাসকরাও এটি দেখতে পারেন না। উদাহরণস্বরূপ, এটি লগ ফাইলগুলিতে প্রেরণ করা উচিত নয় এবং অনুসন্ধানের মাধ্যমে এর উপস্থিতি সনাক্তকরণযোগ্য হওয়া উচিত নয়। কিছু ক্ষণস্থায়ী ডেটা পরিবর্তনীয় ডেটা স্ট্রাকচারে রাখা যেতে পারে যেমন চর অ্যারে, এবং ব্যবহারের সাথে সাথে ক্লিয়ার করা হয়। ক্লিয়ারিং ডেটা স্ট্রাকচারগুলি কার্যকর জাভা রানটাইম সিস্টেমে কার্যকারিতা হ্রাস পেয়েছে কারণ বস্তুগুলি মেমরিতে স্বচ্ছভাবে প্রোগ্রামারটিতে স্থানান্তরিত হয়।

এই নির্দেশিকাতে নিম্ন-স্তরের গ্রন্থাগারগুলির প্রয়োগ ও ব্যবহারের ক্ষেত্রেও অন্তর্ভুক্ত রয়েছে যার সাথে তারা যে ডেটা নিয়ে কাজ করছে তার ডেপটিক জ্ঞান নেই। উদাহরণ হিসাবে, একটি নিম্ন-স্তরের স্ট্রিং পার্সিং লাইব্রেরি এতে লেখা পাঠ্য লগইন করতে পারে। কোনও অ্যাপ্লিকেশন কোনও এসএসএন গ্রন্থাগারের সাথে পার্স করতে পারে। এটি এমন পরিস্থিতি তৈরি করে যেখানে লগ ফাইলগুলিতে অ্যাক্সেস সহ প্রশাসকদের কাছে এসএসএনগুলি উপলব্ধ।


4
এটি হ'ল ত্রুটিযুক্ত / জাল রেফারেন্সটি আমি জনের উত্তরের নীচে আলোচনা করছি, এটি একটি সুপরিচিত উত্স ডাব্লু / প্রচুর সমালোচনা।
বেটসেস

37
@ বেস্টাস আপনি কি দয়া করে একটি রেফারেন্স উদ্ধৃত করতে পারেন?
user961954

10
@bestass আমরা দুঃখিত, কিন্তু Stringবেশ ভাল বোঝা যায় এবং কিভাবে এটা জেভিএম মধ্যে আচরণ করবে ... সেখানে ব্যবহার করতে ভাল কারণ আছে char[]স্থানে Stringকোনও সুরক্ষিত পদ্ধতিতে পাসওয়ার্ড সঙ্গে তার আচরণ।
স্নেকডোক

3
আবার পাসওয়ার্ডটি ব্রাউজার থেকে স্ট্রিং হিসাবে পাস করার অনুরোধ হিসাবে 'স্ট্রিং' চর নয়? সুতরাং আপনি এটি কোনও স্ট্রিংই করেন না কেন, এটি কখন অভিনয় করা উচিত এবং তা ফেলে দেওয়া উচিত, স্মৃতিতে কখনই সংরক্ষণ করা উচিত নয়?
দাওসি

3
@ দাওসি - At which point- এটি অ্যাপ্লিকেশনটি নির্দিষ্ট, তবে সাধারণ নিয়মটি হ'ল আপনি যে কোনও পাসওয়ার্ড (প্লেইন টেক্সট বা অন্যথায়) বলে মনে করছেন তা ধরে ফেললেই তা করা। উদাহরণস্বরূপ, আপনি এটি একটি HTTP অনুরোধের অংশ হিসাবে ব্রাউজার থেকে পান। আপনি ডেলিভারিটি নিয়ন্ত্রণ করতে পারবেন না, তবে আপনি নিজের স্টোরেজ নিয়ন্ত্রণ করতে পারবেন, সুতরাং এটি পাওয়ার সাথে সাথে এটি একটি চরে রাখুন [], আপনার যা করা দরকার তা করুন, তারপরে সমস্ত '0' এ সেট করুন এবং জিসিটিকে দিন এটি আবার দাবি করুন।
luis.espinal

354

char[]প্রতিটি অক্ষরকে শূন্য এবং স্ট্রিংস নয় এ সেট করে অক্ষর অ্যারে ( ) ব্যবহারের পরে সাফ করা যায়। যদি কেউ কোনওভাবে মেমোরি চিত্রটি দেখতে পারে তবে স্ট্রিংস ব্যবহার করা হলে তারা সরল পাঠ্যে একটি পাসওয়ার্ড দেখতে পারে, তবে যদি char[]0 ব্যবহার করে ডেটা শুদ্ধ করার পরে ব্যবহার করা হয় তবে পাসওয়ার্ডটি সুরক্ষিত থাকে।


13
ডিফল্টরূপে সুরক্ষিত নয়। যদি আমরা একটি ওয়েব অ্যাপ্লিকেশন কথা বলি তবে বেশিরভাগ ওয়েব পাত্রে HttpServletRequestপ্লেয়ারটেক্সটে পাসওয়ার্ডটি সেই বস্তুটিতে পাঠানো হবে। যদি জেভিএম সংস্করণটি 1.6 বা তার চেয়ে কম হয় তবে এটি পার্জেন স্পেসে থাকবে। এটি যদি 1.7 এর মধ্যে থাকে তবে এটি সংগ্রহ না হওয়া অবধি এটি পঠনযোগ্য হবে। (যখনই তা হয়))
avgvstvs

4
@avgvstvs: স্ট্রিংগুলি স্বয়ংক্রিয়ভাবে পার্জেন স্পেসে স্থানান্তরিত হয় না, এটি কেবল ইন্টার্নযুক্ত স্ট্রিংয়ের ক্ষেত্রে প্রযোজ্য। তদ্ব্যতীত, পার্জেন স্পেসটিও কেবলমাত্র কম হারে, আবর্জনা সংগ্রহের সাপেক্ষে। পার্জেন স্পেসের সাথে আসল সমস্যাটি হ'ল এটি নির্দিষ্ট আকার, যা হ'ল কারণেই কারও মনেহীনভাবে intern()নির্বিচারে স্ট্রিং না করা উচিত । তবে আপনি ঠিক বলেছেন যে Stringউদাহরণগুলি প্রথম স্থানে রয়েছে (সংগ্রহ না হওয়া পর্যন্ত) এবং সেগুলি char[]অ্যারে রূপান্তরিত করার পরে এটি পরিবর্তন হয় না।
হলগার

3
@ হলজার ডকস দেখুন। ওরা कल / জ্যাভেস / স্পেসস / জেভিএমস / এস // html/… "অন্যথায়, ক্লাস স্ট্রিংয়ের একটি নতুন উদাহরণ তৈরি করা হয়েছে যা ইউনিকোড অক্ষরগুলির ক্রম সহ CONSTANT_String_info কাঠামো দ্বারা প্রদত্ত; সেই শ্রেণীর উদাহরণটি ফলাফল স্ট্রিং আক্ষরিক ডেরাইভেশন। শেষ অবধি, নতুন স্ট্রিং উদাহরণের অভ্যন্তরীণ পদ্ধতিটি চাওয়া হয়েছে "" 1.6-এ, জেভিএম যখন অভিন্ন ক্রমগুলি সনাক্ত করে আপনার জন্য ইন্টার্ন কল করবে।
avgvstvs

3
@ হোলজার, আপনি ঠিক বলেছেন আমি ধ্রুবক পুল এবং স্ট্রিং পুলের সংঘাত ঘটিয়েছি, তবে এটিও মিথ্যা যে পার্জেন স্পেসটি কেবল অভ্যন্তরীণ স্ট্রিংগুলিতে প্রয়োগ করা হয়েছিল। 1.7 এর আগে, ধ্রুবক_পুল এবং স্ট্রিং_পুল উভয়ই পার্জেন স্পেসে থাকে। এর অর্থ হ'ল স্ট্রিংগুলির একমাত্র শ্রেণি যা আপনি বলেছিলেন তেমনই ছিল new String()বা StringBuilder.toString()আমি প্রচুর স্ট্রিং ধ্রুবক সহ অ্যাপ্লিকেশন পরিচালনা করেছিলাম এবং ফলস্বরূপ আমাদের প্রচুর পার্জেঞ্জান ক্রাইপ ছিল। 1..০০ অবধি।
avgvstvs

5
@avgvstvs: ভাল, স্ট্রিং ধ্রুবকগুলি হ'ল জেএলএস আদেশ, সর্বদা অভ্যন্তরীণ, সুতরাং বিবৃতি যে ইন্টার্নযুক্ত স্ট্রিংগুলি পার্মেজ স্পেসে শেষ হয়েছিল, স্ট্রিং ধ্রুবকগুলিকে স্পষ্টভাবে প্রয়োগ করা হয়েছিল। পার্থক্যটি হ'ল প্রথম স্থানে পার্জেন স্পেসে স্ট্রিং কনস্ট্যান্ট তৈরি করা হয়েছিল, তবে intern()একটি স্বেচ্ছাচারী স্ট্রিংকে কল করা পার্জেন স্পেসে সমমানের স্ট্রিংয়ের বরাদ্দের কারণ হতে পারে। পরবর্তী বিষয়গুলি যদি সেই একই বিষয়বস্তুকে ভাগ করে নেওয়ার মতো কোনও আক্ষরিক স্ট্রিং না থাকত তবে GC'ed পেতে পারে ...
হোলার

220

কিছু লোক বিশ্বাস করে যে আপনার আর পাসওয়ার্ডের প্রয়োজন নেই, আপনাকে পাসওয়ার্ড সংরক্ষণ করতে ব্যবহৃত মেমরিটি ওভাররাইট করতে হবে। এটি কোনও আক্রমণকারীকে আপনার সিস্টেম থেকে পাসওয়ার্ড পড়ার সময় উইন্ডো হ্রাস করে এবং পুরোপুরি এড়িয়ে যায় যে আক্রমণকারীকে এটি করতে জেভিএম মেমরি হাইজ্যাক করার জন্য ইতিমধ্যে পর্যাপ্ত অ্যাক্সেসের প্রয়োজন রয়েছে needs এত অ্যাক্সেস সহ একজন আক্রমণকারী আপনার মূল ইভেন্টগুলি এটি সম্পূর্ণরূপে অকেজো করে তুলতে পারে (এএফআইএকে, সুতরাং আমি যদি ভুল হয়ে থাকি তবে আমাকে সংশোধন করুন)।

হালনাগাদ

আমি আমার উত্তর আপডেট করতে হয়েছে মন্তব্য ধন্যবাদ। স্পষ্টতই দুটি ক্ষেত্রে রয়েছে যেখানে এটি একটি (খুব) গৌণ সুরক্ষা উন্নতি যুক্ত করতে পারে কারণ এটি হার্ড ড্রাইভে পাসওয়ার্ড নেওয়ার সময় হ্রাস করে। তবুও আমি মনে করি এটি বেশিরভাগ ব্যবহারের ক্ষেত্রে ওভারকিল।

  • আপনার টার্গেট সিস্টেমটি খারাপভাবে কনফিগার করা হয়েছে বা আপনার এটি ধরে নিতে হবে এবং কোর ডাম্প সম্পর্কে আপনাকে ভৌতিক হতে হবে (সিস্টেমগুলি যদি কোনও প্রশাসকের দ্বারা পরিচালিত না হয় তবে বৈধ হতে পারে)।
  • ভালো জিনিস ব্যবহার - আপনার সফ্টওয়্যার মাত্রাতিরিক্ত আক্রমণকারী হার্ডওয়্যার অ্যাক্সেস হত্তন সাথে ডেটা তথ্য ফাঁসের প্রতিরোধ ভীতু হতে হয়েছে TrueCrypt (বর্তমানে অপ্রচলিত), VeraCrypt , অথবা CipherShed

যদি সম্ভব হয় তবে কোর ডাম্প অক্ষম করা এবং স্ব্যাপ ফাইল উভয় সমস্যার যত্ন নেবে। যাইহোক, তাদের প্রশাসকের অধিকারের প্রয়োজন হবে এবং কার্যকারিতা হ্রাস করতে পারে (ব্যবহার করার জন্য কম স্মৃতি) এবং একটি চলমান সিস্টেম থেকে র‌্যাম টানা এখনও বৈধ উদ্বেগ হতে পারে।


33
আমি "সম্পূর্ণ অকেজো" কে "কেবলমাত্র একটি স্বল্প সুরক্ষা উন্নতি" দিয়ে প্রতিস্থাপন করব। উদাহরণস্বরূপ, আপনি যদি কোনও টিএমপি ডিরেক্টরি, একটি খারাপভাবে কনফিগার করা মেশিন এবং আপনার অ্যাপ্লিকেশনটিতে ক্র্যাশ পড়ে থাকেন তবে আপনি কোনও মেমরি ডাম্পের অ্যাক্সেস পেতে পারেন। সেক্ষেত্রে আপনি একটি কীলগার ইনস্টল করতে সক্ষম হবেন না তবে আপনি মূল ডাম্প বিশ্লেষণ করতে পারবেন
জোচিম সৌর

44
এটি সম্পন্ন করার সাথে সাথে মেমরি থেকে এনক্রিপ্ট করা ডেটা মুছে ফেলা একটি সেরা অনুশীলন হিসাবে বিবেচিত হয় কারণ এটি নির্বোধ (এটি নয়); তবে এটি আপনার হুমকির এক্সপোজার স্তর হ্রাস করে। রিয়েল টাইম আক্রমণগুলি করে এটি প্রতিরোধ করা হয় না; তবে এটি ক্ষতিগ্রস্থতা প্রশমিতকরণ সরঞ্জামটি কার্যকরভাবে মেমোরি স্ন্যাপশটের উপর বিপরীতমুখী আক্রমণে প্রকাশিত তথ্যের পরিমাণকে উল্লেখযোগ্যভাবে হ্রাস করে (উদাহরণস্বরূপ আপনার অ্যাপ্লিকেশন মেমরির একটি অনুলিপি যা একটি সোয়াপ ফাইলটিতে লেখা ছিল, বা যা স্মৃতি থেকে দূরে পড়েছিল) একটি চলমান সার্ভার থেকে এবং এর রাজ্য ব্যর্থ হওয়ার আগে অন্যটিতে চলে গেছে)।
ড্যান ইজ ফিডলিং ফায়ারলাইট

9
আমি এই প্রতিক্রিয়ার মনোভাবের সাথে একমত হতে চাই। আমি পরিণামের সর্বাধিক সুরক্ষা লঙ্ঘনের প্রস্তাব মেমরির বিটের চেয়ে বিমূর্ততার অনেক উচ্চ স্তরে ঘটানোর প্রস্তাব করতাম। অবশ্যই, হাইপার-সুরক্ষিত প্রতিরক্ষা ব্যবস্থায় সম্ভবত এমন পরিস্থিতি রয়েছে যেখানে এটি যথেষ্ট উদ্বেগের বিষয় হতে পারে তবে এই স্তরে গুরুত্ব সহকারে চিন্তা করা 99% অ্যাপ্লিকেশনগুলির জন্য ওভারকিল যেখানে নট বা জাভা ব্যবহার করা হচ্ছে (যেমন এটি আবর্জনা সংগ্রহের সাথে সম্পর্কিত) vera
কিংডাংগো

10
পাসওয়ার্ড প্রকাশ করে সার্ভার মেমরির হৃদয়বিহীন অনুপ্রবেশের পরে, "স্ট্রিং পাসওয়ার্ড ব্যবহার না করার জন্য একেবারে প্রয়োজনীয়," পরিবর্তে একটি চর [] ব্যবহার করে আমি স্ট্রিংটি "কেবলমাত্র একটি ছোট্ট সুরক্ষা উন্নতি" দিয়ে প্রতিস্থাপন করব।
পিটার ভিডিএল

9
@ পিটারভিডিএল কেবলমাত্র বাফারগুলির নির্দিষ্ট পুনরায় ব্যবহৃত সংগ্রহের পড়ার অনুমতি পেয়েছেন (পারফরম্যান্সের কারণে - নিরাপত্তা সমালোচনামূলক ডেটা এবং নেটওয়ার্ক I / O উভয়ের জন্য ব্যবহৃত হয়েছে - পারফরম্যান্সের কারণে), আপনি এটি জাভা স্ট্রিংয়ের সাথে সংযুক্ত করতে পারবেন না কারণ তারা নকশার দ্বারা পুনরায় ব্যবহারযোগ্য নয় । বা স্ট্রিংয়ের বিষয়বস্তু পেতে জাভা ব্যবহার করে এলোমেলো মেমোরিতে পড়তে পারবেন না। ভাষা এবং নকশার সমস্যাগুলি যা হৃদয়গ্রাহী হতে পারে জাভা স্ট্রিংগুলির দ্বারা সম্ভব নয়।
জোসেফএক্স

86

আমি মনে করি না এটি একটি বৈধ পরামর্শ, তবে, আমি কমপক্ষে কারণটিতে অনুমান করতে পারি।

আমি মনে করি যে অনুপ্রেরণাটি তা নিশ্চিত করার ইচ্ছে করছে যে আপনি পাসওয়ার্ডের সমস্ত চিহ্ন মেমোরিতে তাত্ক্ষণিকভাবে এবং ব্যবহারের পরে নিশ্চিতভাবে মুছে ফেলতে পারবেন। একটি দিয়ে char[]আপনি অ্যারের প্রতিটি উপাদান একটি ফাঁকা বা নিশ্চিতভাবে কিছু দিয়ে ওভাররাইট করতে পারেন। আপনি Stringসেভাবে অভ্যন্তরীণ মানটি সম্পাদনা করতে পারবেন না ।

তবে এটি একা ভাল উত্তর নয়; কেন কেবল নিশ্চিত হন না যে একটি রেফারেন্স char[]বা Stringপালাতে পারে না? তারপরে কোনও সুরক্ষা সমস্যা নেই। তবে বিষয়টি হ'ল Stringবস্তুগুলিকে intern()তত্ত্ব অনুসারে এডিট করা যায় এবং ধ্রুবক পুলের অভ্যন্তরে জীবিত রাখা যায়। আমি মনে করি ব্যবহার করা char[]এই সম্ভাবনাটিকে নিষিদ্ধ করে ।


4
আমি বলব না যে সমস্যাটি হ'ল আপনার উল্লেখগুলি "পালাতে" পারবে বা করবে না। এটি কেবলমাত্র স্ট্রিংগুলি অতিরিক্ত কিছু সময়ের জন্য স্মৃতিতে অযৌক্তিক থাকবে, যখন char[]এটি সংশোধন করা যেতে পারে এবং তারপরে এটি সংগৃহীত কিনা তা অপ্রাসঙ্গিক। এবং যেহেতু স্ট্রিং ইন্টার্নিংটি অ লিটারালদের জন্য স্পষ্টভাবে করা দরকার, এটি char[]স্ট্যাটিক ফিল্ড দ্বারা একটি রেফারেন্স করা যায় তা বলার মতো ।
গ্রো

1
ফর্ম পোস্ট থেকে স্ট্রিং হিসাবে মেমরি পাসওয়ার্ড না?
দাওসি

66

উত্তরটি ইতিমধ্যে দেওয়া হয়ে গেছে, তবে আমি জাভা স্ট্যান্ডার্ড লাইব্রেরিগুলির সাথে ইদানীং আবিষ্কার করা একটি সমস্যা ভাগ করতে চাই। যদিও তারা এখন char[]সর্বত্র পাসওয়ার্ডের স্ট্রিংগুলি প্রতিস্থাপনের ক্ষেত্রে খুব যত্ন নিচ্ছে (যা অবশ্যই ভাল জিনিস), অন্য সুরক্ষা-সমালোচনামূলক ডেটা স্মৃতি থেকে সাফ করার সময় এটি উপেক্ষা করা হবে বলে মনে হয়।

আমি যেমন প্রাইভেটকে ক্লাসের কথা ভাবছি । এমন একটি দৃশ্যের কথা বিবেচনা করুন যেখানে আপনি কোনও অপারেশন সম্পাদন করতে কোনও পি কেসিএস # 12 ফাইল থেকে একটি প্রাইভেট আরএসএ কী লোড করবেন। এখন এক্ষেত্রে, পাসওয়ার্ডকে একা স্নিগ্ধ করা ততক্ষণ আপনাকে সাহায্য করবে না যতক্ষণ না মূল ফাইলটিতে শারীরিক অ্যাক্সেস সঠিকভাবে সীমাবদ্ধ থাকবে। আক্রমণকারী হিসাবে আপনি যদি পাসওয়ার্ডের পরিবর্তে সরাসরি কীটি পেয়ে থাকেন তবে আপনি আরও ভাল। কাঙ্ক্ষিত তথ্যগুলি ফাঁস হতে পারে বহুগুণ, কোর ডাম্পস, একটি ডিবাগার সেশন বা অদলবদলের ফাইলগুলির কয়েকটি উদাহরণ।

এবং যেমন দেখা যাচ্ছে, এমন কোনও কিছুই নেই যা আপনাকে PrivateKeyমেমোরি থেকে ব্যক্তিগত তথ্য সাফ করতে দেয় , কারণ এমন কোনও API নেই যা আপনাকে সেই সম্পর্কিত বর্মগুলি মুছতে দেয়।

এটি একটি খারাপ পরিস্থিতি, কারণ এই পত্রিকা বর্ণনা করে যে কীভাবে এই পরিস্থিতিটি সম্ভাব্যভাবে ব্যবহার করা যেতে পারে।

উদাহরণস্বরূপ ওপেনএসএসএল লাইব্রেরি ব্যক্তিগত কীগুলি মুক্ত হওয়ার আগে সমালোচনামূলক মেমরি বিভাগগুলিকে ওভাররাইট করে। জাভা যেহেতু আবর্জনা-সংগৃহীত, তাই জাভা কীগুলির জন্য ব্যক্তিগত তথ্য মুছতে এবং অকার্যকর করার জন্য আমাদের স্পষ্ট পদ্ধতি প্রয়োজন হবে, যা কী ব্যবহারের সাথে সাথেই প্রয়োগ করা উচিত।


এর চারপাশের একটি উপায় PrivateKeyযা এর বাস্তবায়নটি ব্যবহার করে তা আসলে এটির ব্যক্তিগত সামগ্রী মেমরিতে লোড করে না: উদাহরণস্বরূপ একটি পিকেসিএস # 11 হার্ডওয়্যার টোকেনের মাধ্যমে। সম্ভবত পিকেসিএস # 11 এর একটি সফ্টওয়্যার বাস্তবায়ন ম্যানুয়ালি মেমরি পরিষ্কার করার জন্য যত্ন নিতে পারে। সম্ভবত এনএসএস স্টোরের মতো কিছু ব্যবহার করা (যা এর প্রয়োগের বেশিরভাগ অংশ PKCS11জাভাতে স্টোর ধরণের সাথে ভাগ করে নেয় ) আরও ভাল। KeychainStore(OSX এ কীস্টোর) লোড তার মধ্যে ব্যক্তিগত কী সম্পূর্ণ সামগ্রী PrivateKeyদৃষ্টান্ত, কিন্তু এটি প্রয়োজন করা উচিত নয়। ( WINDOWS-MYকীস্টোর উইন্ডোজে কী করে তা নিশ্চিত নয় ))
ব্রুনো

@ ব্রুনো শিওর, হার্ডওয়্যার-ভিত্তিক টোকেনগুলি এতে ভোগেনা তবে আপনি এমন পরিস্থিতিতে কী করবেন যেখানে আপনি সফ্টওয়্যার কী ব্যবহার করতে কম-বেশি বাধ্য হন? প্রতিটি স্থাপনার এইচএসএম বহন করার বাজেট নেই। সফ্টওয়্যার কী স্টোরগুলিকে এক পর্যায়ে কীটি মেমোরিতে লোড করতে হবে, তাই আইএমও কমপক্ষে আমাদের ইচ্ছামত আবার স্মৃতি মুছে ফেলার বিকল্প দেওয়া উচিত।
21-18

অবশ্যই, আমি কেবল ভাবছিলাম যে কোনও এইচএসএম এর সমতুল্য কিছু সফ্টওয়্যার বাস্তবায়ন মেমরি পরিষ্কার করার ক্ষেত্রে আরও ভাল আচরণ করতে পারে কিনা। উদাহরণস্বরূপ, সাফারি / ওএসএক্সের সাথে ক্লায়েন্ট-অথথ ব্যবহার করার সময়, সাফারি প্রক্রিয়াটি কখনই ব্যক্তিগত প্রাইভেট কীটি দেখতে পায় না, ওএসের সরবরাহিত অন্তর্নিহিত এসএসএল লাইব্রেরিটি সরাসরি সুরক্ষা ডিমনটির সাথে কথা বলে যা ব্যবহারকারীকে কীচেন থেকে কীটি ব্যবহার করার জন্য অনুরোধ করে। এটি সমস্ত সফ্টওয়্যারটিতে সম্পন্ন হওয়ার পরে, সাইন ইন যদি কোনও পৃথক সত্তাকে (এমনকি সফ্টওয়্যার ভিত্তিক এমনকি) অর্পণ করা হয় যা মেমরিটিকে আরও ভালভাবে আনলোড বা সাফ করতে পারে এই জাতীয় অনুরূপ বিভাজন হতে পারে।
ব্রুনো

@ ব্রুনো: মজাদার ধারণা, একটি অতিরিক্ত ইন্ডিরিশন লেয়ার যা মেমোরিটি সাফ করার জন্য যত্ন নেয় সত্যই এটি স্বচ্ছভাবে সমাধান করবে। সফটওয়্যার কী স্টোরের জন্য একটি পিকেসিএস # 11 র‌্যাপার লিখে ইতিমধ্যে কৌশলটি কি করতে পারে?
এমবুস

51

জন স্কিটি যেমন বলেছে, প্রতিবিম্ব ব্যবহার করা ছাড়া উপায় নেই।

যাইহোক, যদি প্রতিচ্ছবি আপনার জন্য বিকল্প হয় তবে আপনি এটি করতে পারেন।

public static void main(String[] args) {
    System.out.println("please enter a password");
    // don't actually do this, this is an example only.
    Scanner in = new Scanner(System.in);
    String password = in.nextLine();
    usePassword(password);

    clearString(password);

    System.out.println("password: '" + password + "'");
}

private static void usePassword(String password) {

}

private static void clearString(String password) {
    try {
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        char[] chars = (char[]) value.get(password);
        Arrays.fill(chars, '*');
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}

যখন রান

please enter a password
hello world
password: '***********'

দ্রষ্টব্য: স্ট্রিংয়ের চরটি যদি কোনও জিসি চক্রের অংশ হিসাবে অনুলিপি করা হয়, তবে পূর্ববর্তী অনুলিপিটি মেমরির কোথাও থাকার সম্ভাবনা রয়েছে।

এই পুরানো অনুলিপি হিপ ডাম্পে উপস্থিত হবে না, তবে প্রক্রিয়াটির কাঁচা স্মৃতিতে যদি আপনার সরাসরি অ্যাক্সেস থাকে তবে আপনি এটি দেখতে পেতেন। সাধারণভাবে আপনার কারও এ জাতীয় অ্যাক্সেস এড়ানো উচিত।


2
পাসওয়ার্ডের দৈর্ঘ্য যেটি আমরা পেয়েছি সেটি মুদ্রণ প্রতিরোধ করার জন্য আরও কিছু করা ভাল '***********'
chux - মনিকা পুনরায় ইনস্টল করুন

@ chux আপনি একটি শূন্য প্রস্থের অক্ষর ব্যবহার করতে পারেন, যদিও এটি ব্যবহারের চেয়ে আরও বিভ্রান্তিকর হতে পারে। অসুরক্ষিত ব্যবহার না করে চরের অ্যারের দৈর্ঘ্য পরিবর্তন করা সম্ভব নয়। ;)
পিটার লরে

5
জাভা 8 এর স্ট্রিং ডুপ্লিকেশনটির কারণে, আমি মনে করি যে এরকম কিছু করা বেশ ধ্বংসাত্মক হতে পারে ... আপনি আপনার প্রোগ্রামের অন্যান্য স্ট্রিংগুলি সাফ করে শেষ করতে পারেন যে স্ট্রিংয়ে পাসওয়ার্ডের পাসওয়ার্ডের একই মান ছিল। অসম্ভব, তবে সম্ভব ...
জ্যাম্প

1
@ পিটারলাউরে এটি অবশ্যই একটি জেভিএম যুক্তি দিয়ে সক্রিয় করা উচিত, তবে এটি সেখানে রয়েছে। এটি সম্পর্কে এখানে পড়তে পারেন: blog.codecentric.de/en/2014/08/…
জ্যাম্প

1
পাসওয়ার্ডটি এখনও Scannerঅভ্যন্তরীণ বাফারে রয়েছে এবং যেহেতু আপনি System.console().readPassword()কনসোল উইন্ডোটিতে পঠনযোগ্য ফর্ম হিসাবে ব্যবহার করেন নি, এমন একটি উচ্চ সুযোগ রয়েছে । তবে বেশিরভাগ ব্যবহারিক ব্যবহারের ক্ষেত্রে, usePasswordমৃত্যুদন্ড কার্যকর করার সময়কালই আসল সমস্যা। উদাহরণস্বরূপ, অন্য মেশিনের সাথে সংযোগ স্থাপন করার সময় এটি একটি উল্লেখযোগ্য সময় নেয় এবং আক্রমণকারীকে বলে যে গাদা পাসওয়ার্ডটি অনুসন্ধান করার জন্য এটি সঠিক সময়। একমাত্র সমাধান হ'ল আক্রমণকারীদের হিপ মেমরি পড়তে বাধা দেওয়া ...
হোলার

42

এই সব কারণে এক একটি নির্বাচন করা উচিত হয় গৃহস্থালির কাজ [] অ্যারের পরিবর্তে স্ট্রিং পাসওয়ার্ড।

১. যেহেতু স্ট্রিংস জাভাতে অপরিবর্তনীয়, সুতরাং আপনি যদি পাসওয়ার্ডটিকে সরল পাঠ্য হিসাবে সংরক্ষণ করেন তবে আবর্জনা সংগ্রহকারী এটি সাফ না হওয়া পর্যন্ত এটি মেমরিতে উপলব্ধ থাকবে এবং স্ট্রিংটি পুনরায় ব্যবহারযোগ্যতার জন্য স্ট্রিং পুলে ব্যবহার করা হয়েছে বলে এটি বেশ উচ্চ সম্ভাবনা রয়েছে দীর্ঘ সময় ধরে স্মৃতিতে থেকে যান, যা সুরক্ষার জন্য হুমকি হয়ে দাঁড়িয়েছে।

যেহেতু মেমোরি ডাম্পের অ্যাক্সেস রয়েছে এমন যেহেতু পরিষ্কার পাঠ্যে পাসওয়ার্ডটি খুঁজে পেতে পারে, এর অন্য কারণ আপনার সর্বদা সরল পাঠ্যের পরিবর্তে একটি এনক্রিপ্ট করা পাসওয়ার্ড ব্যবহার করা উচিত। যেহেতু স্ট্রিংস অপরিবর্তনীয় তাই স্ট্রিংসের বিষয়বস্তু পরিবর্তন করার কোনও উপায় নেই কারণ যে কোনও পরিবর্তনই নতুন স্ট্রিং তৈরি করবে, আপনি যদি চর ব্যবহার করেন তবে [] আপনি এখনও সমস্ত উপাদানকে ফাঁকা বা শূন্য হিসাবে সেট করতে পারেন। সুতরাং একটি অক্ষরের অ্যারেতে একটি পাসওয়ার্ড সংরক্ষণ করা একটি পাসওয়ার্ড চুরির সুরক্ষা ঝুঁকিকে স্পষ্টভাবে হ্রাস করে।

২. জাভা নিজেই জেপ্যাসওয়ার্ডফিল্ডের গেটপ্যাসওয়ার্ড () পদ্ধতিটি ব্যবহার করার প্রস্তাব দেয় যা অবহিত গেট টেক্সট () পদ্ধতির পরিবর্তে একটি চর [[] ফেরত দেয় যা সুরক্ষার কারণ উল্লেখ করে স্পষ্ট পাঠ্যে পাসওয়ার্ড দেয়। জাভা টিমের পরামর্শ অনুসরণ করা এবং তাদের বিরুদ্ধে যাওয়ার চেয়ে মানদণ্ডগুলি মেনে চলা ভাল।

৩. স্ট্রিং সহ সর্বদা লগ ফাইল বা কনসোলে প্লেইন পাঠ্য মুদ্রণের ঝুঁকি থাকে তবে আপনি যদি একটি অ্যারে ব্যবহার করেন তবে আপনি কোনও অ্যারের সামগ্রীগুলি মুদ্রণ করতে পারবেন না, পরিবর্তে এর মেমরির অবস্থান মুদ্রিত হয়। যদিও আসল কারণ না, তবু এটি বোধগম্য।

String strPassword="Unknown";
char[] charPassword= new char[]{'U','n','k','w','o','n'};
System.out.println("String password: " + strPassword);
System.out.println("Character password: " + charPassword);

String password: Unknown
Character password: [C@110b053

এই ব্লগ থেকে রেফারেন্স । আশা করি এটা কাজে লাগবে.


10
এটি নিরর্থক। এই উত্তরটি উত্তর @SrujanKumarGulla দ্বারা লিখিত একটি সঠিক সংস্করণ stackoverflow.com/a/14060804/1793718 । দয়া করে পেস্ট অনুলিপি বা একই উত্তর দুটি বার নকল করবেন না।
ভাগ্যবান

1. এর মধ্যে পার্থক্য কী?) System.out.println ("চরিত্রের পাসওয়ার্ড:" + চরপ্যাসওয়ার্ড); এবং ২) সিস্টেম.আউট.প্রিন্টলন (চারপ্যাসওয়ার্ড); কারণ এটি আউটপুট হিসাবে একই "অজানা" দিচ্ছে।
বৈভব_সর্মা

3
@ লাকি দুর্ভাগ্যক্রমে আপনি যে পুরানো উত্তরটির সাথে লিঙ্ক করেছেন তা এই উত্তর হিসাবে একই ব্লগ থেকে চুরি করা হয়েছিল এবং এখন মুছে ফেলা হয়েছে। মেটা.স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 389144/ … দেখুন । এই উত্তরটি সেই একই ব্লগ থেকে কেবল কাটা এবং আটকানো হয়েছে এবং কিছুই জুড়েছে না, সুতরাং এটি মূল উত্সের সাথে সংযোগ করার মত একটি মন্তব্য হওয়া উচিত ছিল।
স্কোমিসা

41

সম্পাদনা: এক বছরের সুরক্ষা গবেষণার পরে এই উত্তরে ফিরে আসার পরে, আমি বুঝতে পেরেছি এটি দুর্ভাগ্যজনকভাবে বোঝায় যে আপনি কখনও প্লেইনেক্সট পাসওয়ার্ডের তুলনা করতে পারবেন। দয়া করে না। লবণ এবং যুক্তিসঙ্গত সংখ্যক পুনরাবৃত্তি সহ একটি নিরাপদ একমুখী হ্যাশ ব্যবহার করুন । একটি লাইব্রেরি ব্যবহার বিবেচনা করুন: এই জিনিস সঠিকভাবে পাওয়া শক্ত!

আসল উত্তর: স্ট্রিং.ইকুয়ালস () সংক্ষিপ্ত-সার্কিট মূল্যায়ন ব্যবহার করে এবং তাই সময়সীমার আক্রমণে ঝুঁকির মধ্যে রয়েছে সে সম্পর্কে কী বলা যায় ? এটি অসম্ভব হতে পারে তবে আপনি অক্ষরগুলির সঠিক ক্রম নির্ধারণ করার জন্য তাত্ত্বিকভাবে পাসওয়ার্ডের তুলনায় সময় দিতে পারেন।

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        // Quits here if Strings are different lengths.
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            // Quits here at first different character.
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

সময় আক্রমণের উপর আরও কিছু সংস্থান:


তবে এটি চরের [] তুলনাতেও থাকতে পারে, কোথাও আমরা পাসওয়ার্ডের বৈধতাতেও একই কাজ করব। তাহলে চরটি কীভাবে স্ট্রিংয়ের চেয়ে ভাল?
মোহিত কানওয়ার

3
আপনি একেবারে সঠিক, ভুলটি যে কোনও উপায়ে করা যেতে পারে। স্ট্রিং-ভিত্তিক বা চর [] - ভিত্তিক পাসওয়ার্ডগুলির জন্য জাভাতে সুস্পষ্ট পাসওয়ার্ড-তুলনা পদ্ধতি নেই বলে বিবেচনা করে এখানে সমস্যাটি সম্পর্কে জানা সবচেয়ে গুরুত্বপূর্ণ বিষয়। আমি বলব স্ট্রিংসের জন্য তুলনা () ব্যবহার করার প্রলোভনটি চর [] নিয়ে যাওয়ার ভাল কারণ] এইভাবে তুলনা কীভাবে করা যায় তার উপর আপনার অন্তত নিয়ন্ত্রণ থাকে (স্ট্রিংকে প্রসারিত না করে, যা ব্যথার ইমো)।
গ্রাফ থিওরি

এছাড়া প্লেইন পাসওয়ার্ড তুলনা ডান জিনিস যাহাই হউক না কেন নয়, লোভ ব্যবহার করতে Arrays.equalsজন্য char[]জন্য হিসাবে উচ্চ হিসাবে String.equals। কেউ যদি চিন্তা, একটি ডেডিকেটেড কী বর্গ প্রকৃত পাসওয়ার্ড encapsulating এবং তদারক বিষয়-ওহ অপেক্ষা করুন, বাস্তব নিরাপত্তা প্যাকেজ ছিল আছে ডেডিকেটেড কী ক্লাস, এই Q & A- শুধুমাত্র একটি সম্পর্কে অভ্যাস তাদের বাইরে, বলতে, যেমন JPasswordFieldব্যবহার করার জন্য, char[]পরিবর্তে String(যেখানে প্রকৃত অ্যালগরিদমগুলি byte[]যাইহোক ব্যবহার করে )।
হলগার

সুরক্ষা সম্পর্কিত সফ্টওয়্যার sleep(secureRandom.nextInt())যেভাবেই কোনও লগইন প্রচেষ্টা প্রত্যাখ্যান করার আগে এমন কিছু করা উচিত যা কেবলমাত্র সময় সময় আক্রমণ করার সম্ভাবনা সরিয়ে দেয় না, এটি পাল্টা জোর প্রচেষ্টা চালিয়ে যায় makes
হলগার

36

ব্যবহারের পরে আপনি ম্যানুয়ালি পরিষ্কার না করে চরের অ্যারে আপনাকে বনাম স্ট্রিং দেয় এমন কিছুই নেই এবং আমি আসলে কাউকে এটি করতে দেখিনি। সুতরাং আমার কাছে চর [] বনাম স্ট্রিংয়ের পছন্দটি কিছুটা অতিরঞ্জিত।

কটাক্ষপাত ব্যাপকভাবে ব্যবহৃত স্প্রিং সিকিউরিটি গ্রন্থাগার এখানে এবং নিজেকে জিজ্ঞাসা - স্প্রিং সিকিউরিটি বলছি অযোগ্য বা গৃহস্থালির কাজ হয় [] পাসওয়ার্ড শুধু অনেক মানে হয় না। যখন কোনও বাজে হ্যাকার আপনার র‌্যামের মেমরি ডাম্পগুলিকে ধরবে তখন নিশ্চিত হয়ে নিন যে সেগুলি গোপন করার জন্য অত্যাধুনিক উপায়গুলি ব্যবহার করলেও তিনি সমস্ত পাসওয়ার্ড পেয়ে যাবেন।

তবে জাভা সর্বদা পরিবর্তিত হয় এবং জাভা 8 এর স্ট্রিং ডুপ্লোকেশন ফিচারের মতো কিছু ভীতিজনক বৈশিষ্ট্য আপনার অজান্তেই স্ট্রিং অবজেক্টগুলিকে ইন্টার্ন করতে পারে। তবে এটি একটি আলাদা কথোপকথন।


স্ট্রিং-ডুপ্লিকেশন ভীতিজনক কেন? এটি কেবল তখনই প্রযোজ্য যখন কমপক্ষে দুটি স্ট্রিং একই বিষয়বস্তুযুক্ত থাকে, সুতরাং এই দুটি ইতিমধ্যে অভিন্ন স্ট্রিং একই অ্যারে ভাগ করে দেওয়া থেকে কী বিপদ দেখা দিতে পারে? বা অন্য উপায়ে রাউন্ডটি জিজ্ঞাসা করতে দেয়: যদি কোনও স্ট্রিং-অনুদান না থাকে তবে উভয় স্ট্রিংয়ের পৃথক অ্যারে রয়েছে (একই বিষয়বস্তুগুলির) থেকে কী লাভ হবে? উভয় ক্ষেত্রেই contents বিষয়বস্তুর সর্বাধিক দীর্ঘস্থায়ী স্ট্রিং বেঁচে থাকা
হোলার

@ আপনার নিয়ন্ত্রণের বাইরে থাকা যে কোনও কিছুই হ'ল সম্ভাব্য ঝুঁকি ... উদাহরণস্বরূপ যদি দু'জন ব্যবহারকারীর একই পাসওয়ার্ড থাকে তবে এই চমত্কার বৈশিষ্ট্যটি উভয়কে একক চরে সংরক্ষণ করবে [] এটি স্পষ্ট করে দেয় যে তারা একই, নিশ্চিত কিনা তা একটি বিশাল ঝুঁকি কিন্তু এখনও
ওলেগ মিখিভ

আপনার যদি হিপ মেমরির এবং উভয় স্ট্রিংয়ের উদাহরণগুলিতে অ্যাক্সেস থাকে তবে স্ট্রিংগুলি একই অ্যারে বা একই সামগ্রীর দুটি অ্যারেতে নির্দেশ করে কিনা তা বিচার্য নয়, প্রতিটি খুঁজে পাওয়া সহজ to বিশেষত এটি যেভাবেই অপ্রাসঙ্গিক। আপনি যদি এই মুহুর্তে থাকেন তবে আপনি উভয় পাসওয়ার্ড হ'ল, অভিন্ন কিনা। আসল ত্রুটিটি সল্ট হ্যাশগুলির পরিবর্তে প্লেইন টেক্সট পাসওয়ার্ডগুলি ব্যবহার করে।
হোলার

@ পাসওয়ার্ড যাচাই করার জন্য এটি কিছুক্ষণ 10 মিনিটের জন্য মেমরির স্পষ্ট পাঠ্যে থাকতে হবে, এমনকি এটি থেকে সল্ট হ্যাশ তৈরির জন্য হলেও। তারপরে, যদি এটি ঘটে থাকে যে এমনকি 10 এমএসের জন্য মেমরিতে দুটি অভিন্ন পাসওয়ার্ড রাখা আছে, তবে অনুদান খেলতে আসতে পারে। যদি এটি সত্যিই স্ট্রিংগুলি ইন্টার্ন করে তবে এগুলিকে দীর্ঘ সময়ের জন্য স্মৃতিতে রাখা হয়। কয়েক মাস ধরে রিস্টার্ট না হওয়া সিস্টেম এগুলি প্রচুর সংগ্রহ করবে। শুধু তাত্ত্বিক।
ওলেগ মিখিভ

দেখে মনে হচ্ছে, আপনার স্ট্রিং ডুপ্লিকেশন সম্পর্কে মৌলিক ভুল ধারণা রয়েছে। এটি "ইন্টার্ন স্ট্রিংগুলি" করে না, এটি একইভাবে একই স্ট্রিংগুলিকে একই অ্যারেতে নির্দেশ করে যা প্লেইনেক্সট পাসওয়ার্ড সহ অ্যারে উদাহরণগুলির সংখ্যা হ্রাস করে, কারণ একটি অ্যারের উদাহরণ ছাড়াও সমস্ত পুনরুদ্ধার ও ওভাররাইট করা যায় অন্যান্য অবজেক্টের সাথে সাথেই। এই স্ট্রিংগুলি এখনও অন্য স্ট্রিংয়ের মতো সংগ্রহ করা হয়। সম্ভবত এটি সাহায্য করে, যদি আপনি বুঝতে পারেন যে ডি-ডুপ্লিকেশনটি কেবল আবর্জনা সংগ্রহকারী দ্বারা করা হয়েছে, কেবলমাত্র একাধিক জিসি চক্র থেকে বেঁচে থাকা স্ট্রিংগুলির জন্য।
হলগার

30

স্ট্রিংগুলি পরিবর্তনযোগ্য এবং একবার তৈরি হয়ে গেলে সেগুলি পরিবর্তন করা যায় না। স্ট্রিং হিসাবে একটি পাসওয়ার্ড তৈরি করা হিপ বা স্ট্রিং পুলের পাসওয়ার্ডের দিকে বিপথগামী রেফারেন্স ছেড়ে যাবে। এখন যদি কেউ জাভা প্রক্রিয়াটির হিপ ডাম্প নেয় এবং সাবধানতার সাথে স্ক্যান করে সে পাসওয়ার্ডগুলি অনুমান করতে সক্ষম হতে পারে। অবশ্যই এই অ-ব্যবহৃত স্ট্রিংগুলি আবর্জনা সংগ্রহ করা হবে তবে এটি কখন নির্ভর করে জিসি লাথি দেয় on

অন্যদিকে চর [] প্রবর্তনযোগ্য প্রমাণীকরণের সাথে সাথেই আপনি এগুলি সমস্ত এম এর বা ব্যাকস্ল্যাশগুলির মতো কোনও অক্ষর দিয়ে ওভাররাইট করতে পারেন। এখন এমনকি কেউ যদি হ্যাপ ডাম্প নেয় তবে তিনি বর্তমানে ব্যবহার করা হয়নি এমন পাসওয়ার্ডগুলি পেতে সক্ষম হতে পারবেন না। এটি আপনাকে জিসির অপেক্ষায় বনাম অবজেক্ট সামগ্রীটি সাফ করার মতো অর্থে আরও নিয়ন্ত্রণ দেয়।


তারা কেবলমাত্র GC'd হবে যদি প্রশ্নে থাকা JVM> 1.6 হয়। 1.7 এর আগে, সমস্ত স্ট্রিং পার্জেজেনে সংরক্ষণ করা হয়েছিল।
avgvstvs

@avgvstvs: "সমস্ত স্ট্রিং পার্জেজেনে সংরক্ষণ করা হয়েছিল" ঠিক মৃত ভুল। কেবলমাত্র ইন্টার্নযুক্ত স্ট্রিংগুলি সেখানে সংরক্ষণ করা হয়েছিল এবং যদি তারা কোড অনুসারে স্ট্রিং লিটারেলগুলি থেকে উত্স না পেয়ে থাকে তবে তারা এখনও আবর্জনা সংগ্রহ করেছিল। এটা আমার মনে হয়. যদি স্ট্রিংগুলি সাধারণত 1.7 এর আগে জেভিএমগুলিতে কখনও জিসিড না হয়, তবে কোনও জাভা অ্যাপ্লিকেশন কয়েক মিনিটের বেশি বেঁচে থাকতে পারে কীভাবে?
হলগার

@ হোলজার এটি মিথ্যা। অভ্যন্তরীণ stringsএবং Stringপুল (পূর্বে ব্যবহৃত স্ট্রিংগুলির পুল) দুটি 1.7 এর আগে পার্মজেনে সংরক্ষণ করা হয়েছিল। এছাড়াও, বিভাগ 5.1 দেখুন: docs.oracle.com/javase/specs/jvms/se6/html/… জেভিএম সর্বদা Stringsতারা একই রেফারেন্স মান কিনা তা পরীক্ষা করে দেখেছিল এবং আপনার String.intern()জন্য ফোন করবে । ফলাফলটি ছিল যে প্রতিবার JVM এর অভিন্ন স্ট্রিংগুলি সনাক্ত করেছিল constant_poolবা এটি হিপ এটি তাদের পার্জেঞ্জে স্থানান্তরিত করবে। এবং আমি "ক্রাইপিং পার্জেন" দিয়ে 1.7 পর্যন্ত একাধিক অ্যাপ্লিকেশনগুলিতে কাজ করেছি। এটি একটি বাস্তব সমস্যা ছিল।
avgvstvs

সুতরাং পুনরুদ্ধার করার জন্য: 1.7 অবধি স্ট্রিংগুলি গাদা থেকে শুরু হয়েছিল, যখন তারা ব্যবহার করা হত তখন constant_poolসেগুলিতে প্রবেশ করানো হত যা পার্মেজ অবস্থিত ছিল এবং তারপরে যদি কোনও স্ট্রিং একাধিকবার ব্যবহৃত হয় তবে এটি অভ্যন্তরীণ হবে।
avgvstvs

@avgvstvs: এখানে "আগে ব্যবহৃত স্ট্রিংগুলির পুল" নেই। আপনি সম্পূর্ণ ভিন্ন জিনিস একসাথে নিক্ষেপ করছেন। এখানে একটি রানটাইম স্ট্রিং পুল রয়েছে যা স্ট্রিং আক্ষরিক এবং স্পষ্টতই ইন্টার্নযুক্ত স্ট্রিং রয়েছে তবে অন্য কোনও নয়। এবং প্রতিটি শ্রেণীর সংকলন-সময় ধ্রুবক সমন্বিত এর ধ্রুব পুল রয়েছে । এই স্ট্রিংগুলি রানটাইম পুলে স্বয়ংক্রিয়ভাবে যুক্ত হয় তবে কেবল প্রতিটি স্ট্রিং নয়।
হলগার

21

স্ট্রিং পরিবর্তনযোগ্য এবং এটি স্ট্রিং পুলে যায় to একবার লেখা হয়ে গেলে এটি ওভাররাইট করা যায় না।

char[] একবারে পাসওয়ার্ড ব্যবহার করার পরে আপনার ওভাররাইট করা উচিত এমন একটি অ্যারে এবং এটি এটি করা উচিত:

char[] passw = request.getPassword().toCharArray()
if (comparePasswords(dbPassword, passw) {
 allowUser = true;
 cleanPassword(passw);
 cleanPassword(dbPassword);
 passw=null;
}

private static void cleanPassword (char[] pass) {

Arrays.fill(pass, '0');
}

আক্রমণকারী এটির ব্যবহার করতে পারে এমন একটি দৃশ্য ক্র্যাশডাম্প - যখন জেভিএম ক্র্যাশ হয়ে মেমরির ডাম্প তৈরি করে - আপনি পাসওয়ার্ডটি দেখতে সক্ষম হবেন।

এটি অগত্যা কোনও দূষিত বাহ্যিক আক্রমণকারী নয়। এটি এমন কোনও সমর্থনকারী ব্যবহারকারী হতে পারে যা পর্যবেক্ষণের উদ্দেশ্যে সার্ভারে অ্যাক্সেস পায়। তিনি ক্রাশডাম্পে উঁকি মারতে এবং পাসওয়ার্ডগুলি খুঁজে পেতে পারতেন।


2
ch = নাল; আপনি এটি করতে পারবেন না
যুজার্টেন

কিন্তু request.getPassword()ইতিমধ্যে স্ট্রিংটি তৈরি করে তা পুলটিতে যুক্ত করে না ?
Tvde1

1
ch = '0'স্থানীয় পরিবর্তনশীল পরিবর্তন ch; অ্যারেতে এর কোনও প্রভাব নেই। এবং আপনার উদাহরণটি যাইহোক, অর্থহীন, আপনি যে স্ট্রিং উদাহরণটি দিয়েছিলেন তা দিয়ে শুরু toCharArray()করুন, একটি নতুন অ্যারে তৈরি করে এবং নতুন অ্যারেটি সঠিকভাবে ওভাররাইট করার পরেও এটি স্ট্রিং উদাহরণটি পরিবর্তন করে না, সুতরাং কেবল স্ট্রিংটি ব্যবহার করে এর কোনও সুবিধা নেই দৃষ্টান্ত.
হলগার

@ বৃহত্তর ধন্যবাদ চর অ্যারে ক্লিনআপ কোডটি সংশোধন করে।
এসিভি

3
আপনি সহজভাবে ব্যবহার করতে পারেনArrays.fill(pass, '0');
হোলার

18

সংক্ষিপ্ত এবং সরল উত্তর char[]হ'ল কারণ Stringবস্তুগুলি না থাকায় পরিবর্তনযোগ্য ।

Stringsজাভাতে অপরিবর্তনীয় বস্তু। এ কারণেই একবার এগুলি তৈরি করার পরে তাদের সংশোধন করা যাবে না এবং তাই তাদের সামগ্রীগুলি মেমরি থেকে সরিয়ে ফেলার একমাত্র উপায় হ'ল তাদের আবর্জনা সংগ্রহ করা। এটি তখনই যখন অবজেক্টের দ্বারা মুক্ত মেমরির ওভাররাইট করা যাবে এবং ডেটা চলে যাবে।

এখন জাভাতে আবর্জনা সংগ্রহ কোনও গ্যারান্টিযুক্ত বিরতিতে ঘটে না। Stringএইভাবে একটি দীর্ঘ সময়ের জন্য মেমরির মধ্যে জিদ করতে পারেন, এবং যদি একটি প্রক্রিয়া এই সময় ক্র্যাশ, স্ট্রিং এর বিষয়বস্তু একটি মেমরি ডাম্প অথবা কিছু লগ আপ শেষ হতে পারে।

একটি অক্ষরের অ্যারে দিয়ে , আপনি পাসওয়ার্ডটি পড়তে পারেন, যত তাড়াতাড়ি সম্ভব এটির সাথে কাজ শেষ করতে পারেন এবং তারপরে অবিলম্বে সামগ্রীগুলি পরিবর্তন করতে পারেন change


পছন্দ করুন সাবধানে পড়ুন এবং আপনি পার্থক্য খুঁজে পাবেন।
প্রীতম ব্যানার্জি

12

জাভা স্ট্রিং অপরিবর্তনীয়। সুতরাং যখনই কোনও স্ট্রিং তৈরি হবে, এটি আবর্জনা সংগ্রহ না করা অবধি স্মৃতিতে থাকবে। সুতরাং যে যার কাছে মেমোরিতে অ্যাক্সেস রয়েছে তারা স্ট্রিংয়ের মানটি পড়তে পারেন।
যদি স্ট্রিংয়ের মান সংশোধন করা হয় তবে এটি একটি নতুন স্ট্রিং তৈরি করে শেষ করবে। সুতরাং মূল মান এবং পরিবর্তিত মান উভয়ই ময়লা আবর্জনা সংগ্রহ না করা অবধি মেমরিতে থাকে।

অক্ষর অ্যারের সাথে, পাসওয়ার্ডের উদ্দেশ্যটি পরিবেশন করা হলে অ্যারের সামগ্রীগুলি পরিবর্তন বা মোছা যায়। অ্যারের মূল বিষয়বস্তু মেমরি পাওয়া যাবে না পরে এটি রুপান্তরিত করা হয়েছে এবং এমনকি সামনে আবর্জনা সংগ্রহ কিক।

নিরাপত্তা উদ্বেগ এটি একটি অক্ষর অ্যারে হিসাবে দোকান পাসওয়ার্ড করাই ভালো কারণ।


2

এই উদ্দেশ্যে আপনার স্ট্রিং ব্যবহার করা উচিত বা চর [] ব্যবহার করা উচিত কিনা তা নিয়ে বিতর্কযোগ্য কারণ উভয়েরই সুবিধা এবং অসুবিধা রয়েছে। এটি নির্ভর করে ব্যবহারকারী কী প্রয়োজন।

যেহেতু জাভাতে স্ট্রিংগুলি পরিবর্তনযোগ্য নয়, যখনই কেউ আপনার স্ট্রিংয়ে হেরফের করার চেষ্টা করে এটি একটি নতুন অবজেক্ট তৈরি করে এবং বিদ্যমান স্ট্রিংগুলি ক্ষতিগ্রস্থ থেকে যায়। স্ট্রিং হিসাবে একটি পাসওয়ার্ড সংরক্ষণ করার জন্য এটি একটি সুবিধা হিসাবে দেখা যেতে পারে, তবে অবজেক্টটি ব্যবহারের পরেও স্মৃতিতে থেকে যায়। সুতরাং কেউ যদি কোনওভাবে অবজেক্টটির মেমরি অবস্থান পেয়ে থাকে তবে that ব্যক্তি সেই জায়গায় আপনার পাসওয়ার্ডটি সহজেই সন্ধান করতে পারে।

চর [] পরিবর্তনীয়, তবে এর সুবিধা রয়েছে যে এর ব্যবহারের পরে প্রোগ্রামার স্পষ্ট করে অ্যারে বা ওভাররাইড মানগুলি পরিষ্কার করতে পারে। সুতরাং এটি ব্যবহার করা হয়ে গেলে এটি পরিষ্কার হয়ে যায় এবং আপনার সঞ্চিত তথ্য সম্পর্কে কেউ জানতে পারেনি ever

উপরের অবস্থার উপর ভিত্তি করে, কেউ স্ট্রিংয়ের সাথে যেতে হবে বা তাদের প্রয়োজনীয়তার জন্য চরের সাথে যেতে হবে কিনা সে সম্পর্কে ধারণা পেতে পারে।


0

কেস স্ট্রিং:

    String password = "ill stay in StringPool after Death !!!";
    // some long code goes
    // ...Now I want to remove traces of password
    password = null;
    password = "";
    // above attempts wil change value of password
    // but the actual password can be traced from String pool through memory dump, if not garbage collected

কেস চার এয়ার:

    char[] passArray = {'p','a','s','s','w','o','r','d'};
    // some long code goes
    // ...Now I want to remove traces of password
    for (int i=0; i<passArray.length;i++){
        passArray[i] = 'x';
    }
    // Now you ACTUALLY DESTROYED traces of password form memory
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.