অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে ব্যবহারকারী সেটিংস সঞ্চয় করার সবচেয়ে উপযুক্ত উপায় কী What


308

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

আমি এটি ভাগ করে নেওয়া পছন্দগুলি দিয়ে করার চেষ্টা করছিলাম তবে এটি সেরা সমাধান কিনা তা নিশ্চিত নই।

অ্যান্ড্রয়েড অ্যাপ্লিকেশনটিতে কীভাবে ব্যবহারকারীর মান / সেটিংস সঞ্চয় করতে হয় সে সম্পর্কে আমি যে কোনও পরামর্শের প্রশংসা করব।

উত্তর:


233

সাধারনত SharedPreferences আপনার পছন্দ সংরক্ষণ করার জন্য সেরা বাজি, তাই সাধারণভাবে আমি অ্যাপ্লিকেশন এবং ব্যবহারকারীর সেটিংস সংরক্ষণের জন্য সেই পদ্ধতির প্রস্তাব দিই।

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

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


3
আপনি দয়া করে স্যান্ডবক্সযুক্ত বলতে কী বোঝাতে পারেন?
অভিজিৎ

14
একটি স্যান্ডবক্সযুক্ত প্রোগ্রাম এমন কোনও অ্যাপ্লিকেশন যার প্রক্রিয়া এবং তথ্য (যেমন ভাগ করা পছন্দগুলি) বাকি অ্যাপ্লিকেশনগুলি থেকে গোপন থাকে। একটি প্যাকেজে চলমান একটি অ্যান্ড্রয়েড অ্যাপ্লিকেশন অন্য প্যাকেজের অভ্যন্তরের যে কোনও কিছুতে সরাসরি অ্যাক্সেস করতে পারে না। এজন্য একই প্যাকেজের অ্যাপ্লিকেশনগুলি (যা সর্বদা আপনার থাকে)
অন্যগুলি

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

1
প্রতি android-developers.blogspot.com/2013/02/... , ব্যবহারকারী প্রমাণপত্রাদি MODE_PRIVATE পতাকা সেট দিয়ে সংরক্ষিত হয় এবং অভ্যন্তরীণ সঞ্চয় সংরক্ষণ করা উচিত (স্থানীয়ভাবে পরিণামে আক্রমণ খোলা পাসওয়ার্ডের কোন ধরণের সংরক্ষণকারী সম্পর্কে একই আদেশ সহকারে সহ)। এটি বলেছে, MODE_PRIVATEস্থানীয়ভাবে সঞ্চিত ডেটা অপ্রত্যাশিত করার জন্য কার্যকারিতা হিসাবে, অভ্যন্তরীণ স্টোরেজটিতে তৈরি করা কোনও ফাইলের সাথে একই কাজ করার সমতুল্য শেয়ার্ডপ্রিফারেন্সিসহ কী ব্যবহার করা হচ্ছে?
কিউস

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

211

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

যাইহোক, এটি বলা হচ্ছে, এমন একটি প্রচারমূলক উদ্যোগ এমন মোবাইল অ্যাপ্লিকেশনগুলি সনাক্ত করতে চলছে যা তাদের পাসওয়ার্ডগুলি শেরেডপ্রেরিফারেন্সে স্বচ্ছ টেক্সটে সংরক্ষণ করে এবং সেই অ্যাপ্লিকেশনগুলিতে প্রতিকূল আলোকিত করে তোলে। কিছু উদাহরণের জন্য http://blogs.wsj.com/digits/2011/06/08/some-top-apps-put-data-at-risk/ এবং http://viaforensics.com/appwatchdog দেখুন ।

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

কেবল এটির মধ্যে আপনার নিজের ভাগ করা পছন্দসই বিষয়টিকে আবদ্ধ করুন এবং আপনার পড়া / লেখার যে কোনও ডেটা স্বয়ংক্রিয়ভাবে এনক্রিপ্ট হবে এবং ডিক্রিপ্ট হবে। যেমন।

final SharedPreferences prefs = new ObscuredSharedPreferences( 
    this, this.getSharedPreferences(MY_PREFS_FILE_NAME, Context.MODE_PRIVATE) );

