2010-06-23 13 views
99

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

उत्तर

226

एक स्ट्रिंग हैश, का उपयोग में निर्मित 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 स्ट्रिंग है।

+0

एक ही प्लेन टेक्स्ट के लिए, हैश हर बार अलग हो लगता है? क्योंकि यह मेरे साथ हो रहा है –

+2

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

+2

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

7

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

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

आप डाइजेस्ट का उपयोग अपनी आवश्यकताओं

+0

जिज्ञासा से बाहर, क्या आप इनपुट बाइट सरणी के साथ सीधे 'पाचन() 'पर जा सकते हैं,' अपडेट()' को छोड़कर? – ladenedge

+0

एक बात मैंने देखी है कि यह "SHA-256" के साथ काम करता है जबकि "SHA256" NoSuchAlgorithmException फेंकता है। कोई बड़ी बात नहीं – KPthunder

+8

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

28

यह पहले से ही क्रम libs में कार्यान्वित किया जाता के अनुसार एक बेस 64 या हेक्स इनकोडिंग संस्करण प्राप्त कर सकते हैं।

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"))); 
+1

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

+0

@Chris धन्यवाद से शुरू होता है, मैंने इसे यहां तय किया है, लेकिन मुझे एक बेहतर समाधान मिला है, इस पर मेरा पसंदीदा वर्तमान में है: http: // stackoverflow .com/प्रश्न/415953/how-can-i-gener-an-md5-hash/23273249 # 23273249 – stacker

+1

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

1
return new String(Hex.encode(digest)); 
+3

पैकेज/प्रदाता जानकारी के बिना "हेक्स" वर्ग बहुत उपयोगी नहीं है। और अगर वह अपाचे कॉमन्स कोडेक से हेक्स है तो मैं 'बदले हेक्स.एन्कोडहेक्सस्ट्रिंग (डाइजेस्ट)' का उपयोग करता हूं। – eckes

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(); 
+0

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

-1

इस पैकेज निम्नलिखित bouncycastle जार में

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

इसकी "org.bouncycastle.util.encoders.Hex" के साथ काम करेंगे।

14

आपको जौन्सीकास्टल लाइब्रेरी की आवश्यकता नहीं है। निम्नलिखित कोड से पता चलता इस पोस्ट से 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 को विशेष धन्यवाद का उपयोग कर ऐसा करने के लिए कैसे: How to hash some string with sha256 in Java?

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

7

जावा 8: Base64 उपलब्ध:

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

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