मैं जावा में पासवर्ड कैसे रख सकता हूं?


176

मुझे डेटाबेस में स्टोरेज के लिए हैश पासवर्ड की आवश्यकता है। मैं जावा में यह कैसे कर सकता हूं?

मैं सादे पाठ पासवर्ड लेने की उम्मीद कर रहा था, एक यादृच्छिक नमक जोड़ें, फिर डेटाबेस में नमक और हैशेड पासवर्ड संग्रहीत करें।

फिर जब कोई उपयोगकर्ता लॉग इन करना चाहता था, तो मैं उनका प्रस्तुत पासवर्ड ले सकता था, उनके खाते की जानकारी से यादृच्छिक नमक जोड़ सकता था, हैश कर सकता था और यह देख सकता था कि यह उनके खाते की जानकारी के साथ संग्रहीत हैश पासवर्ड के बराबर है या नहीं।


11
@ यह वास्तव में आजकल एक पुनर्संयोजन नहीं है क्योंकि GPU हमलों के इतने सस्ते होने के कारण, SHA परिवार वास्तव में नमक के साथ पासवर्ड हैशिंग (बहुत तेज़) के लिए एक बहुत बुरा विकल्प है। Bcrypt, scrypt या PBKDF2
Eran Medan

11
यह सवाल क्यों बंद किया गया? यह एक वास्तविक इंजीनियरिंग समस्या के लिए एक सवाल है, और जवाब अमूल्य हैं। ओपी एक पुस्तकालय के लिए नहीं कह रहा है, वह पूछ रहा है कि इंजीनियरिंग समस्या को कैसे हल किया जाए।
stackoverflowuser2010

12
बस कमाल। इस प्रश्न के 52 उत्थान हैं, और कोई इसे "ऑफ-टॉपिक" के रूप में बंद करने का निर्णय लेता है।
stackoverflowuser2010

1
हाँ, मैं मेटा पर पोस्टिंग के इस मुद्दे के बारे में पहले भी पोस्ट कर चुका हूँ, हालांकि बहुत बुरी तरह से पिट गया।
क्रिस डुट्रो

8
यह प्रश्न फिर से खोला जाना चाहिए। यह एक प्रश्न है कि शॉर्ट कोड समाधान के साथ वर्णित समस्या (पासवर्ड प्रमाणीकरण) को हल करने के लिए एक कार्यक्रम कैसे लिखें। ट्रिगर शब्द "लाइब्रेरी" देखकर स्पष्ट रूप से एक प्रश्न को बंद करने का औचित्य नहीं है; वह लाइब्रेरी की सिफारिश नहीं मांग रहा है, वह पूछ रहा है कि पासवर्ड कैसे हैश करें। संपादित करें: वहाँ, इसे ठीक किया।
इरिकसन

जवाबों:


157

आप वास्तव में ऐसा करने के लिए जावा रनटाइम में निर्मित सुविधा का उपयोग कर सकते हैं। जावा 6 में सनजेस PBKDF2 का समर्थन करता है, जो पासवर्ड हैशिंग के लिए उपयोग करने के लिए एक अच्छा एल्गोरिथ्म है।

byte[] salt = new byte[16];
random.nextBytes(salt);
KeySpec spec = new PBEKeySpec("password".toCharArray(), salt, 65536, 128);
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
byte[] hash = f.generateSecret(spec).getEncoded();
Base64.Encoder enc = Base64.getEncoder();
System.out.printf("salt: %s%n", enc.encodeToString(salt));
System.out.printf("hash: %s%n", enc.encodeToString(hash));

यहां एक उपयोगिता वर्ग है जिसे आप PBKDF2 पासवर्ड प्रमाणीकरण के लिए उपयोग कर सकते हैं:

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

/**
 * Hash passwords for storage, and test passwords against password tokens.
 * 
 * Instances of this class can be used concurrently by multiple threads.
 *  
 * @author erickson
 * @see <a href="http://stackoverflow.com/a/2861125/3474">StackOverflow</a>
 */
