Sha256 দিয়ে একটি স্ট্রিং হ্যাশ করছে


141

আমি SHA256 ব্যবহার করে একটি স্ট্রিং হ্যাশ করার চেষ্টা করছি, আমি নিম্নলিখিত কোডটি ব্যবহার করছি:

using System;
using System.Security.Cryptography;
using System.Text;
 public class Hash
    {
    public static string getHashSha256(string text)
    {
        byte[] bytes = Encoding.Unicode.GetBytes(text);
        SHA256Managed hashstring = new SHA256Managed();
        byte[] hash = hashstring.ComputeHash(bytes);
        string hashString = string.Empty;
        foreach (byte x in hash)
        {
            hashString += String.Format("{0:x2}", x);
        }
        return hashString;
    }
}

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

কেউ কি জানেন যে ত্রুটিটি কী? বিভিন্ন ঘাঁটি?


17
বিষয় ছাড়াই তবে মনে রাখবেন যে স্ট্রিংবিল্ডার তৈরি করা এবং স্ট্রিংয়ের পরিবর্তে অ্যাপেন্ডফর্ম্যাট ব্যবহার করা .আপনার ফোরচ লুপে ফর্ম্যাট আপনার কোডটিকে অযথা স্ট্রিং অবজেক্ট তৈরি করতে বাধা দেবে।
মার্সেল ল্যামোথ

উত্তর:


154

Encoding.Unicodeইউটিএফ -16 (মাইক্রোসফ্টের বিভ্রান্তিমূলক নামটি ইউটিএফ -16 (ডাবল-ওয়াইড এনকোডিং, যা উইন্ডোজ বিশ্বে historicalতিহাসিক কারণে ব্যবহৃত হয় তবে অন্য কারও দ্বারা ব্যবহৃত হয় না)। http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx

যদি আপনি আপনার bytesঅ্যারেটি পরীক্ষা করেন তবে আপনি দেখতে পাবেন যে প্রতি সেকেন্ড বাইট 0x00(ডাবল-ওয়াইড এনকোডিংয়ের কারণে)।

Encoding.UTF8.GetBytesপরিবর্তে আপনি ব্যবহার করা উচিত ।

তবে এছাড়াও, আপনি টার্মিনেটিং '\0'বাইটকে আপনার হ্যাশ করা ডেটার অংশ হিসাবে বিবেচনা করছেন কিনা তা নির্ভর করে আপনি বিভিন্ন ফলাফল দেখতে পাবেন । দুটি বাইট "Hi"হ্যাশ করলে তিনটি বাইট হ্যাশ করা থেকে আলাদা ফলাফল পাওয়া যাবে "Hi"। আপনি যা করতে চান তা আপনাকে সিদ্ধান্ত নিতে হবে। (সম্ভবত আপনার বন্ধুর পিএইচপি কোড যেটিই করছেন আপনি করতে চান))

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


3
@ এলমিউ, আপনি "ইউটিএফ 8-এনকোডেড বাইট দ্বারা বাছাই করা" এবং "ইউনিকোড কোডপয়েন্ট দ্বারা বাছাই করা" সমতুল্য তা জানতে পেরে আপনি সন্তুষ্ট হতে পারেন! (আস "দ্বারা UTF16 এনকোডেড বাছাই করা হয় shortগুলি", কিন্তু না সত্যিই একটি যদি না আপনি একটি বড়-endian সিস্টেম, যা উইন্ডোজ নয় আছি "UTF16 এনকোডেড বাইট বাছাই"।) যাইহোক, "বাছাই" ইউনিকোড হল জটিল বিষয় যা অন্য দিনের জন্য সংরক্ষণ করা উচিত।
কুক্সপ্লসোন

2
@ এলমিউ আপনার ভুল উত্তরের বিষয়ে এতটা আত্মবিশ্বাসী হবেন না। চেষ্টা কর; আপনি অবাক হবেন আশ্চর্য আনন্দদায়ক বা অপ্রীতিকর কিনা তা সম্পূর্ণ আপনার উপর নির্ভর করে। :)
কুক্সপ্লসোন

2
@ এলম্যু, " আপনি যদি কোনও ক্ষেত্রে সংবেদনশীল তুলনা করতে চান? ”আপনি যদি এই ধরণের জিনিস করতে চান তবে আপনাকে ইউটিএফ -16 এ বাইটগুলি রূপান্তর করতে হবে। এটির দৈর্ঘ্য স্থির হওয়াটি কিছুটা সাহায্য করে না।
আর্টুরো টরেস সানচেজ

2
"অন্য কারও দ্বারা ব্যবহৃত হয় না" এটি বেশ আকর্ষণীয় দাবি, যেহেতু জাভা অভ্যন্তরীণভাবে ইউটিএফ -16 হিসাবে স্ট্রিংগুলি পরিচালনা করে ...
সামি কুহমনেন

4
@ এলমিউ "আপনার মন্তব্যগুলি ভুল: ইউটিএফ 16 ইউনিকোড।" আপনি ভুল. "ইউনিকোড" এমন একটি মান যা গ্লাইফগুলিকে সংখ্যার (কোড পয়েন্ট) বরাদ্দ করে। সারোগেট জোড়া বাদে কীভাবে এই সংখ্যাগুলিকে বাইট হিসাবে উপস্থাপন করা যায় তা নির্দেশ করে না। UTF16 কোড পয়েন্ট <--> বাইট নির্দিষ্ট করে। ইউনিকোড গ্লাইফগুলি উল্লেখ করে <--> কোড পয়েন্ট।
এন্টিডহ

103

