নিরাপদে কীভাবে ব্যবহারকারীর নাম / পাসওয়ার্ড (স্থানীয়) সংরক্ষণ করবেন?


106

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

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


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

"ব্যবহারকারী" বলতে আপনি নিয়মিত উইন্ডোজ ব্যবহারকারী বা অন্য কিছু বোঝেন? (আমি মনে করি আপনারা কেউ কেউ আপনার "ব্যবহারকারীদের" মালিক হিসাবে নিয়মিত উইন্ডোজ ব্যবহারকারী ইতিমধ্যে একে অপরের ডেটা দেখতে পাচ্ছেন না ...)
আলেক্সি লেভেনকভ

আমি আপনার শিরোনাম সম্পাদনা করেছি। দয়া করে দেখুন, " প্রশ্নগুলিতে তাদের শিরোনামগুলিতে" ট্যাগ "অন্তর্ভুক্ত করা উচিত? ", যেখানে sensক্যমত "না, তাদের উচিত নয়"।
জন স্যান্ডার্স

@ জন স্যান্ডারস ঠিক আছে, আমার অজ্ঞতা ক্ষমা করুন।
রবিন 12

2
পূর্ণ উত্স কোড সহ কোনও চূড়ান্ত সমাধান?
কিকিনেট

উত্তর:


160

যদি আপনি কেবল প্রবেশ করা ব্যবহারকারীর নাম এবং পাসওয়ার্ড যাচাই / প্রমাণীকরণ করতে চলেছেন তবে আরএফসি 2898 ডেরিভডবাইটস ক্লাসটি (পাসওয়ার্ড ভিত্তিক কী ডেরিভেশন ফাংশন 2 বা পিবিকেডিএফ 2 নামে পরিচিত) ব্যবহার করুন। এটি ট্রিপল ডিইএস বা এইএসের মতো এনক্রিপশন ব্যবহার করার চেয়ে বেশি সুরক্ষিত কারণ আরএফসি 2898 ডেরিভাইডবাইটসের পাসওয়ার্ডে ফিরে যাওয়ার কোনও ফলসই উপায় নেই। আপনি কেবল পাসওয়ার্ড থেকে ফলাফল যেতে পারেন। দেখুন পাসওয়ার্ড স্ট্রিং থেকে এনক্রিপশন কী এবং IV প্রাপ্ত করার সময় লক হিসাবে পাসওয়ার্ডের SHA1 হ্যাশ ব্যবহার করা ঠিক কি? উইনআরটি / মেট্রোর জন্য পাসওয়ার্ড সহ নেট বা স্ট্রিং এনক্রিপ্ট / ডিক্রিপ্টের উদাহরণ এবং আলোচনার জন্য #

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

সি # তে, সিস্টেম.সিকিউরিটি.ক্রিপোগ্রাফি.প্রযুক্তি ডেটা ক্লাস ব্যবহার করুন । উদাহরণস্বরূপ, কোনও টুকরো ডেটা এনক্রিপ্ট করতে, ব্যবহার করুন ProtectedData.Protect():

// Data to protect. Convert a string to a byte[] using Encoding.UTF8.GetBytes().
byte[] plaintext; 

// Generate additional entropy (will be used as the Initialization vector)
byte[] entropy = new byte[20];
using(RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
    rng.GetBytes(entropy);
}

byte[] ciphertext = ProtectedData.Protect(plaintext, entropy,
    DataProtectionScope.CurrentUser);

এনট্রপি এবং সিফারেক্সট নিরাপদে সংরক্ষণ করুন, যেমন কোনও ফাইল বা রেজিস্ট্রি কীতে অনুমতি সহ সেট করা থাকে যাতে কেবলমাত্র বর্তমান ব্যবহারকারী এটি পড়তে পারেন। মূল ডেটাতে অ্যাক্সেস পেতে, ব্যবহার করুন ProtectedData.Unprotect():

byte[] plaintext= ProtectedData.Unprotect(ciphertext, entropy,
    DataProtectionScope.CurrentUser);

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


হাই, আমি এটি চেষ্টা করেছিলাম, তবে এন্ট্রপি = rng.GetBytes (20) এ বলে আমি একটি ত্রুটি পেয়েছি: int থেকে বাইটে রূপান্তর করা যায় না []
রবিন

@ ক্রিস্পি জিএমআর আমি উত্তরে সেই অংশের কোডটি ঠিক করেছি। ভালো বল ধরা.
অ্যাকটন 11

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

2
মনে হচ্ছে যে বর্গ এখন Rfc2898DeriveBytes হিসাবে (ছোট হাতের অক্ষর 4.6, 4.5 .net এবং) জানা হয়ে থাকে এবং এখানে পাওয়া যাবে: নামস্থান: System.Security.Cryptography পরিষদের: (mscorlib.dll মধ্যে) mscorlib
দাশু

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

8

আমি এটি আগে ব্যবহার করেছি এবং আমি মনে করি যে শংসাপত্রগুলি অব্যাহত রাখতে এবং সেরা সুরক্ষিত উপায়ে এটি নিশ্চিত করতে

  1. আপনি ConfigurationManagerক্লাসটি ব্যবহার করে এগুলি অ্যাপ্লিকেশন কনফিগারেশনে লিখতে পারেন
  2. SecureStringক্লাস ব্যবহার করে পাসওয়ার্ড সুরক্ষিত করা
  3. তারপরে Cryptographyনেমস্পেসে সরঞ্জামগুলি ব্যবহার করে এটি এনক্রিপ্ট করা ।