public final class PasswordAuthentication
{

  /**
   * Each token produced by this class uses this identifier as a prefix.
   */
  public static final String ID = "$31$";

  /**
   * The minimum recommended cost, used by default
   */
  public static final int DEFAULT_COST = 16;

  private static final String ALGORITHM = "PBKDF2WithHmacSHA1";

  private static final int SIZE = 128;

  private static final Pattern layout = Pattern.compile("\\$31\\$(\\d\\d?)\\$(.{43})");

  private final SecureRandom random;

  private final int cost;

  public PasswordAuthentication()
  {
    this(DEFAULT_COST);
  }

  /**
   * Create a password manager with a specified cost
   * 
   * @param cost the exponential computational cost of hashing a password, 0 to 30
   */
  public PasswordAuthentication(int cost)
  {
    iterations(cost); /* Validate cost */
    this.cost = cost;
    this.random = new SecureRandom();
  }

  private static int iterations(int cost)
  {
    if ((cost < 0) || (cost > 30))
      throw new IllegalArgumentException("cost: " + cost);
    return 1 << cost;
  }

  /**
   * Hash a password for storage.
   * 
   * @return a secure authentication token to be stored for later authentication 
   */
  public String hash(char[] password)
  {
    byte[] salt = new byte[SIZE / 8];
    random.nextBytes(salt);
    byte[] dk = pbkdf2(password, salt, 1 << cost);
    byte[] hash = new byte[salt.length + dk.length];
    System.arraycopy(salt, 0, hash, 0, salt.length);
    System.arraycopy(dk, 0, hash, salt.length, dk.length);
    Base64.Encoder enc = Base64.getUrlEncoder().withoutPadding();
    return ID + cost + '$' + enc.encodeToString(hash);
  }

  /**
   * Authenticate with a password and a stored password token.
   * 
   * @return true if the password and token match
   */
  public boolean authenticate(char[] password, String token)
  {
    Matcher m = layout.matcher(token);
    if (!m.matches())
      throw new IllegalArgumentException("Invalid token format");
    int iterations = iterations(Integer.parseInt(m.group(1)));
    byte[] hash = Base64.getUrlDecoder().decode(m.group(2));
    byte[] salt = Arrays.copyOfRange(hash, 0, SIZE / 8);
    byte[] check = pbkdf2(password, salt, iterations);
    int zero = 0;
    for (int idx = 0; idx < check.length; ++idx)
      zero |= hash[salt.length + idx] ^ check[idx];
    return zero == 0;
  }

  private static byte[] pbkdf2(char[] password, byte[] salt, int iterations)
  {
    KeySpec spec = new PBEKeySpec(password, salt, iterations, SIZE);
    try {
      SecretKeyFactory f = SecretKeyFactory.getInstance(ALGORITHM);
      return f.generateSecret(spec).getEncoded();
    }
    catch (NoSuchAlgorithmException ex) {
      throw new IllegalStateException("Missing algorithm: " + ALGORITHM, ex);
    }
    catch (InvalidKeySpecException ex) {
      throw new IllegalStateException("Invalid SecretKeyFactory", ex);
    }
  }

  /**
   * Hash a password in an immutable {@code String}. 
   * 
   * <p>Passwords should be stored in a {@code char[]} so that it can be filled 
   * with zeros after use instead of lingering on the heap and elsewhere.
   * 
   * @deprecated Use {@link #hash(char[])} instead
   */
  @Deprecated
  public String hash(String password)
  {
    return hash(password.toCharArray());
  }

  /**
   * Authenticate with a password in an immutable {@code String} and a stored 
   * password token. 
   * 
   * @deprecated Use {@link #authenticate(char[],String)} instead.
   * @see #hash(String)
   */
  @Deprecated
  public boolean authenticate(String password, String token)
  {
    return authenticate(password.toCharArray(), token);
  }

}