অন্য একটি স্টাইল প্রয়োগের ক্ষেত্রেও আমার এই সমস্যা ছিল তবে আমি ভুলে গিয়েছিলাম যে এটি 2 বছর আগে যেহেতু পেয়েছিলাম it

static string sha256(string randomString)
{
    var crypt = new SHA256Managed();
    string hash = String.Empty;
    byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString));
    foreach (byte theByte in crypto)
    {
        hash += theByte.ToString("x2");
    }
    return hash;
}

আমি যখন abcdefghi2013কোনও কারণে ইনপুট করি তখন এটি আমার লগইন মডিউলে ত্রুটির ক্ষেত্রে বিভিন্ন ফলাফল এবং ফলাফল দেয়। তারপর আমি যেমন Quuxplusone দ্বারা প্রস্তাবিত থেকে এনকোডিং পরিবর্তন কোড একই ভাবে পরিবর্তন চেষ্টা ASCIIকরতে UTF8তারপর, এটা অবশেষে কাজ!

static string sha256(string randomString)
{
    var crypt = new System.Security.Cryptography.SHA256Managed();
    var hash = new System.Text.StringBuilder();
    byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
    foreach (byte theByte in crypto)
    {
        hash.Append(theByte.ToString("x2"));
    }
    return hash.ToString();
}

চমত্কার এবং বিস্তারিত উত্তরের জন্য আবারও কুক্সপ্লসোন ধন্যবাদ! :)


আপনার সমাধান আমার জন্য কাজ করে। তবে আমার আলাদা কেস আছে এটি sha512 এবং কোড লাইন দিয়ে আমার সমস্যার সমাধান করেছে আমি hash += bit.ToString("x2");এখানে একটি প্রশ্ন করেছি: আমি Convert.ToBase64String(byte[] encryptedBytes)বাইট থেকে স্ট্রিংয়ে ফিরে রূপান্তর করতে ব্যবহার করছি। যে আমাকে ভিন্ন ফলাফল দিচ্ছিল। সুতরাং এই দুটি পদ্ধতির মধ্যে কী বাইট থেকে স্ট্রিংয়ে রূপান্তরিত?
কেভাল লাঙ্গালিয়া

এখানে কি কিছু কাস্টমাইজেশন ব্যবহার করা সম্ভব (নিজের নিজস্ব আরম্ভের ভেক্টরের মতো) বা এলোমেলো / প্র্যান্ডেন্ডিং এলোমেলো স্ট্রিংয়ের একমাত্র বিকল্প?
ফ্রেনকিবি

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

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

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

6
public static string ComputeSHA256Hash(string text)
{
    using (var sha256 = new SHA256Managed())
    {
        return BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", "");
    }                
}

আপনি আলাদা ফলাফল পাওয়ার কারণ হ'ল কারণ আপনি একই স্ট্রিং এনকোডিংটি ব্যবহার করেন না। আপনি যে লিংকটি অন-লাইন ওয়েব সাইটের জন্য রেখেছেন তা SHA256 গণনা করে ইউটিএফ 8 এনকোডিং ব্যবহার করে, আপনার উদাহরণে আপনি ইউনিকোড এনকোডিং ব্যবহার করেছেন। এগুলি দুটি পৃথক এনকোডিং, সুতরাং আপনি একই ফলাফল পাবেন না। উপরের উদাহরণ সহ আপনি লিঙ্কযুক্ত ওয়েব সাইটের একই SHA256 হ্যাশ পাবেন। আপনাকে পিএইচপি তেও একই এনকোডিং ব্যবহার করতে হবে।

পরম সর্বনিম্ন প্রতিটি সফ্টওয়্যার বিকাশকারী অবশ্যই, ইউনিকোড এবং চরিত্রের সেটগুলি সম্পর্কে ইতিবাচকভাবে অবশ্যই জানতে হবে (কোনও বাহানা নেই!)

https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/


4

পিএইচপি সংস্করণে আপনি শেষ প্যারামিটারে 'সত্য' পাঠাতে পারেন, তবে ডিফল্টটি 'মিথ্যা'। প্রথম পরামিতি হিসাবে 'sha256' পাস করার সময় নিম্নলিখিত অ্যালগরিদম ডিফল্ট পিএইচপি এর হ্যাশ ফাংশনের সমতুল্য:

public static string GetSha256FromString(string strData)
    {
        var message = Encoding.ASCII.GetBytes(strData);
        SHA256Managed hashString = new SHA256Managed();
        string hex = "";

        var hashValue = hashString.ComputeHash(message);
        foreach (byte x in hashValue)
        {
            hex += String.Format("{0:x2}", x);
        }
        return hex;
    }

4
আমি পরিবর্তে ব্যবহার ASCIIএবং করব byte[] arrBytes = System.Text.Encoding.UTF8.GetBytes(strData)না।
c00000fd

3
public string EncryptPassword(string password, string saltorusername)
        {
            using (var sha256 = SHA256.Create())
            {
                var saltedPassword = string.Format("{0}{1}", salt, password);
                byte[] saltedPasswordAsBytes = Encoding.UTF8.GetBytes(saltedPassword);
                return Convert.ToBase64String(sha256.ComputeHash(saltedPasswordAsBytes));
            }
        }

1
আপনি যে পরিমাণে কিছু লবণ যুক্ত করেছেন তা আমি পছন্দ করি ^^
ফ্যাবিয়ান

1

সবচেয়ে স্বল্পতম এবং দ্রুততমতম পথ way মাত্র 1 লাইন!

public static string StringSha256Hash(string text) =>
    string.IsNullOrEmpty(text) ? string.Empty : BitConverter.ToString(new System.Security.Cryptography.SHA256Managed().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text))).Replace("-", string.Empty);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.