// eg.    
prefs.edit().putString("foo","bar").commit();
prefs.getString("foo", null);

ক্লাসের কোড এখানে:

/**
 * Warning, this gives a false sense of security.  If an attacker has enough access to
 * acquire your password store, then he almost certainly has enough access to acquire your
 * source binary and figure out your encryption key.  However, it will prevent casual
 * investigators from acquiring passwords, and thereby may prevent undesired negative
 * publicity.
 */
public class ObscuredSharedPreferences implements SharedPreferences {
    protected static final String UTF8 = "utf-8";
    private static final char[] SEKRIT = ... ; // INSERT A RANDOM PASSWORD HERE.
                                               // Don't use anything you wouldn't want to
                                               // get out there if someone decompiled
                                               // your app.


    protected SharedPreferences delegate;
    protected Context context;

    public ObscuredSharedPreferences(Context context, SharedPreferences delegate) {
        this.delegate = delegate;
        this.context = context;
    }

    public class Editor implements SharedPreferences.Editor {
        protected SharedPreferences.Editor delegate;

        public Editor() {
            this.delegate = ObscuredSharedPreferences.this.delegate.edit();                    
        }

        @Override
        public Editor putBoolean(String key, boolean value) {
            delegate.putString(key, encrypt(Boolean.toString(value)));
            return this;
        }

        @Override
        public Editor putFloat(String key, float value) {
            delegate.putString(key, encrypt(Float.toString(value)));
            return this;
        }

        @Override
        public Editor putInt(String key, int value) {
            delegate.putString(key, encrypt(Integer.toString(value)));
            return this;
        }

        @Override
        public Editor putLong(String key, long value) {
            delegate.putString(key, encrypt(Long.toString(value)));
            return this;
        }

        @Override
        public Editor putString(String key, String value) {
            delegate.putString(key, encrypt(value));
            return this;
        }

        @Override
        public void apply() {
            delegate.apply();
        }

        @Override
        public Editor clear() {
            delegate.clear();
            return this;
        }

        @Override
        public boolean commit() {
            return delegate.commit();
        }

        @Override
        public Editor remove(String s) {
            delegate.remove(s);
            return this;
        }
    }

    public Editor edit() {
        return new Editor();
    }


    @Override
    public Map<String, ?> getAll() {
        throw new UnsupportedOperationException(); // left as an exercise to the reader
    }

    @Override
    public boolean getBoolean(String key, boolean defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Boolean.parseBoolean(decrypt(v)) : defValue;
    }

    @Override
    public float getFloat(String key, float defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Float.parseFloat(decrypt(v)) : defValue;
    }

    @Override
    public int getInt(String key, int defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Integer.parseInt(decrypt(v)) : defValue;
    }

    @Override
    public long getLong(String key, long defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Long.parseLong(decrypt(v)) : defValue;
    }

    @Override
    public String getString(String key, String defValue) {
        final String v = delegate.getString(key, null);
        return v != null ? decrypt(v) : defValue;
    }

    @Override
    public boolean contains(String s) {
        return delegate.contains(s);
    }

    @Override
    public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
        delegate.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }

    @Override
    public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
        delegate.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }




    protected String encrypt( String value ) {

        try {
            final byte[] bytes = value!=null ? value.getBytes(UTF8) : new byte[0];
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));
            return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP),UTF8);

        } catch( Exception e ) {
            throw new RuntimeException(e);
        }

    }

    protected String decrypt(String value){
        try {
            final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0];
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));
            return new String(pbeCipher.doFinal(bytes),UTF8);

        } catch( Exception e) {
            throw new RuntimeException(e);
        }
    }

}

3
এফওয়াইআই বেস64 এপিআই স্তরের 8 (2.2) এবং তার পরে পাওয়া যায়। আপনি পূর্ববর্তী ওএসগুলির জন্য iharder.sourceforge.net/current/java/base64 বা অন্য কিছু ব্যবহার করতে পারেন ।
emmby

34
হ্যাঁ, আমি এটি লিখেছি। বিনা দ্বিধায় ব্যবহার করুন, কোনও অ্যাট্রিবিউশনের প্রয়োজন নেই
emmby

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