11
आप बाइट से हेक्स रूपांतरणों से थोड़ा सावधान रहना चाह सकते हैं BigInteger: प्रमुख शून्य हटा दिए जाते हैं। यह त्वरित डिबग के लिए ठीक है, लेकिन मैंने उस प्रभाव के कारण उत्पादन कोड में कीड़े देखे हैं।
थॉमस पोर्निन

24
@ थोमस-पोर्निन की हाइलाइट्स हमें लाइब्रेरी की आवश्यकता क्यों है , कोड ब्लॉक नहीं है जो लगभग वहां है। डरावना कि स्वीकृत उत्तर इस तरह के एक महत्वपूर्ण विषय पर प्रश्न का उत्तर नहीं देता है।
निलज़ोर

9
जावा 8 के साथ शुरू होने वाले एल्गोरिथ्म PBKDF2WithHmacSHA512 का उपयोग करें। यह थोड़ा मजबूत है।
इवान .z

1
ध्यान दें, मौजूदा ALGs बाद के संस्करणों में नहीं हटाया जाता है: java_4: PBEWithMD5AndDES, DESede, डेस java_5 / 6/7: PBKDF2WithHmacSHA1, PBE, PBEWithSHA1AndRC2_40, PBEWithSHA1And, PBEWithMD5AndTriple java_8 (केवल जावा 5 में): PBEWithHmacSHA224AndAES_128, PBEWithHmacSHA384AndAES_128, PBEWithHmacSHA512AndAES_128, RC4_40, PBKDF2WithHmacSHA256 , PBEWithHmacSHA1AndAES_128, RC4_128, PBKDF2WithHmacSHA224, PBEWithHmacSHA256AndAES_256, RC2_128, PBEWithHmacSHA224AndAES_256, PBEWithHmacSHA384AndAES_256, PBEWithHmacSHA512AndAES_256, PBKDF2WithHmacSHA512, PBEWithHmacSHA256AndAES_128, PBKDF2WithHmacSHA384, PBEWithHmacSHA1AndAES_256
iwan.z

4
@ द पोस्टर्स हां, गलत पासवर्ड के लिए निष्पादन का समय लंबा होगा ; अधिक विशेष रूप से, गलत पासवर्ड सही पासवर्ड के रूप में एक ही समय लगेगा। यह समय के हमलों को रोकता है , हालांकि मैं मानता हूं कि मैं इस मामले में इस तरह की भेद्यता का फायदा उठाने के लिए एक व्यावहारिक तरीका नहीं सोच सकता। लेकिन आप कोनों में कटौती नहीं करते। सिर्फ इसलिए कि मैं इसे नहीं देख सकता, इसका मतलब यह नहीं है कि अधिक कुटिल दिमाग नहीं होगा।
एरिक्सन

97

यहाँ दो तरीकों के साथ एक पूर्ण कार्यान्वयन है जो आप चाहते हैं:

String getSaltedHash(String password)
boolean checkPassword(String password, String stored)

मुद्दा यह है कि भले ही एक हमलावर को आपके डेटाबेस और स्रोत कोड दोनों तक पहुंच प्राप्त हो, पासवर्ड अभी भी सुरक्षित हैं।

import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.SecureRandom;
import org.apache.commons.codec.binary.Base64;

public class Password {
    // The higher the number of iterations the more 
    // expensive computing the hash is for us and
    // also for an attacker.
    private static final int iterations = 20*1000;
    private static final int saltLen = 32;
    private static final int desiredKeyLen = 256;

    /** Computes a salted PBKDF2 hash of given plaintext password
        suitable for storing in a database. 
        Empty passwords are not supported. */
    public static String getSaltedHash(String password) throws Exception {
        byte[] salt = SecureRandom.getInstance("SHA1PRNG").generateSeed(saltLen);
        // store the salt with the password
        return Base64.encodeBase64String(salt) + "$" + hash(password, salt);
    }

