जावा में SHA-256 के माध्यम से हैश स्ट्रिंग


111

इधर-उधर देखने के साथ-साथ सामान्य रूप से इंटरनेट, मैंने बाउंसी कैसल पाया है । मैं जावा में एक स्ट्रिंग के SHA-256 हैश उत्पन्न करने के लिए बाउंसी कैसल (या कुछ अन्य स्वतंत्र रूप से उपलब्ध उपयोगिता) का उपयोग करना चाहता हूं। उनके दस्तावेज़ीकरण को देखकर मुझे लगता है कि मैं क्या करना चाहता हूं इसका कोई अच्छा उदाहरण नहीं मिल सकता है। क्या यहाँ कोई मेरी मदद कर सकता है?

जवाबों:


264

एक स्ट्रिंग हैश करने के लिए, अंतर्निहित MessageDigest वर्ग का उपयोग करें :

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शामिल है और बाईं शून्य गद्दी के साथ हेक्साडेसिमल ASCII स्ट्रिंग है।


2
@ हेरी फाम, हैश हमेशा एक ही होना चाहिए, लेकिन अधिक जानकारी के बिना यह कहना मुश्किल होगा कि आप अलग क्यों हो रहे हैं। आपको शायद एक नया प्रश्न खोलना चाहिए।
ब्रेंडन लॉन्ग

2
@ हैरी फाम: कॉल digestकरने के बाद आंतरिक स्थिति रीसेट हो जाती है; इसलिए जब आप इसे पहले अपडेट किए बिना फिर से कॉल करते हैं, तो आपको खाली स्ट्रिंग का हैश मिलता है।
डेबिल्स्की

3
@BrendanLong अब, digestस्ट्रिंग को फिर से पुनर्प्राप्ति कैसे करें?
सज्जाद

1
@ सज्जाद अपने पसंदीदा बेस 64 एनकोडिंग फ़ंक्शन का उपयोग करें। मैं व्यक्तिगत रूप से अपाचे कॉमन्स में से एक को पसंद करता हूं ।
ब्रेंडन लॉन्ग

1
@ अदम नहीं, यह भ्रामक है। बाइट सरणी पर ingtoString´ को कॉल करना, बाइट सरणी की सामग्री को स्ट्रिंग में परिवर्तित करने की तुलना में एक अलग परिणाम उत्पन्न कर रहा है, ब्रेंडन
लोंग्स

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 DataTypeConverter का उपयोग कर सकता है :

import javax.xml.bind.DatatypeConverter;

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

3
इस संस्करण में एक बग (कम से कम आज और java8 @ win7 के साथ) है। '1234' को हैश करने की कोशिश करें। परिणाम '03ac67 ...' से शुरू होना चाहिए, लेकिन यह वास्तव में '3ac67 ...' से शुरू होता है
क्रिस

@ धन्यवाद, मैंने इसे यहाँ ठीक कर दिया, लेकिन मुझे एक बेहतर समाधान मिल गया, इस पर मेरा पसंदीदा वर्तमान में है: stackoverflow.com/questions/415953/…
स्टेकर

1
इस पुराने सूत्र के नए पाठकों के लिए: @stacker द्वारा संदर्भित पसंदीदा (MD5-hash) अब असुरक्षित माना जाता है ( en.wikipedia.org/wiki/MD5 )।
मोर्टेंसी

1
हालत output.length होना चाहिए () <64, नहीं 32.
Sampo

हम एक ही नमक का उपयोग करके बनाए गए दो अलग-अलग हैशेड मूल्य की तुलना कैसे कर सकते हैं? मान लें, एक फॉर्म लॉगिन से आता है (तुलना करने से पहले नमक का उपयोग करने की आवश्यकता है) और दूसरा डीबी से आता है और फिर हम इन दोनों की तुलना कैसे कर सकते हैं?
प्र। ए।

16

जरूरी नहीं कि आपको BouncyCastle लाइब्रेरी की आवश्यकता हो। निम्न कोड दिखाता है कि 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);
    }
}

इस पोस्ट से user1452273 के लिए विशेष धन्यवाद: जावा में sha256 के साथ कुछ स्ट्रिंग कैसे करें?

अच्छा काम करते रहें !


9

किसी भी jce प्रदाता के साथ हैशकोड का उपयोग करते समय आप पहले एल्गोरिथ्म का एक उदाहरण प्राप्त करने का प्रयास करते हैं, फिर उस डेटा से अपडेट करें जिसे आप हैशेड करना चाहते हैं और जब आप समाप्त कर लेते हैं तो आप हैश मान प्राप्त करने के लिए डाइजेस्ट को कॉल करते हैं।

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

आप अपनी आवश्यकताओं के अनुसार बेस 64 या हेक्स एनकोडेड संस्करण प्राप्त करने के लिए डाइजेस्ट का उपयोग कर सकते हैं


जिज्ञासा से बाहर, आप सीधे digest()इनपुट बाइट सरणी के साथ जा सकते हैं , लंघन update()?
लाडनूं 16

एक बात मैंने देखी कि यह "SHA-256" के साथ काम करता है, जबकि "SHA256" एक NoSuchAl एल्गोरिदम के अपवाद को फेंकता है। कोई बड़ाई नहीं।
knpwrs

9
ब्रैंडन को मेरी टिप्पणी के अनुसार, एन्कोडिंग निर्दिष्ट किए बिना उपयोग करें String.getBytes()। वर्तमान में यह कोड विभिन्न प्लेटफार्मों पर अलग-अलग परिणाम दे सकता है - जो कि एक अच्छी तरह से परिभाषित हैश के लिए टूटा हुआ व्यवहार है।
जॉन स्कीट

@ladenedge हां - यदि आपका स्ट्रिंग काफी छोटा है तो @Kththunder आपका अधिकार @Jon Skeet स्ट्रिंग की सामग्री पर निर्भर करता है - लेकिन हां एक एन्कोडिंग स्ट्रिंग 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 के बिना एक अपेक्षाकृत पुराने जावा संस्करण का उपयोग कर रहे हैं। इसलिए आपको अपने जावा संस्करण में पहले से उपलब्ध 'सिक्योरिटी प्रोवाइडर्स' के लिए BouncyCastle प्रदाता को जोड़ना होगा।

    // 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();

BouncyCastle का उल्लेख करने के लिए +1, जो JDK में उपलब्ध अपेक्षाकृत तालमेल चयन की तुलना में कुछ नए मैसेजडिजेस्ट जोड़ता है।
मुजरेज़

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

4
पैकेज / प्रदाता जानकारी के बिना "हेक्स" वर्ग बहुत उपयोगी नहीं है। और अगर वह अपाचे कॉमन्स कोडेक से हेक्स है तो मैं return Hex.encodeHexString(digest)इसके बजाय उपयोग करूंगा ।
eckes

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.b Councilycastle.util.encoders.Hex" के साथ काम करेगा

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

बाउंसिलकास्टल जार में इसकी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.