github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/grypto/pass.go (about)

     1  // Copyright 2017-present Kirill Danshin and Gramework contributors
     2  // Copyright 2019-present Highload LTD (UK CN: 11893420)
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  
    11  // Package grypto provides helpers for dealing with cryptography.
    12  package grypto
    13  
    14  import (
    15  	"crypto/subtle"
    16  
    17  	"github.com/gramework/gramework/grypto/salt"
    18  )
    19  
    20  type PasswordCryptoProvider interface {
    21  	HashString(plain string) []byte
    22  	Hash(plain []byte) []byte
    23  	NeedsRehash(hash []byte) bool
    24  	Valid(hash, plain []byte) bool
    25  }
    26  
    27  func matchProvider(hash []byte) PasswordCryptoProvider {
    28  	if len(hash) < 4 {
    29  		return nil
    30  	}
    31  	for key, provider := range registry {
    32  		if len(hash) > len(key)+2 && subtle.ConstantTimeCompare(hash[1:len(key)+1], []byte(key)) == 1 {
    33  			return provider
    34  		}
    35  	}
    36  	return nil
    37  }
    38  
    39  // PasswordHashString returns hash of plain password in the given string
    40  func PasswordHashString(plainPass string) []byte {
    41  	return registry[defaultProvider].HashString(plainPass)
    42  }
    43  
    44  // PasswordHash returns hash of plain password in the given byte slice
    45  func PasswordHash(plainPass []byte) []byte {
    46  	return registry[defaultProvider].Hash(plainPass)
    47  }
    48  
    49  // PasswordNeedsRehash checks if the password should be rehashed as soon as possible
    50  func PasswordNeedsRehash(hash []byte) bool {
    51  	return registry[defaultProvider].NeedsRehash(hash)
    52  }
    53  
    54  // Salt128 generates 128 bits of random data.
    55  func Salt128() []byte {
    56  	return salt.Gen128()
    57  }
    58  
    59  // PasswordValid checks if provided hash
    60  func PasswordValid(hash, password []byte) bool {
    61  	p := matchProvider(hash)
    62  	if p == nil {
    63  		return false
    64  	}
    65  	return p.Valid(hash, password)
    66  }