    /** Checks whether given plaintext password corresponds 
        to a stored salted hash of the password. */
    public static boolean check(String password, String stored) throws Exception{
        String[] saltAndHash = stored.split("\\$");
        if (saltAndHash.length != 2) {
            throw new IllegalStateException(
                "The stored password must have the form 'salt$hash'");
        }
        String hashOfInput = hash(password, Base64.decodeBase64(saltAndHash[0]));
        return hashOfInput.equals(saltAndHash[1]);
    }

    // using PBKDF2 from Sun, an alternative is https://github.com/wg/scrypt
    // cf. http://www.unlimitednovelty.com/2012/03/dont-use-bcrypt.html
    private static String hash(String password, byte[] salt) throws Exception {
        if (password == null || password.length() == 0)
            throw new IllegalArgumentException("Empty passwords are not supported.");
        SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        SecretKey key = f.generateSecret(new PBEKeySpec(
            password.toCharArray(), salt, iterations, desiredKeyLen));
        return Base64.encodeBase64String(key.getEncoded());
    }
}

हम भंडारण कर रहे हैं 'salt$iterated_hash(password, salt)'। नमक 32 यादृच्छिक बाइट्स हैं और यह उद्देश्य है कि यदि दो अलग-अलग लोग एक ही पासवर्ड चुनते हैं, तो संग्रहीत पासवर्ड अभी भी अलग दिखेंगे।

iterated_hash, जो मूल रूप से है hash(hash(hash(... hash(password, salt) ...)))यह बहुत एक संभावित हमलावर अनुमान पासवर्ड, उन्हें हैश करने के लिए अपने डेटाबेस तक पहुँच गया है के लिए महंगा बना देता है, और डेटाबेस में हैश देखो। iterated_hashजब भी कोई उपयोगकर्ता लॉग इन करता है तो आपको हर बार इसकी गणना करनी होती है, लेकिन यह आपको उस हमलावर की तुलना में बहुत अधिक खर्च नहीं करता है जो अपने समय के कंप्यूटिंग हैश का लगभग 100% खर्च करता है।


14
नाग को क्षमा करें, लेकिन मुझे इसे मौजूदा पुस्तकालय में क्यों चुनना चाहिए? एक पुस्तकालय में संभवतः पूरी तरह से समीक्षा किए जाने की संभावना अधिक होती है। मुझे संदेह है कि 14 में से हर एक वोट ने किसी भी समस्या के लिए कोड का विश्लेषण किया।
जोकिम सॉउर

2
@JoachimSauer यह अनिवार्य रूप से केवल एक पुस्तकालय (javax.crypto) का उपयोग कर रहा है, लेकिन आप सही हैं - खाली पासवर्ड समर्थित नहीं हैं। इसे स्पष्ट करने के लिए एक अपवाद जोड़ा गया। धन्यवाद!
मार्टिन कोनिसक

3
आपको शायद char[] passwordइसके बजाय तरीकों के हस्ताक्षरों को बदलना चाहिए String password
assylias

2
हालांकि ऐसा लगता है कि संदर्भ को एकमत सहमति नहीं मिली है। इसे भी देखें: security.stackexchange.com/a/20369/12614
assylias

3
क्या आप सुनिश्चित हैं कि तार पर (।) शॉर्ट-सर्किट नहीं है (यानी: दो बाइट्स समान नहीं मिलने पर लूप करना बंद कर दें)? अगर ऐसा होता है तो पासवर्ड हैश के बारे में जानकारी लीक करने वाले टाइमिंग अटैक का खतरा रहता है।
बोबपोकेर्ट


7

आप OWASP द्वारा वर्णित शिरो लाइब्रेरी (पूर्व में JSecurity ) के कार्यान्वयन का उपयोग कर सकते हैं ।

यह भी लगता है कि JASYPT लाइब्रेरी की समान उपयोगिता है


