জাভাতে SHA-256 এর মাধ্যমে হ্যাশ স্ট্রিং


111

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

উত্তর:


264

একটি স্ট্রিং হ্যাশ করতে, অন্তর্নির্মিত ম্যাসেজডিজাস্ট শ্রেণিটি ব্যবহার করুন :

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.nio.charset.StandardCharsets;
import java.math.BigInteger;

public class CryptoHash {
  public static void main(String[] args) throws NoSuchAlgorithmException {
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    String text = "Text to hash, cryptographically.";

    // Change this to UTF-16 if needed
    md.update(text.getBytes(StandardCharsets.UTF_8));
    byte[] digest = md.digest();

    String hex = String.format("%064x", new BigInteger(1, digest));
    System.out.println(hex);
  }
}

উপরের স্নিপেটে digestহ্যাশ স্ট্রিং hexরয়েছে এবং বাম শূন্য প্যাডিং সহ একটি হেক্সাডেসিমাল এএসসিআইআই স্ট্রিং রয়েছে।


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

2
@ হ্যারি ফ্যাম: কল digestকরার পরে অভ্যন্তরীণ অবস্থাটি পুনরায় সেট হয়ে গেছে; সুতরাং যখন আপনি আগে আপডেট না করে আবার কল করেন, আপনি খালি স্ট্রিংয়ের হ্যাশ পাবেন।
দেবিলেস্কি

3
@ ব্রেন্ডনলং এখন, digestআবার স্ট্রিংয়ে কীভাবে পুনরুদ্ধার করবেন?
সাজাদ

1
@ সাজ্জাদ আপনার প্রিয় বেস 64 এনকোডিং ফাংশনটি ব্যবহার করুন। আমি ব্যক্তিগতভাবে অ্যাপাচি কমন্সে একটি পছন্দ করি ।
ব্রেন্ডন লং

1
@ অ্যাডাম না, এটি বিভ্রান্তিকর। বাইট অ্যারেতে SttoString´ কল করা বাইট অ্যারের সামগ্রীটি স্ট্রিংয়ে রূপান্তর করার চেয়ে আলাদা ফলাফল তৈরি করছে, ব্রেন্ডন লংস উত্তরটি আরও উপযুক্ত
ম্যাক্স.মাস্টারম্যান

30

এটি ইতিমধ্যে রানটাইম লাইবগুলিতে প্রয়োগ করা হয়েছে।

public static String calc(InputStream is) {
    String output;
    int read;
    byte[] buffer = new byte[8192];

    try {
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        while ((read = is.read(buffer)) > 0) {
            digest.update(buffer, 0, read);
        }
        byte[] hash = digest.digest();
        BigInteger bigInt = new BigInteger(1, hash);
        output = bigInt.toString(16);
        while ( output.length() < 32 ) {
            output = "0"+output;
        }
    } 
    catch (Exception e) {
        e.printStackTrace(System.err);
        return null;
    }

    return output;
}

একটি JEE6 + পরিবেশে কেউ JAXB ডেটা টাইপ কনভার্টার ব্যবহার করতে পারে :

import javax.xml.bind.DatatypeConverter;

String hash = DatatypeConverter.printHexBinary( 
           MessageDigest.getInstance("MD5").digest("SOMESTRING".getBytes("UTF-8")));

3
এই সংস্করণটিতে একটি বাগ রয়েছে (কমপক্ষে আজকের হিসাবে এবং জাভা 8 @ উইন 7 সহ)। '1234' হ্যাশ করার চেষ্টা করুন। ফলাফলটি অবশ্যই '03ac67 ...' দিয়ে শুরু হওয়া উচিত তবে এটি '3ac67 ...' দিয়ে শুরু হয়
ক্রিস

@ ক্রিস ধন্যবাদ, আমি এটি এখানে স্থির করেছি, তবে আমি এটির জন্য আমার প্রিয় একটি ভাল সমাধানটি বর্তমানে পেয়েছি: stackoverflow.com/questions/415953/…
স্ট্যাকার

1
এই পুরানো থ্রেডের নতুন পাঠকদের জন্য: @ স্ট্যাকার দ্বারা উল্লিখিত প্রিয় (এমডি 5-হ্যাশ) এখন নিরাপদ হিসাবে বিবেচিত নয় ( en.wikedia.org/wiki/MD5 )।
মর্টেনসির

1
শর্তটি আউটপুট.লেন্থ হতে হবে () <64, 32 নয়
সাম্পো

আমরা কীভাবে একই লবণের সাহায্যে তৈরি দুটি ভিন্ন হ্যাশ মানটির তুলনা করতে পারি? ধরুন, একটি ফর্ম লগইন থেকে আসে (তুলনা করার আগে সল্ট ব্যবহার করে হ্যাশ করা দরকার) এবং অন্যটি ডিবি থেকে আসে এবং তারপরে আমরা কীভাবে এই দুটি তুলনা করতে পারি?
Pra_A

16

