upd: essential/file updated
helper hash updated
This commit is contained in:
parent
6ce02e92b8
commit
c1172749b4
@ -0,0 +1,396 @@
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Description
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Name:
|
||||
| - Hash
|
||||
|
|
||||
| Purpose:
|
||||
| - Generate and verify cryptographic hash values using standard or
|
||||
| salted hashing methods for integrity verification, canonical
|
||||
| fingerprinting, resource identification, comparison workflows,
|
||||
| and security-oriented hashing requirements.
|
||||
|
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Instruction
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Guideline:
|
||||
| - Use to generate deterministic hashes in standard mode.
|
||||
| - Use to generate salted hashes when salted hashing is required.
|
||||
| - Use to verify supplied hash values against input values.
|
||||
| - Use standard mode when deterministic hashing without a salt is
|
||||
| required.
|
||||
| - Use salted mode when a supplied or cryptographically secure
|
||||
| generated salt is required.
|
||||
|
|
||||
| Example:
|
||||
| - ObrimHash("calculate", map[string]any{
|
||||
| "mode": "standard",
|
||||
| "algorithm": "...",
|
||||
| "value": "...",
|
||||
| })
|
||||
|
|
||||
| - ObrimHash("calculate", map[string]any{
|
||||
| "mode": "salted",
|
||||
| "algorithm": "...",
|
||||
| "value": "...",
|
||||
| "salt": "...",
|
||||
| })
|
||||
|
|
||||
| - ObrimHash("compare", map[string]any{
|
||||
| "mode": "standard",
|
||||
| "algorithm": "...",
|
||||
| "value": "...",
|
||||
| "hash": "...",
|
||||
| })
|
||||
|
|
||||
| - ObrimHash("compare", map[string]any{
|
||||
| "mode": "salted",
|
||||
| "algorithm": "...",
|
||||
| "value": "...",
|
||||
| "hash": "...",
|
||||
| "salt": "...",
|
||||
| })
|
||||
|
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Credit
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Contributor:
|
||||
| - Rajon Ahmed
|
||||
| - Blockonite
|
||||
|
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
package hash
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// Hash result codes.
|
||||
const (
|
||||
ObrimHashSuccessCalculated = "SUCCESS_CALCULATED"
|
||||
ObrimHashSuccessCompared = "SUCCESS_COMPARED"
|
||||
ObrimHashFailureInvalidType = "FAILURE_INVALID_TYPE"
|
||||
ObrimHashFailureInvalidConfig = "FAILURE_INVALID_CONFIG"
|
||||
ObrimHashFailureInvalidMode = "FAILURE_INVALID_MODE"
|
||||
ObrimHashFailureInvalidAlgorithm = "FAILURE_INVALID_ALGORITHM"
|
||||
ObrimHashFailureInvalidValue = "FAILURE_INVALID_VALUE"
|
||||
ObrimHashFailureInvalidHash = "FAILURE_INVALID_HASH"
|
||||
ObrimHashFailureInvalidSalt = "FAILURE_INVALID_SALT"
|
||||
ObrimHashFailureProcessing = "FAILURE_PROCESSING"
|
||||
)
|
||||
|
||||
// Hash utility modes.
|
||||
const (
|
||||
obrimHashModeStandard = "standard"
|
||||
obrimHashModeSalted = "salted"
|
||||
)
|
||||
|
||||
// Hash utility algorithms.
|
||||
const (
|
||||
obrimHashAlgorithmSHA256 = "sha256"
|
||||
obrimHashAlgorithmSHA512 = "sha512"
|
||||
)
|
||||
|
||||
// Hash utility configuration keys.
|
||||
const (
|
||||
obrimHashConfigMode = "mode"
|
||||
obrimHashConfigAlgorithm = "algorithm"
|
||||
obrimHashConfigValue = "value"
|
||||
obrimHashConfigHash = "hash"
|
||||
obrimHashConfigSalt = "salt"
|
||||
)
|
||||
|
||||
// Hash utility operation types.
|
||||
const (
|
||||
obrimHashTypeCalculate = "calculate"
|
||||
obrimHashTypeCompare = "compare"
|
||||
)
|
||||
|
||||
// Hash utility output structure.
|
||||
type obrimHashOutput struct {
|
||||
Status bool `json:"status"`
|
||||
Code string `json:"code"`
|
||||
Payload map[string]any `json:"payload"`
|
||||
}
|
||||
|
||||
// Hash utility request configuration.
|
||||
type obrimHashConfig struct {
|
||||
Mode string
|
||||
Algorithm string
|
||||
Value string
|
||||
Hash string
|
||||
Salt string
|
||||
}
|
||||
|
||||
// Hash utility execution function.
|
||||
func ObrimHash(Type string, Config map[string]any) map[string]any {
|
||||
ConfigData, Code := obrimHashValidateInput(Type, Config)
|
||||
if Code != "" {
|
||||
return obrimHashBuildOutput(false, Code, nil)
|
||||
}
|
||||
|
||||
return obrimHashRouteRequest(Type, ConfigData)
|
||||
}
|
||||
|
||||
// Validate hash utility input.
|
||||
func obrimHashValidateInput(Type string, Config map[string]any) (obrimHashConfig, string) {
|
||||
var ConfigData obrimHashConfig
|
||||
|
||||
switch Type {
|
||||
case obrimHashTypeCalculate, obrimHashTypeCompare:
|
||||
default:
|
||||
return ConfigData, ObrimHashFailureInvalidType
|
||||
}
|
||||
|
||||
if Config == nil {
|
||||
return ConfigData, ObrimHashFailureInvalidConfig
|
||||
}
|
||||
|
||||
ConfigData.Mode = obrimHashReadStringConfig(Config, obrimHashConfigMode)
|
||||
ConfigData.Algorithm = obrimHashReadStringConfig(Config, obrimHashConfigAlgorithm)
|
||||
ConfigData.Value = obrimHashReadStringConfig(Config, obrimHashConfigValue)
|
||||
ConfigData.Hash = obrimHashReadStringConfig(Config, obrimHashConfigHash)
|
||||
ConfigData.Salt = obrimHashReadStringConfig(Config, obrimHashConfigSalt)
|
||||
|
||||
switch ConfigData.Mode {
|
||||
case obrimHashModeStandard, obrimHashModeSalted:
|
||||
default:
|
||||
return ConfigData, ObrimHashFailureInvalidMode
|
||||
}
|
||||
|
||||
switch ConfigData.Algorithm {
|
||||
case obrimHashAlgorithmSHA256, obrimHashAlgorithmSHA512:
|
||||
default:
|
||||
return ConfigData, ObrimHashFailureInvalidAlgorithm
|
||||
}
|
||||
|
||||
if ConfigData.Value == "" {
|
||||
return ConfigData, ObrimHashFailureInvalidValue
|
||||
}
|
||||
|
||||
switch Type {
|
||||
case obrimHashTypeCalculate:
|
||||
if ConfigData.Mode == obrimHashModeStandard && ConfigData.Salt != "" {
|
||||
return ConfigData, ObrimHashFailureInvalidSalt
|
||||
}
|
||||
case obrimHashTypeCompare:
|
||||
if ConfigData.Hash == "" {
|
||||
return ConfigData, ObrimHashFailureInvalidHash
|
||||
}
|
||||
|
||||
switch ConfigData.Mode {
|
||||
case obrimHashModeStandard:
|
||||
if ConfigData.Salt != "" {
|
||||
return ConfigData, ObrimHashFailureInvalidSalt
|
||||
}
|
||||
case obrimHashModeSalted:
|
||||
if ConfigData.Salt == "" {
|
||||
return ConfigData, ObrimHashFailureInvalidSalt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ConfigData, ""
|
||||
}
|
||||
|
||||
// Route the hash utility request.
|
||||
func obrimHashRouteRequest(Type string, Config obrimHashConfig) map[string]any {
|
||||
switch Type {
|
||||
case obrimHashTypeCalculate:
|
||||
return obrimHashCalculate(Config)
|
||||
case obrimHashTypeCompare:
|
||||
return obrimHashCompare(Config)
|
||||
default:
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureInvalidType, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Build standardized hash utility output.
|
||||
func obrimHashBuildOutput(Status bool, Code string, Payload map[string]any) map[string]any {
|
||||
Output := obrimHashOutput{
|
||||
Status: Status,
|
||||
Code: Code,
|
||||
Payload: Payload,
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"status": Output.Status,
|
||||
"code": Output.Code,
|
||||
"payload": Output.Payload,
|
||||
}
|
||||
}
|
||||
|
||||
// Process hash generation.
|
||||
func obrimHashCalculate(Config obrimHashConfig) map[string]any {
|
||||
switch Config.Mode {
|
||||
case obrimHashModeStandard:
|
||||
return obrimHashCalculateStandard(Config)
|
||||
case obrimHashModeSalted:
|
||||
return obrimHashCalculateSalted(Config)
|
||||
default:
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureInvalidMode, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate deterministic standard hash.
|
||||
func obrimHashCalculateStandard(Config obrimHashConfig) map[string]any {
|
||||
HashValue, Error := obrimHashGenerate(Config.Algorithm, Config.Value)
|
||||
if Error != nil {
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureProcessing, nil)
|
||||
}
|
||||
|
||||
Payload := map[string]any{
|
||||
"algorithm": Config.Algorithm,
|
||||
"hash": HashValue,
|
||||
}
|
||||
|
||||
return obrimHashBuildOutput(true, ObrimHashSuccessCalculated, Payload)
|
||||
}
|
||||
|
||||
// Generate salted hash.
|
||||
func obrimHashCalculateSalted(Config obrimHashConfig) map[string]any {
|
||||
Salt := Config.Salt
|
||||
|
||||
if Salt == "" {
|
||||
var Error error
|
||||
|
||||
Salt, Error = obrimHashGenerateSalt()
|
||||
if Error != nil {
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureProcessing, nil)
|
||||
}
|
||||
}
|
||||
|
||||
HashValue, Error := obrimHashGenerate(Config.Algorithm, Salt+Config.Value)
|
||||
if Error != nil {
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureProcessing, nil)
|
||||
}
|
||||
|
||||
Payload := map[string]any{
|
||||
"algorithm": Config.Algorithm,
|
||||
"hash": HashValue,
|
||||
"salt": Salt,
|
||||
}
|
||||
|
||||
return obrimHashBuildOutput(true, ObrimHashSuccessCalculated, Payload)
|
||||
}
|
||||
|
||||
// Generate a cryptographically secure random salt.
|
||||
func obrimHashGenerateSalt() (string, error) {
|
||||
Salt := make([]byte, 32)
|
||||
|
||||
if _, Error := rand.Read(Salt); Error != nil {
|
||||
return "", Error
|
||||
}
|
||||
|
||||
return hex.EncodeToString(Salt), nil
|
||||
}
|
||||
|
||||
// Process hash verification.
|
||||
func obrimHashCompare(Config obrimHashConfig) map[string]any {
|
||||
switch Config.Mode {
|
||||
case obrimHashModeStandard:
|
||||
return obrimHashCompareStandard(Config)
|
||||
case obrimHashModeSalted:
|
||||
return obrimHashCompareSalted(Config)
|
||||
default:
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureInvalidMode, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify standard hash.
|
||||
func obrimHashCompareStandard(Config obrimHashConfig) map[string]any {
|
||||
HashValue, Error := obrimHashGenerate(Config.Algorithm, Config.Value)
|
||||
if Error != nil {
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureProcessing, nil)
|
||||
}
|
||||
|
||||
Matched := obrimHashVerify(HashValue, Config.Hash)
|
||||
|
||||
Payload := map[string]any{
|
||||
"algorithm": Config.Algorithm,
|
||||
"matched": Matched,
|
||||
"hash": Config.Hash,
|
||||
}
|
||||
|
||||
return obrimHashBuildOutput(true, ObrimHashSuccessCompared, Payload)
|
||||
}
|
||||
|
||||
// Verify salted hash.
|
||||
func obrimHashCompareSalted(Config obrimHashConfig) map[string]any {
|
||||
HashValue, Error := obrimHashGenerate(Config.Algorithm, Config.Salt+Config.Value)
|
||||
if Error != nil {
|
||||
return obrimHashBuildOutput(false, ObrimHashFailureProcessing, nil)
|
||||
}
|
||||
|
||||
Matched := obrimHashVerify(HashValue, Config.Hash)
|
||||
|
||||
Payload := map[string]any{
|
||||
"algorithm": Config.Algorithm,
|
||||
"matched": Matched,
|
||||
"hash": Config.Hash,
|
||||
"salt": Config.Salt,
|
||||
}
|
||||
|
||||
return obrimHashBuildOutput(true, ObrimHashSuccessCompared, Payload)
|
||||
}
|
||||
|
||||
// Verify regenerated and supplied hashes using strict byte comparison.
|
||||
func obrimHashVerify(Expected string, Supplied string) bool {
|
||||
return string([]byte(Expected)) == string([]byte(Supplied))
|
||||
}
|
||||
|
||||
// Generate a hash using the selected algorithm.
|
||||
func obrimHashGenerate(Algorithm string, Value string) (string, error) {
|
||||
var HashFunction func() hash.Hash
|
||||
|
||||
switch Algorithm {
|
||||
case obrimHashAlgorithmSHA256:
|
||||
HashFunction = sha256.New
|
||||
case obrimHashAlgorithmSHA512:
|
||||
HashFunction = sha512.New
|
||||
default:
|
||||
return "", errors.New("unsupported hashing algorithm")
|
||||
}
|
||||
|
||||
Hasher := HashFunction()
|
||||
|
||||
if _, Error := Hasher.Write([]byte(Value)); Error != nil {
|
||||
return "", Error
|
||||
}
|
||||
|
||||
return hex.EncodeToString(Hasher.Sum(nil)), nil
|
||||
}
|
||||
|
||||
// Read a string configuration value.
|
||||
func obrimHashReadStringConfig(Config map[string]any, Key string) string {
|
||||
Value, Exists := Config[Key]
|
||||
if !Exists || Value == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
StringValue, Valid := Value.(string)
|
||||
if !Valid {
|
||||
return ""
|
||||
}
|
||||
|
||||
return StringValue
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user