Thats वास्तव में मैं क्या उपयोग कर रहा था। लेकिन जब से हमने शिरो का उपयोग नहीं करने का फैसला किया, तो उस एक पैकेज के लिए पूरे शिरो लाइब्रेरी को शामिल करने की अक्षमता के बारे में कुछ चिंता थी।
क्रिस ड्यूट्रो

मुझे नहीं पता कि एक पुस्तकालय सिर्फ एक पासवर्ड हैशिंग उपयोगिता से बना है। अगर आप निर्भरता एक चिंता का विषय हैं, तो आप शायद अपना ही रोल बेहतर कर रहे हैं। एरिकसन का जवाब मुझे बहुत अच्छा लगता है। या कोड को उस OWASP लिंक से कॉपी करें जिसे मैंने संदर्भित किया था कि आप सुरक्षित तरीके से SHA का उपयोग करेंगे।
लाज़

7

आप हैश का उपयोग करके गणना कर सकते हैं MessageDigest, लेकिन सुरक्षा के मामले में यह गलत है। पासवर्ड स्टोर करने के लिए हैश का उपयोग नहीं किया जाना चाहिए, क्योंकि वे आसानी से टूटने योग्य होते हैं।

आपको पासवर्ड स्टोर करने के लिए bcrypt, PBKDF2 और scrypt जैसे अन्य एल्गोरिदम का उपयोग करना चाहिए। यहाँ देखें


3
डेटाबेस में नमक का भंडारण किए बिना लॉगिन पर पासवर्ड कैसे होगा?
जेडजेड कोडर

9
नमक के रूप में उपयोगकर्ता नाम का उपयोग करना एक घातक दोष नहीं है, लेकिन यह एक क्रिप्टोग्राफिक आरएनजी से नमक का उपयोग करने के रूप में कहीं भी अच्छा नहीं है। और डेटाबेस में नमक को स्टोर करने में कोई समस्या नहीं है। नमक गुप्त नहीं है।
इरिकसन

1
क्या उपयोगकर्ता नाम और ई-मेल भी डेटाबेस में संग्रहीत नहीं किए जाएंगे?
क्रिस डुट्रो

@ZZ कोडर, @erickson सही है, मैंने किसी तरह यह मान लिया कि यह सभी पासवर्डों के लिए एक नमक होगा, जिससे आसानी से गणना योग्य इंद्रधनुष तालिका बन जाएगी।
बोजो

13
नमक के रूप में उपयोगकर्ता नाम (या ईमेल जैसी अन्य आईडी) का उपयोग करने के साथ एक समस्या यह है कि आप तब उपयोगकर्ता को नया पासवर्ड सेट किए बिना आईडी को बदल नहीं सकते हैं।
लॉरेंस Dol

6

अन्य उत्तरों में उल्लिखित bcrypt और PBKDF2 के अलावा, मैं scrypt को देखने की सलाह दूंगा

MD5 और SHA-1 की अनुशंसा नहीं की जाती है क्योंकि वे अपेक्षाकृत तेज़ होते हैं "किराए पर प्रति घंटा" वितरित कंप्यूटिंग (जैसे EC2) या आधुनिक उच्च अंत GPU एक का उपयोग करके अपेक्षाकृत कम लागत और उचित तरीके से क्रूर बल / शब्दकोश हमलों का उपयोग करके पासवर्ड को "क्रैक" कर सकते हैं। समय।

यदि आपको उनका उपयोग करना चाहिए, तो कम से कम एल्गोरिथ्म को पूर्वनिर्धारित महत्वपूर्ण मात्रा में पुनरावृत्त करें (1000+)।


6

एरिकसन से पूरी तरह सहमत हैं कि PBKDF2 इसका उत्तर है।

यदि आपके पास वह विकल्प नहीं है, या केवल हैश का उपयोग करने की आवश्यकता है, तो Apache Commons DigestUtils JCE कोड सही होने से बहुत आसान है: https://commons.apache.org/proper/commons-codec/apidocs/org/apache /commons/codec/digest/DigestUtils.html