4
আমি এই কোডটিতে কয়েকটি বৈশিষ্ট্য যুক্ত করেছি এবং এটি github.com/RightHandedMonkey/WorxForUs_Library/blob/master/src/…গিথুবে রেখেছি । এটি এখন একটি এনক্রিপ্ট করা পছন্দগুলি এনক্রিপ্ট করাতে স্থানান্তরিত করে rating এছাড়াও এটি রানটাইমের সময় কী উত্পন্ন করে, তাই অ্যাপ্লিকেশনটি ডিকম্পলিং কীটি প্রকাশ করে না।
রাইটহ্যান্ডডমনকি

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

29

অ্যান্ড্রয়েড ক্রিয়াকলাপে কোনও একক পছন্দ সংরক্ষণ করার সহজ উপায় সম্পর্কে এই জাতীয় কিছু করা:

Editor e = this.getPreferences(Context.MODE_PRIVATE).edit();
e.putString("password", mPassword);
e.commit();

আপনি যদি এইগুলির সুরক্ষা সম্পর্কে উদ্বিগ্ন হন তবে আপনি সর্বদা পাসওয়ার্ডটি সংরক্ষণের আগে এনক্রিপ্ট করতে পারবেন।


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

1
পাসওয়ার্ডটি সংরক্ষণ করা কীটি আপনি কোথায় সংরক্ষণ করবেন? যদি ভাগ করা পছন্দগুলি অন্যান্য ব্যবহারকারীদের দ্বারা অ্যাক্সেসযোগ্য হয় তবে এটি কী।
অরহানসি 1

@ অরহানসি 1 আপনি উত্তর পেয়েছেন??
eRaisedToX

10

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

আমি এটি পূর্বে একটি "লুকানো" পছন্দ যুক্ত করার পরামর্শ দিয়েছিলাম। এটি অবশ্যই সেরা উপায় নয়। আমি আরও দুটি বিকল্প উপস্থাপন করতে যাচ্ছি যা আমি আরও কার্যকর হিসাবে বিবেচনা করি।

