...

Source file src/edge-infra.dev/pkg/lib/crypto/pbkdf2.go

Documentation: edge-infra.dev/pkg/lib/crypto

     1  package crypto
     2  
     3  import (
     4  	"crypto/sha512"
     5  	"encoding/hex"
     6  
     7  	"github.com/xdg-go/pbkdf2"
     8  
     9  	"edge-infra.dev/pkg/lib/crypto/randomizer"
    10  	"edge-infra.dev/pkg/lib/crypto/validation"
    11  )
    12  
    13  type pbkdf2Credential struct {
    14  	plainTextPwd string
    15  	hashedPwd    []byte
    16  	iterations   int
    17  	salt         []byte
    18  }
    19  
    20  func (pwd pbkdf2Credential) Salt() ([]byte, error) {
    21  	return pwd.salt, nil
    22  }
    23  
    24  func (pwd pbkdf2Credential) Iterations() (int, error) {
    25  	return pwd.iterations, nil
    26  }
    27  
    28  func (pwd pbkdf2Credential) HashFunction() string {
    29  	return string(pbkdf2Type)
    30  }
    31  
    32  func (pwd pbkdf2Credential) HashType() string {
    33  	return pbkdf2Type.Type()
    34  }
    35  
    36  func (pwd pbkdf2Credential) Hashed() []byte {
    37  	return pwd.hashedPwd
    38  }
    39  
    40  func (pwd pbkdf2Credential) Plain() string {
    41  	return pwd.plainTextPwd
    42  }
    43  
    44  // Generates a random hashed password using pdkdf2
    45  func GenerateRandomPbkdf2Password(minLength, maxLength, iterations, saltLength, keyLength int) (Credential, error) {
    46  	if err := validation.ValidatePwdBounds(minLength, maxLength); err != nil {
    47  		return nil, err
    48  	}
    49  
    50  	pwdLen, err := randomizer.RandomPassLength(minLength, maxLength)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  
    55  	if err := validation.ValidateSaltLength(saltLength); err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	if err := validation.ValidateIterationLen(iterations); err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	if err = validation.ValidateKeyLen(keyLength, saltLength); err != nil {
    64  		return nil, err
    65  	}
    66  
    67  	pwd, err := randomizer.GenerateRandomPlainPwd(pwdLen)
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  
    72  	salt, err := randomizer.GenerateRandomSalt(saltLength)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	hashedPwd := hashPbkdf2([]byte(pwd), []byte(salt), iterations, keyLength)
    78  	return pbkdf2Credential{plainTextPwd: pwd, hashedPwd: hashedPwd, iterations: iterations, salt: []byte(salt)}, nil
    79  }
    80  
    81  func GeneratePbkdf2Password(pwd string, iterations, saltLength, keyLength int) (Credential, error) {
    82  	if err := validation.ValidatePwdLen(len(pwd)); err != nil {
    83  		return nil, err
    84  	}
    85  
    86  	if err := validation.ValidateSaltLength(saltLength); err != nil {
    87  		return nil, err
    88  	}
    89  
    90  	if err := validation.ValidateIterationLen(iterations); err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	if err := validation.ValidateKeyLen(keyLength, saltLength); err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	salt, err := randomizer.GenerateRandomSalt(saltLength)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	hashedPwd := hashPbkdf2([]byte(pwd), []byte(salt), iterations, keyLength)
   104  	return pbkdf2Credential{plainTextPwd: pwd, hashedPwd: hashedPwd, iterations: iterations, salt: []byte(salt)}, nil
   105  }
   106  
   107  func hashPbkdf2(pwd, salt []byte, iterations, keyLength int) []byte {
   108  	return pbkdf2.Key(pwd, salt, iterations, keyLength, sha512.New)
   109  }
   110  
   111  func ComparePbkdf2HashAndPassword(hash, salt []byte, pwd string, iterations, keyLength int) bool {
   112  	pwdHash := hashPbkdf2([]byte(pwd), salt, iterations, keyLength)
   113  	return hex.EncodeToString(pwdHash) == hex.EncodeToString(hash)
   114  }
   115  

View as plain text