এই লিঙ্কটি সাহায্য করবে আশা করি: এখানে ক্লিক করুন


4

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


4

এটি কেবল উইন্ডোজে কাজ করে, সুতরাং আপনি যদি ডটনেট কোর ক্রস প্ল্যাটফর্ম ব্যবহার করার পরিকল্পনা করছেন তবে আপনাকে অন্য কোথাও দেখতে হবে। Https://github.com/dotnet/corefx/blob/master/Docamentation/architecture/cross-platform-cryptography.md দেখুন


এই লিঙ্কটি মারা গেছে (404)
কার্লোএক্স

1

আমি পঠনযোগ্য স্ট্রিং হিসাবে স্ট্রিংটি এনক্রিপ্ট এবং ডিক্রিপ্ট করতে চেয়েছিলাম।

উত্তরের উপর ভিত্তি করে সি # ভিজ্যুয়াল স্টুডিও 2019 উইনফোর্মে একটি খুব সাধারণ দ্রুত উদাহরণ @Pradip

প্রকল্প> বৈশিষ্ট্য> সেটিংস> একটি usernameএবং passwordসেটিংস তৈরি করতে ডান ক্লিক করুন ।

এখানে চিত্র বর্ণনা লিখুন

আপনি এখন স্রেফ তৈরি করা সেটিংগুলি আপনি লাভ করতে পারেন। এখানে আমি সংরক্ষণ করি usernameএবং passwordতবে কেবলমাত্র ফাইলটিতে passwordএটি সম্মানজনক মান ক্ষেত্রটি এনক্রিপ্ট করব user.config

user.configফাইলটিতে এনক্রিপ্ট করা স্ট্রিংয়ের উদাহরণ ।

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <secure_password_store.Properties.Settings>
            <setting name="username" serializeAs="String">
                <value>admin</value>
            </setting>
            <setting name="password" serializeAs="String">
                <value>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAQpgaPYIUq064U3o6xXkQOQAAAAACAAAAAAAQZgAAAAEAACAAAABlQQ8OcONYBr9qUhH7NeKF8bZB6uCJa5uKhk97NdH93AAAAAAOgAAAAAIAACAAAAC7yQicDYV5DiNp0fHXVEDZ7IhOXOrsRUbcY0ziYYTlKSAAAACVDQ+ICHWooDDaUywJeUOV9sRg5c8q6/vizdq8WtPVbkAAAADciZskoSw3g6N9EpX/8FOv+FeExZFxsm03i8vYdDHUVmJvX33K03rqiYF2qzpYCaldQnRxFH9wH2ZEHeSRPeiG</value>
            </setting>
        </secure_password_store.Properties.Settings>
    </userSettings>
</configuration>

এখানে চিত্র বর্ণনা লিখুন

সম্পূর্ণ কোড

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace secure_password_store
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Exit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private void Login_Click(object sender, EventArgs e)
        {
            if (checkBox1.Checked == true)
            {
                Properties.Settings.Default.username = textBox1.Text;
                Properties.Settings.Default.password = EncryptString(ToSecureString(textBox2.Text));
                Properties.Settings.Default.Save();
            }
            else if (checkBox1.Checked == false)
            {
                Properties.Settings.Default.username = "";
                Properties.Settings.Default.password = "";
                Properties.Settings.Default.Save();
            }
            MessageBox.Show("{\"data\": \"some data\"}","Login Message Alert",MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        private void DecryptString_Click(object sender, EventArgs e)
        {
            SecureString password = DecryptString(Properties.Settings.Default.password);
            string readable = ToInsecureString(password);
            textBox4.AppendText(readable + Environment.NewLine);
        }
        private void Form_Load(object sender, EventArgs e)
        {
            //textBox1.Text = "UserName";
            //textBox2.Text = "Password";
            if (Properties.Settings.Default.username != string.Empty)
            {
                textBox1.Text = Properties.Settings.Default.username;
                checkBox1.Checked = true;
                SecureString password = DecryptString(Properties.Settings.Default.password);
                string readable = ToInsecureString(password);
                textBox2.Text = readable;
            }
            groupBox1.Select();
        }


        static byte[] entropy = Encoding.Unicode.GetBytes("SaLtY bOy 6970 ePiC");

        public static string EncryptString(SecureString input)
        {
            byte[] encryptedData = ProtectedData.Protect(Encoding.Unicode.GetBytes(ToInsecureString(input)),entropy,DataProtectionScope.CurrentUser);
            return Convert.ToBase64String(encryptedData);
        }

        public static SecureString DecryptString(string encryptedData)
        {
            try
            {
                byte[] decryptedData = ProtectedData.Unprotect(Convert.FromBase64String(encryptedData),entropy,DataProtectionScope.CurrentUser);
                return ToSecureString(Encoding.Unicode.GetString(decryptedData));
            }
            catch
            {
                return new SecureString();
            }
        }

        public static SecureString ToSecureString(string input)
        {
            SecureString secure = new SecureString();
            foreach (char c in input)
            {
                secure.AppendChar(c);
            }
            secure.MakeReadOnly();
            return secure;
        }

        public static string ToInsecureString(SecureString input)
        {
            string returnValue = string.Empty;
            IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input);
            try
            {
                returnValue = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
            }
            return returnValue;
        }

        private void EncryptString_Click(object sender, EventArgs e)
        {
            Properties.Settings.Default.password = EncryptString(ToSecureString(textBox2.Text));
            textBox3.AppendText(Properties.Settings.Default.password.ToString() + Environment.NewLine);
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.