প্রথমটি, সর্বাধিক সরল, অগ্রাধিকারের চেঞ্জলাইস্টেনারে রয়েছে, আপনি প্রবেশ করা মানটি ধরে ফেলতে পারেন, এটি এনক্রিপ্ট করতে পারেন এবং তারপরে বিকল্প বিকল্প ফাইলটিতে সংরক্ষণ করতে পারেন:

  public boolean onPreferenceChange(Preference preference, Object newValue) {
      // get our "secure" shared preferences file.
      SharedPreferences secure = context.getSharedPreferences(
         "SECURE",
         Context.MODE_PRIVATE
      );
      String encryptedText = null;
      // encrypt and set the preference.
      try {
         encryptedText = SimpleCrypto.encrypt(Preferences.SEED,(String)newValue);

         Editor editor = secure.getEditor();
         editor.putString("encryptedPassword",encryptedText);
         editor.commit();
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      // always return false.
      return false; 
   }

দ্বিতীয় উপায় এবং আমি এখন যেভাবে পছন্দ করি তা হ'ল আপনার নিজস্ব কাস্টম পছন্দ তৈরি করা, সম্পাদনাপ্রবন্ধকে প্রসারিত করা, @ পদ্ধতি setText()এবং getText()পদ্ধতিগুলিকে ওভাররাইড করা , যাতে setText()পাসওয়ার্ডটি এনক্রিপ্ট হয় এবং getText()শূন্য ফিরে আসে।


আমি জানি এটি বেশ পুরানো, তবে আপনার নিজের সম্পাদনা পাঠ্য পছন্দসই সংস্করণের জন্য আপনার কোড পোস্ট করতে আপত্তি হবে?
রেনিপেট

কিছু মনে করবেন না, আমি এখানে একটি কার্যকর ব্যবহারযোগ্য নমুনা পেয়েছি এখানে. google.google.com/forum/#!topic/android-developers/pMYNEVXMa6M এবং আমি এখন এটি কাজ করে চলেছি। এই পদ্ধতির পরামর্শ দেওয়ার জন্য ধন্যবাদ।
রেনিপেট

6

ঠিক আছে; উত্তরটি মিশ্রিত হওয়ার পরে এটি বেশ কিছুক্ষণ হয়েছে, তবে কয়েকটি সাধারণ উত্তর এখানে। আমি এটি পাগলের মতো গবেষণা করেছি এবং ভাল উত্তর তৈরি করা শক্ত ছিল

  1. আপনি যদি ধরে নেন যে ব্যবহারকারী ডিভাইসটি রুট করেনি, তবে MODE_PRIVATE পদ্ধতিটি সাধারণত নিরাপদ হিসাবে বিবেচিত হয়। আপনার ডেটা ফাইল সিস্টেমের এমন একটি অংশে সরল পাঠ্যে সঞ্চিত আছে যা কেবলমাত্র মূল প্রোগ্রাম দ্বারা অ্যাক্সেস করা যায়। এটি রুট ডিভাইসে সহজেই অন্য অ্যাপের সাহায্যে পাসওয়ার্ড হ'ল। তারপরে আবার, আপনি কি রুটযুক্ত ডিভাইসগুলি সমর্থন করতে চান?

  2. AES টি এখনও আপনার পক্ষে করা সেরা এনক্রিপশন। আপনি যদি একটি নতুন বাস্তবায়ন শুরু করছেন তবে এটি পোস্ট করার কিছুক্ষণ পরে যদি এটি দেখতে মনে রাখবেন। এর সাথে সবচেয়ে বড় সমস্যাটি হ'ল "এনক্রিপশন কী দিয়ে কী করব?"

সুতরাং, এখন আমরা "কী দিয়ে কী করব?" অংশ। এটি কঠিন অংশ। চাবিটি পাওয়া খুব খারাপ নয়। আপনি কিছু পাসওয়ার্ড নিতে এবং এটি একটি সুরক্ষিত কী তৈরি করতে একটি কী ডেরাইভেশন ফাংশন ব্যবহার করতে পারেন। আপনি "পিকেএফডিএফ 2 দিয়ে কতগুলি পাস করেন?" এর মতো সমস্যায় পড়েছেন, তবে এটি অন্য একটি বিষয়

  1. আদর্শভাবে, আপনি ডিভাইসটিতে এএস কী সংরক্ষণ করেন। আপনাকে সার্ভার থেকে কীটি নিরাপদে, নির্ভরযোগ্যভাবে এবং সুরক্ষিতভাবে পুনরুদ্ধার করার জন্য একটি ভাল উপায় বের করতে হবে

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

আপনি যখন লগ ইন করেন, আপনি স্থানীয় লগইন-এ কীটি পুনরায় প্রাপ্ত করে এবং সঞ্চিত কীটির সাথে তুলনা করুন। এটি হয়ে গেলে আপনি AES এর জন্য ডেরিভ কী # 2 ব্যবহার করেন।

  1. "সাধারণভাবে নিরাপদ" পদ্ধতির ব্যবহার করে আপনি AES ব্যবহার করে ডেটা এনক্রিপ্ট করেন এবং কীটি MODE_PRIVATE এ সঞ্চয় করেন। এটি সাম্প্রতিক-ইশ অ্যান্ড্রয়েড ব্লগ পোস্ট দ্বারা প্রস্তাবিত। অবিশ্বাস্যরূপে সুরক্ষিত নয়, তবে কিছু লোকের পক্ষে সরল পাঠ্যের চেয়ে আরও ভাল উপায়

আপনি এগুলির বিভিন্ন প্রকারের পরিবর্তন করতে পারেন। উদাহরণস্বরূপ, সম্পূর্ণ লগইন ক্রমের পরিবর্তে আপনি একটি দ্রুত পিন করতে পারেন (প্রাপ্ত)। দ্রুত পিন সম্পূর্ণ লগইন ক্রমের মতো নিরাপদ নাও হতে পারে, তবে এটি সরল পাঠ্যের চেয়ে অনেকগুণ বেশি সুরক্ষিত


5

আমি জানি এটি সামান্য সামান্যতম কাজ, তবে আপনার অ্যান্ড্রয়েড অ্যাকাউন্টম্যানেজারটি ব্যবহার করা উচিত । এটি এই দৃশ্যের জন্য উদ্দেশ্য-নির্মিত। এটি কিছুটা জটিল।

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

স্যাম্পেলসিঙ্কএডাপ্টার একটি উদাহরণ যা সঞ্চিত অ্যাকাউন্ট শংসাপত্রগুলি ব্যবহার করে।


1
দয়া করে নোট করুন যে অ্যাকাউন্টম্যানেজারটি ব্যবহার করা উপরোক্ত অন্য যে কোনও পদ্ধতির চেয়ে নিরাপদ নয়! বিকাশকারী.অ্যান্ড্রয়েড
ট্রেনিং / আইডিয়াথ/…

1
অ্যাকাউন্টম্যানেজারের ব্যবহারের ক্ষেত্রে হ'ল অ্যাকাউন্টটি যখন বিভিন্ন অ্যাপ্লিকেশন এবং বিভিন্ন লেখকের অ্যাপ্লিকেশনগুলির মধ্যে ভাগ করে নেওয়া হয়। পাসওয়ার্ডটি সংরক্ষণ করা এবং কোনও অনুরোধ অ্যাপ্লিকেশনটিতে এটি দেওয়া ঠিক হবে না। যদি ব্যবহারকারী / পাসওয়ার্ডের ব্যবহার কেবলমাত্র একটি একক অ্যাপ্লিকেশানের জন্য হয় তবে অ্যাকাউন্টম্যানেজারটি ব্যবহার করবেন না।
ডোলম্যান

1
@ ডলম্যান, এটি একদম সঠিক নয়। যার ইউআইডি প্রমাণীকরণকারীর সাথে মেলে না এমন অ্যাকাউন্টে ম্যানেজার অ্যাকাউন্টের পাসওয়ার্ড দেয় না। নাম, হ্যাঁ; লেখক টোকেন, হ্যাঁ; পাসওয়ার্ড, না। যদি আপনি চেষ্টা করেন তবে এটি একটি সুরক্ষা ধারণাটি ছুঁড়ে দেবে। এবং ব্যবহারের ক্ষেত্রে তার চেয়ে অনেক বিস্তৃত। developer.android.com/training/id-auth/uthorfy.html
জন হে

5

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

এর মতো দুটি পরামর্শ আমি সেখানে ফেলে দিতে চাই যদি সুরক্ষা আপনার জন্য প্রধান উদ্বেগ হয়:

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

2) 2 ফ্যাক্টর প্রমাণীকরণ ব্যবহার করুন। এটি আরও বিরক্তিকর এবং হস্তক্ষেপমূলক হতে পারে তবে কিছু আনুগত্যের জন্য বাধ্যবাধকতা রয়েছে।