অগত্যা আপনার বাউন্সিস্টল লাইব্রেরির প্রয়োজন নেই। Integer.toHexString ফাংশনটি ব্যবহার করে কীভাবে এটি করবেন তা নিম্নলিখিত কোডটি দেখায়

public static String sha256(String base) {
    try{
        MessageDigest digest = MessageDigest.getInstance("SHA-256");
        byte[] hash = digest.digest(base.getBytes("UTF-8"));
        StringBuffer hexString = new StringBuffer();

        for (int i = 0; i < hash.length; i++) {
            String hex = Integer.toHexString(0xff & hash[i]);
            if(hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }

        return hexString.toString();
    } catch(Exception ex){
       throw new RuntimeException(ex);
    }
}

এই পোস্ট থেকে ইউজার 1452273 কে বিশেষ ধন্যবাদ: জাভাতে sha256 সহ কিছু স্ট্রিং হ্যাশ করবেন কীভাবে?

ভাল কাজগুলো করতে থাকো !


9

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

MessageDigest sha = MessageDigest.getInstance("SHA-256");
sha.update(in.getBytes());
byte[] digest = sha.digest();

আপনি আপনার প্রয়োজন অনুযায়ী বেস 64 বা হেক্স এনকোডড সংস্করণ পেতে ডাইজেস্ট ব্যবহার করতে পারেন


কৌতূহলের বাইরে, আপনি কি সরাসরি digest()ইনপুট বাইট অ্যারে, এড়িয়ে যেতে পারেন update()?
লা

একটি জিনিস আমি লক্ষ্য করেছি যে এটি "SHA-256" নিয়ে কাজ করে যেখানে "SHA256" একটি NoSuchAlgorithmException নিক্ষেপ করে। কোনও বিগি নেই।
knpwrs

9
ব্র্যান্ডনের কাছে আমার মন্তব্য অনুসারে, কোনও এনকোডিং নির্দিষ্ট না করে ব্যবহার করবেন নাString.getBytes() । বর্তমানে এই কোডটি বিভিন্ন প্ল্যাটফর্মগুলিতে বিভিন্ন ফলাফল দিতে পারে - যা একটি ভাল-সংজ্ঞায়িত হ্যাশের জন্য ভাঙা আচরণ।
জন স্কিটি

@ লেডেঞ্জ হ্যাঁ - যদি আপনার স্ট্রিংটি সংক্ষিপ্ত আকার ধারণ করে @ কেপথেন্ডার আপনার ডান @ জোন স্কিটি স্ট্রিংয়ের বিষয়বস্তুর উপর নির্ভর করে - তবে হ্যাঁ একটি এনকোডিং স্ট্রিং গেটবাইটস সেভ সাইডে যুক্ত করুন
নিকোলাস গ্রেডওহল

7

জাভা 8: বেস 64 উপলব্ধ:

    MessageDigest md = MessageDigest.getInstance( "SHA-512" );
    md.update( inbytes );
    byte[] aMessageDigest = md.digest();

    String outEncoded = Base64.getEncoder().encodeToString( aMessageDigest );
    return( outEncoded );

5

আমি মনে করি আপনি SHA-256 ছাড়াই তুলনামূলকভাবে পুরানো জাভা সংস্করণ ব্যবহার করছেন। সুতরাং আপনাকে অবশ্যই আপনার জাভা সংস্করণে বাউনিসিস্টল সরবরাহকারীটিকে ইতিমধ্যে সরবরাহিত 'সুরক্ষা সরবরাহকারী'গুলিতে যুক্ত করতে হবে।

    // NEEDED if you are using a Java version without SHA-256    
    Security.addProvider(new BouncyCastleProvider());

    // then go as usual 
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    String text = "my string...";
    md.update(text.getBytes("UTF-8")); // or UTF-16 if needed
    byte[] digest = md.digest();

বাউন্সিস্টল উল্লেখ করার জন্য +1, যা জেডিকে উপলভ্য তুলনামূলকভাবে পোল্ট্রি নির্বাচনের তুলনায় বেশ কয়েকটি নতুন মেসেজডিজ্টস যুক্ত করে।
মজুয়ারেজ

0
return new String(Hex.encode(digest));

4
প্যাকেজ / সরবরাহকারীর তথ্য ছাড়া "হেক্স" শ্রেণিটি খুব সহায়ক নয়। এবং যদি এটি অ্যাপাচি কমন্স কোডেক থেকে হেক্স হয় তবে আমি তার return Hex.encodeHexString(digest)পরিবর্তে ব্যবহার করব ।

0

জাভা 8 ব্যবহার করা

MessageDigest digest = null;
try {
    digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
}
byte[] hash = digest.digest(text.getBytes(StandardCharsets.UTF_8));
String encoded = DatatypeConverter.printHexBinary(hash);        
System.out.println(encoded.toLowerCase());

-1

এটি "org.bouncycastle.util.encoders.Hex" নিম্নলিখিত প্যাকেজটির সাথে কাজ করবে

return new String(Hex.encode(digest));

এটি বাউন্সিস্টল জারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.