यदि आप हैश का उपयोग करते हैं, तो sha256 या sha512 के साथ जाएं। इस पृष्ठ में पासवर्ड हैंडलिंग और हैशिंग पर अच्छी अनुशंसाएँ हैं (ध्यान दें कि यह पासवर्ड से निपटने के लिए हैशिंग की अनुशंसा नहीं करता है): http://www.daemonology.net/blog/2009-06-11-cryptographic-right-answers.html


यह ध्यान देने योग्य है कि SHA512 SHA256 (इस उद्देश्य के लिए) से बेहतर नहीं है, क्योंकि संख्या बड़ी है।
अज्जी

5

आप स्प्रिंग सिक्योरिटी क्रिप्टो (केवल 2 वैकल्पिक संकलन निर्भरताएँ ) का उपयोग कर सकते हैं , जो PBKDF2 , BCrypt , SCrypt और Argon2 पासवर्ड एन्क्रिप्शन का समर्थन करता है।

Argon2PasswordEncoder argon2PasswordEncoder = new Argon2PasswordEncoder();
String aCryptedPassword = argon2PasswordEncoder.encode("password");
boolean passwordIsValid = argon2PasswordEncoder.matches("password", aCryptedPassword);
SCryptPasswordEncoder sCryptPasswordEncoder = new SCryptPasswordEncoder();
String sCryptedPassword = sCryptPasswordEncoder.encode("password");
boolean passwordIsValid = sCryptPasswordEncoder.matches("password", sCryptedPassword);
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String bCryptedPassword = bCryptPasswordEncoder.encode("password");
boolean passwordIsValid = bCryptPasswordEncoder.matches("password", bCryptedPassword);
Pbkdf2PasswordEncoder pbkdf2PasswordEncoder = new Pbkdf2PasswordEncoder();
String pbkdf2CryptedPassword = pbkdf2PasswordEncoder.encode("password");
boolean passwordIsValid = pbkdf2PasswordEncoder.matches("password", pbkdf2CryptedPassword);

4

जबकि NIST अनुशंसा PBKDF2 पहले ही उल्लेख किया जा चुका है, मैं बताना चाहूंगा कि 2013 से 2015 तक एक सार्वजनिक पासवर्ड हैशिंग प्रतियोगिता हुई थी। अंत में, Argon2 को अनुशंसित पासवर्ड हैशिंग फ़ंक्शन के रूप में चुना गया था।

मूल (देशी C) लाइब्रेरी के लिए काफी अच्छी तरह से अपनाई गई जावा बाइंडिंग है जिसका आप उपयोग कर सकते हैं।

औसत उपयोग-मामले में, मुझे नहीं लगता कि अगर आप Argon2 पर PBKDF2 या इसके विपरीत का चयन करते हैं तो यह सुरक्षा के दृष्टिकोण से कोई फर्क नहीं पड़ता। यदि आपके पास मजबूत सुरक्षा आवश्यकताएं हैं, तो मैं आपके मूल्यांकन में आर्गन 2 पर विचार करने की सलाह देता हूं।

पासवर्ड हैशिंग कार्यों की सुरक्षा पर अधिक जानकारी के लिए देख security.se


@ ज़ाफ मैंने उत्तर को अधिक उद्देश्य के लिए संपादित किया। कृपया ध्यान रखें कि NIST सिफारिश हमेशा सबसे अच्छा विकल्प नहीं हो सकती है ( उदाहरण के लिए यहां देखें ) - बेशक यह किसी भी चीज के लिए सच है जो कहीं और भी अनुशंसित है। इसलिए मुझे लगता है कि यह उत्तर इस प्रश्न का मूल्य प्रदान करता है।
Qw3ry

2

यहाँ आपके पास MD5 हैशिंग और अन्य हैश विधियों के लिए दो लिंक हैं:

Javadoc API: https://docs.oracle.com/javase/1.5.0/docs/api/java/security/MessageDigest.html