2

আপনি উল্লিখিত কার্যকারিতা সহ আপনি এই ছোট্ট lib টিও পরীক্ষা করতে পারেন।

https://github.com/kovmarci86/android-secure-preferences

এটি এখানে অন্যান্য অ্যাপ্রোচগুলির মতো। আশা করি সহায়তা করে :)


2

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

ভাগ করা পছন্দগুলি কীভাবে ব্যবহার করবেন

ব্যবহারকারীর সেটিংস সাধারণত SharedPreferencesকী-মান জুটির সাহায্যে Android এ স্থানীয়ভাবে সংরক্ষণ করা হয় saved Stringসম্পর্কিত মানটি সংরক্ষণ করতে বা সন্ধান করতে আপনি কীটি ব্যবহার করেন ।

ভাগ করা পছন্দগুলিতে লিখুন

String key = "myInt";
int valueToSave = 10;

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(key, valueToSave).commit();

তাত্ক্ষণিক না হয়ে পটভূমিতে সংরক্ষণ করার apply()পরিবর্তে ব্যবহার করুন commit()

ভাগ করা পছন্দগুলি থেকে পড়ুন

String key = "myInt";
int defaultValue = 0;

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
int savedValue = sharedPref.getInt(key, defaultValue);

কীটি না পাওয়া গেলে ডিফল্ট মান ব্যবহৃত হয়।

