working commit
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package auxpwd
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var rnd *rand.Rand
|
||||
|
||||
const (
|
||||
sha256Prefix = "sha256pwd"
|
||||
sha512Prefix = "sha512pwd"
|
||||
saltSize = 16
|
||||
)
|
||||
|
||||
func init() {
|
||||
src := rand.NewSource(time.Now().UnixNano())
|
||||
rnd = rand.New(src)
|
||||
}
|
||||
|
||||
func MakeSHA256Hash(passwd []byte) string {
|
||||
var res string
|
||||
salt := hex.EncodeToString(randomBytes(saltSize))
|
||||
passwdString := hex.EncodeToString(passwd)
|
||||
passwdString = fmt.Sprintf("%s%s", passwdString, salt)
|
||||
|
||||
hasher := sha256.New()
|
||||
hasher.Write([]byte(passwdString))
|
||||
checksum := hex.EncodeToString(hasher.Sum(nil))
|
||||
|
||||
res = fmt.Sprintf("%s:%s:%s", sha256Prefix, salt, checksum)
|
||||
return res
|
||||
}
|
||||
|
||||
func MakeSHA512Hash(passwd []byte) string {
|
||||
var res string
|
||||
salt := hex.EncodeToString(randomBytes(saltSize))
|
||||
passwdString := hex.EncodeToString(passwd)
|
||||
passwdString = fmt.Sprintf("%s%s", passwdString, salt)
|
||||
|
||||
hasher := sha512.New()
|
||||
hasher.Write([]byte(passwdString))
|
||||
checksum := hex.EncodeToString(hasher.Sum(nil))
|
||||
|
||||
res = fmt.Sprintf("%s:%s:%s", sha512Prefix, salt, checksum)
|
||||
return res
|
||||
}
|
||||
|
||||
func PasswordMatch(passwd []byte, hash string) bool {
|
||||
hashComponents := strings.Split(hash, ":")
|
||||
if len(hashComponents) != 3 {
|
||||
return false
|
||||
}
|
||||
method := hashComponents[0]
|
||||
salt := hashComponents[1]
|
||||
controlChecksum := hashComponents[2]
|
||||
|
||||
switch method {
|
||||
case sha256Prefix:
|
||||
passwdString := hex.EncodeToString(passwd)
|
||||
passwdString = fmt.Sprintf("%s%s", passwdString, salt)
|
||||
hasher := sha256.New()
|
||||
hasher.Write([]byte(passwdString))
|
||||
checksum := hex.EncodeToString(hasher.Sum(nil))
|
||||
if checksum != controlChecksum {
|
||||
return false
|
||||
}
|
||||
case sha512Prefix:
|
||||
passwdString := hex.EncodeToString(passwd)
|
||||
passwdString = fmt.Sprintf("%s%s", passwdString, salt)
|
||||
hasher := sha512.New()
|
||||
hasher.Write([]byte(passwdString))
|
||||
checksum := hex.EncodeToString(hasher.Sum(nil))
|
||||
if checksum != controlChecksum {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func randomString(n int) string {
|
||||
const letters = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
arr := make([]byte, n)
|
||||
lettersArrayLen := len(letters)
|
||||
for i := range arr {
|
||||
arr[i] = letters[rnd.Intn(lettersArrayLen)]
|
||||
}
|
||||
return string(arr)
|
||||
}
|
||||
|
||||
func randomBytes(n int) []byte {
|
||||
arr := make([]byte, n)
|
||||
for i := range arr {
|
||||
arr[i] = byte(rnd.Intn(256) & 0xFF)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2026 Oleg Borodin <onborodin@gmail.com>
|
||||
*
|
||||
* This work is published and licensed under a Creative Commons
|
||||
* Attribution-NonCommercial-NoDerivatives 4.0 International License.
|
||||
*
|
||||
* Distribution of this work is permitted, but commercial use and
|
||||
* modifications are strictly prohibited.
|
||||
*/
|
||||
package auxpwd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPasswd256(t *testing.T) {
|
||||
password := []byte("123456789")
|
||||
wrongPasswd := []byte("qwerty")
|
||||
|
||||
hash := MakeSHA256Hash(password)
|
||||
fmt.Printf("%s\n", hash)
|
||||
{
|
||||
match := PasswordMatch(password, hash)
|
||||
require.Equal(t, true, match)
|
||||
}
|
||||
{
|
||||
match := PasswordMatch(wrongPasswd, hash)
|
||||
require.NotEqual(t, true, match)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPasswd512(t *testing.T) {
|
||||
password := []byte("123456781")
|
||||
wrongPasswd := []byte("qwerty")
|
||||
|
||||
hash := MakeSHA512Hash(password)
|
||||
fmt.Printf("%s\n", hash)
|
||||
{
|
||||
match := PasswordMatch(password, hash)
|
||||
require.Equal(t, true, match)
|
||||
}
|
||||
{
|
||||
match := PasswordMatch(wrongPasswd, hash)
|
||||
require.NotEqual(t, true, match)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user