ट्यूटोरियल: http://www.twmacinta.com/myjava/fast_md5.php


3
बस यह ध्यान रखें कि पासवर्ड हैशिंग के लिए, धीमा बेहतर है। आपको "महत्वपूर्ण सुदृढ़ीकरण" तकनीक के रूप में हैश फ़ंक्शन के हजारों पुनरावृत्तियों का उपयोग करना चाहिए। इसके अलावा, नमक जरूरी है।
एरिकसन

मैं इस धारणा के तहत था कि एक गुणवत्ता हैशिंग एल्गोरिथ्म के कई पुनरावृत्तियों में एक ही सुरक्षा के बारे में एक ही निर्माण होगा क्योंकि बाइट्स की लंबाई अभी भी एक ही होगी?
क्रिस डुट्रो

@erickson हमलावरों को स्पष्ट रूप से धीमा करना बेहतर होगा।
deamon को

6
प्रमुख सुदृढ़ीकरण के बारे में: लवण पूर्ववर्ती हैश को अनुपयोगी बनाने के लिए मौजूद हैं। लेकिन हमलावरों को शिकार नहीं करना पड़ता है। हमलावर तब तक बस हैश + नमक "मक्खी पर" जब तक वे सही नहीं पाते। लेकिन यदि आप अपनी हैश के लिए हजारों बार पुनरावृति करते हैं तो उन्हें भी ऐसा ही करना होगा। आपका सर्वर 10k पुनरावृत्तियों द्वारा बहुत अधिक प्रभावित नहीं होगा क्योंकि ऐसा अक्सर नहीं होता है। हमलावरों को कंप्यूटिंग शक्ति के 10k गुना की आवश्यकता होगी।
जोकमैन

2
@Simon आज MD5 पासवर्ड हैशिंग के लिए बेकार माना जाता है क्योंकि यह GPU brute Force / Dictionary हमलों का उपयोग करके सेकंड में क्रैक किया जा सकता है। यहाँ देखें: codahale.com/how-to-safely-store-a-password
Eran Medan

1

सभी मानक हैश योजनाओं में, LDAP ssh उपयोग करने के लिए सबसे सुरक्षित है,

http://www.openldap.org/faq/data/cache/347.html

मैं बस वहां निर्दिष्ट एल्गोरिदम का पालन करूंगा और हैश करने के लिए मैसेजडिगस्ट का उपयोग करूंगा।

आपको अपने डेटाबेस में नमक को स्टोर करने की आवश्यकता है जैसा आपने सुझाया था।


1
क्योंकि SSHA हैश फ़ंक्शन को पुनरावृत्त नहीं करता है, यह बहुत तेज़ है। इससे हमलावर अधिक तेज़ी से पासवर्ड आज़मा सकते हैं। बेहतर एल्गोरिदम जैसे Bcrypt, PBBKDF1, और PBKDF2 हमलावरों को उस बिंदु पर धीमा करने के लिए "कुंजी को मजबूत करने" की तकनीक का उपयोग करते हैं जहां एक पासवर्ड को समाप्त होना चाहिए, इससे पहले कि वे 8-अक्षर वाले पासवर्ड स्थान को भी बल दे सकें।
इरिकसन

इन सभी तंत्रों के साथ समस्या यह है कि आपको क्लाइंट का समर्थन नहीं मिलता है। हैशेड पासवर्ड के साथ समस्या यह है कि आप किसी अन्य एल्गोरिदम के साथ पासवर्ड हैशेड का समर्थन नहीं कर सकते हैं। Ssha के साथ, कम से कम सभी LDAP क्लाइंट इसका समर्थन करते हैं।
जेडजेड कोडर

यह "सबसे सुरक्षित" नहीं है यह केवल "बहुत संगत" है। bcrypt / scrypt एक तरह से अधिक गहन स्रोत है।
Eckes

1

2020 तक, उपयोग में सबसे विश्वसनीय और लचीला एल्गोरिथ्म,