মন্তব্য

  • আমি উপরের মতো একাধিক জায়গায় লোকাল কী স্ট্রিং ব্যবহার না করে একক স্থানে ধ্রুবক ব্যবহার করা ভাল। আপনি আপনার সেটিংস ক্রিয়াকলাপের শীর্ষে এই জাতীয় কিছু ব্যবহার করতে পারেন:

    final static String PREF_MY_INT_KEY = "myInt";
  • আমি একজন ব্যবহৃত intআমার উদাহরণে, কিন্তু আপনি ব্যবহার করতে পারেন putString(), putBoolean(), getString(), getBoolean(), ইত্যাদি

  • আরও বিশদ জন্য ডকুমেন্টেশন দেখুন ।
  • অংশীদারি পছন্দগুলি পাওয়ার একাধিক উপায় রয়েছে। কী সন্ধান করতে হবে তার জন্য এই উত্তরটি দেখুন ।

1

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

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

এখানে কাস্টম এডিটেক্সট প্রেফারেন্স ক্লাসের কোড রয়েছে:

package com.Merlinia.OutBack_Client;

import android.content.Context;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.util.Base64;

import com.Merlinia.MEncryption_Main.MEncryptionUserPassword;


/**
 * This class extends the EditTextPreference view, providing encryption and decryption services for
 * OutBack user passwords. The passwords in the preferences store are first encrypted using the
 * MEncryption classes and then converted to string using Base64 since the preferences store can not
 * store byte arrays.
 *
 * This is largely copied from this article, except for the encryption/decryption parts:
 * https://groups.google.com/forum/#!topic/android-developers/pMYNEVXMa6M
 */
public class EditPasswordPreference  extends EditTextPreference {

    // Constructor - needed despite what compiler says, otherwise app crashes
    public EditPasswordPreference(Context context) {
        super(context);
    }


    // Constructor - needed despite what compiler says, otherwise app crashes
    public EditPasswordPreference(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
    }


    // Constructor - needed despite what compiler says, otherwise app crashes
    public EditPasswordPreference(Context context, AttributeSet attributeSet, int defaultStyle) {
        super(context, attributeSet, defaultStyle);
    }


    /**
     * Override the method that gets a preference from the preferences storage, for display by the
     * EditText view. This gets the base64 password, converts it to a byte array, and then decrypts
     * it so it can be displayed in plain text.
     * @return  OutBack user password in plain text
     */
    @Override
    public String getText() {
        String decryptedPassword;

        try {
            decryptedPassword = MEncryptionUserPassword.aesDecrypt(
                     Base64.decode(getSharedPreferences().getString(getKey(), ""), Base64.DEFAULT));
        } catch (Exception e) {
            e.printStackTrace();
            decryptedPassword = "";
        }

        return decryptedPassword;
    }


    /**
     * Override the method that gets a text string from the EditText view and stores the value in
     * the preferences storage. This encrypts the password into a byte array and then encodes that
     * in base64 format.
     * @param passwordText  OutBack user password in plain text
     */
    @Override
    public void setText(String passwordText) {
        byte[] encryptedPassword;

        try {
            encryptedPassword = MEncryptionUserPassword.aesEncrypt(passwordText);
        } catch (Exception e) {
            e.printStackTrace();
            encryptedPassword = new byte[0];
        }

        getSharedPreferences().edit().putString(getKey(),
                                          Base64.encodeToString(encryptedPassword, Base64.DEFAULT))
                .commit();
    }


    @Override
    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
        if (restoreValue)
            getEditText().setText(getText());
        else
            super.onSetInitialValue(restoreValue, defaultValue);
    }
}

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

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <EditTextPreference
        android:key="@string/useraccountname_key"
        android:title="@string/useraccountname_title"
        android:summary="@string/useraccountname_summary"
        android:defaultValue="@string/useraccountname_default"
        />

    <com.Merlinia.OutBack_Client.EditPasswordPreference
        android:key="@string/useraccountpassword_key"
        android:title="@string/useraccountpassword_title"
        android:summary="@string/useraccountpassword_summary"
        android:defaultValue="@string/useraccountpassword_default"
        />

    <EditTextPreference
        android:key="@string/outbackserverip_key"
        android:title="@string/outbackserverip_title"
        android:summary="@string/outbackserverip_summary"
        android:defaultValue="@string/outbackserverip_default"
        />

    <EditTextPreference
        android:key="@string/outbackserverport_key"
        android:title="@string/outbackserverport_title"
        android:summary="@string/outbackserverport_summary"
        android:defaultValue="@string/outbackserverport_default"
        />

</PreferenceScreen>

প্রকৃত এনক্রিপশন / ডিক্রিপশন হিসাবে, এটি পাঠকের অনুশীলন হিসাবে ছেড়ে গেছে। আমি বর্তমানে এই নিবন্ধটির উপর ভিত্তি করে কিছু কোড ব্যবহার করছি http://zenu.wordpress.com/2011/09/21/aes-128bit-cross-platform-java-and-c-encryption-compatibility/ যদিও বিভিন্ন মান সহ কী এবং সূচনা ভেক্টর জন্য।


1

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

সংবেদনশীল ডেটা নিরাপদে সংরক্ষণ করা উচিত বা মোটেই নয়। হারিয়ে যাওয়া ডিভাইস বা ম্যালওয়্যার সংক্রমণের ক্ষেত্রে, সুরক্ষিতভাবে সংরক্ষণ করা ডেটা আপোস করা যেতে পারে।


1

আমি ইসিবি মোডে আরএসএ ব্যবহার করে পাসওয়ার্ডটি এনক্রিপ্ট করতে অ্যান্ড্রয়েড কীস্টোর ব্যবহার করি এবং তারপরে এটি ভাগ করে নেওয়া পছন্দগুলিতে সংরক্ষণ করি save

আমি যখন পাসওয়ার্ডটি ফিরে চাই তখন আমি শেয়ারডপ্রাইফারেন্সগুলি থেকে এনক্রিপ্ট করা একটি পড়ি এবং কীস্টোর ব্যবহার করে এটি ডিক্রিপ্ট করি।

এই পদ্ধতির সাহায্যে আপনি একটি সর্বজনীন / প্রাইভেট কী-জুড়ি তৈরি করেন যেখানে ব্যক্তিগতটি অ্যান্ড্রয়েড দ্বারা সুরক্ষিতভাবে সংরক্ষণ করা হয় এবং পরিচালনা করা হয়।

এটি কীভাবে করা যায় তার একটি লিঙ্ক এখানে: অ্যান্ড্রয়েড কীস্টোর টিউটোরিয়াল


-2

ভাগ করা পছন্দগুলি হল আমাদের অ্যাপ্লিকেশন ডেটা সঞ্চয় করার সহজতম উপায়। তবে এটি সম্ভব যে কেউ অ্যাপ্লিকেশন ম্যানেজারের মাধ্যমে আমাদের ভাগ করা পছন্দসই ডেটা সাফ করতে পারে i সুতরাং আমি মনে করি না এটি আমাদের আবেদনের জন্য সম্পূর্ণ নিরাপদ।


-3

পাসওয়ার্ডগুলি সংরক্ষণ করার জন্য আপনাকে স্ক্লাইট, সুরক্ষা এপিট ব্যবহার করতে হবে। এখানে সর্বোত্তম উদাহরণ, যা পাসওয়ার্ড সংরক্ষণ করে - পাসওয়ার্ডসেফ। উত্স এবং ব্যাখ্যার জন্য এখানে লিঙ্কটি রয়েছে - http://code.google.com/p/android-passwordsafe/


3
ওপিতে একটি ব্যবহারকারীর নাম এবং পাসওয়ার্ডের জুড়ি রাখা দরকার। এই এক ব্যবহারের জন্য একটি সম্পূর্ণ ডাটাবেস টেবিল তৈরি করা বিবেচনা করা হাস্যকর হবে
এইচএক্সকেইন

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

দু'বছরের মন্তব্যে চমৎকার পুনরুত্থান! সত্যি কথা বলতে গেলে আমার মন্তব্যটি উত্তরের এক বছর পরে ছিল :) এমনকি মুষ্টিমেয় এফটিপি পাসওয়ার্ড সহ, ওভারহেড স্থান এবং কোডিং উভয়ের দিক থেকে SharedPreferences এর চেয়ে এসকিউএলাইট টেবিলের সাথে অনেক বড়। অবশ্যই এটি প্রয়োজনীয় হতে পারে না
এইচএক্সকেন 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.