किसी भी हार्डवेयर को देखते हुए अपनी ताकत को अनुकूलित करने की सबसे अधिक संभावना है,

है Argon2id या Argon2i

यह एक लक्ष्य हैशिंग समय और उपयोग किए गए हार्डवेयर को देखते हुए अनुकूलित शक्ति मापदंडों को खोजने के लिए आवश्यक अंशांकन उपकरण प्रदान करता है।

  • आर्गन 2 आई मेमोरी लालची हैशिंग में विशिष्ट है
  • Argon2d सीपीयू लालची हैशिंग में विशेषज्ञता प्राप्त है
  • Argon2id दोनों विधियों का उपयोग करें।

मेमोरी लालची हैशिंग क्रैकिंग के लिए GPU के उपयोग के खिलाफ मदद करेगी।

वसंत सुरक्षा / उछालभरी कैसल कार्यान्वयन को अनुकूलित नहीं किया गया है और अपेक्षाकृत सप्ताह दिया गया है जो हमलावर उपयोग कर सकता है। cf: स्प्रिंग डॉक्यूमेंटेशन

वर्तमान में कार्यान्वयन बाउंसी महल का उपयोग करता है जो समानता / अनुकूलन का शोषण नहीं करता है जो पासवर्ड पटाखे करेंगे, इसलिए हमलावर और रक्षक के बीच एक अनावश्यक विषमता है।

जावा के लिए उपयोग में सबसे विश्वसनीय कार्यान्वयन है मम्ममेर ,

एक आवरण जार / आधिकारिक मूल कार्यान्वयन के पुस्तकालय में लिखा गया है।

यह अच्छी तरह से लिखा है और उपयोग करने के लिए सरल है।

एम्बेडेड संस्करण लिनक्स, विंडोज़ और ओएसएक्स के लिए देशी बिल्ड प्रदान करता है।

एक उदाहरण के रूप में, यह अपने में jpmorganchase द्वारा किया जाता है Tessera सुरक्षित करने के लिए इस्तेमाल किया सुरक्षा परियोजना कोरम , अपने Ethereum cryptocurency कार्यान्वयन।

यहाँ tessera से उदाहरण कोड है।

अंशांकन de.mkammerer.argon2.Argon2Helper # findIterations का उपयोग करके किया जा सकता है

SCRYPT और Pbkdf2 एल्गोरिथ्म को कुछ सरल बेंचमार्क लिखकर भी कैलिब्रेट किया जा सकता है, लेकिन वर्तमान न्यूनतम सुरक्षित पुनरावृत्तियों मूल्यों, को उच्च हैशिंग समय की आवश्यकता होगी।


0

मुझे लगता है कि udemy पर एक वीडियो से और मजबूत यादृच्छिक पासवर्ड होने का संपादन किया

}

private String pass() {
        String passswet="1234567890zxcvbbnmasdfghjklop[iuytrtewq@#$%^&*" ;

        char icon1;
        char[] t=new char[20];

         int rand1=(int)(Math.random()*6)+38;//to make a random within the range of special characters

            icon1=passswet.charAt(rand1);//will produce char with a special character

        int i=0;
        while( i <11) {

             int rand=(int)(Math.random()*passswet.length());
             //notice (int) as the original value of Math>random() is double

             t[i] =passswet.charAt(rand);

             i++;
                t[10]=icon1;
//to replace the specified item with icon1
         }
        return new String(t);
}






}

मैं सही होने के लिए खुला हूं, लेकिन मुझे लगता है कि आपको हैशिंग के दौरान यादृच्छिक संख्याओं का उपयोग नहीं करना चाहिए। यह इसलिए है ताकि आपका हैश फ़ंक्शन नियतात्मक हो; यदि आप एक स्ट्रिंग हैश कई बार है कि आप हमेशा उस स्ट्रिंग के लिए एक ही हैश मान वापस मिल जाएगा।
duldi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.