SHA1 encoding with secret, equivalent to PHP hash_hmac - go

I have the following PHP function
public function encodePassword($raw, $salt)
{
return hash_hmac('sha1', $raw . $salt, $this->secret);
}
which I need to translate to Go. I found the following example, but it doesn't involve secret key.
https://gobyexample.com/sha1-hashes
How can I create a function in Go, that produces exactly same result as PHP's hash_hmac?
Update: After Leo's answer, found this resource with hmac examples in
many languages: https://github.com/danharper/hmac-examples. Can be
useful to somebody.

Something like this:
import "crypto/sha1"
import "crypto/hmac"
func hash_hmac_sha1(password, salt, key []byte) []byte {
h := hmac.New(sha1.New, key)
h.Write(password)
h.Write(salt)
return h.Sum(nil)
}

Like this function:
func decriptSign(message string, key string) string {
h := hmac.New(sha1.New, []byte(key))
h.Write([]byte(message))
return hex.EncodeToString(h.Sum(nil))
}

Related

How to generate the ECDSA public key from its private key?

The following site is frequently referenced and, I assume, accurate:
https://gobittest.appspot.com/Address
I'm trying to repro these steps in Golang but failing at the first step :-(
Is someone able to provide me with a Golang snippet that, given a ECDSA private key, returns the public key? I think I may specifically mean the private key exponent and public key exponent per the above site's examples.
i.e. given e.g. a randomly-generated (hex-encoded) private key (exponent?) E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75 returns the public key 04369D83469A66920F31E4CF3BD92CB0BC20C6E88CE010DFA43E5F08BC49D11DA87970D4703B3ADBC9A140B4AD03A0797A6DE2D377C80C369FE76A0F45A7A39D3F
I've found many (relevant) results:
https://crypto.stackexchange.com/questions/5756/how-to-generate-a-public-key-from-a-private-ecdsa-key
But none that includes a definitive example.
Go's crypto/ecdsa module allows keys to generated and includes a Public function on the type but this returns the PublicKey property.
Alternative ways that start from a private key appear to require going through a PEM-encoded (including a DER-encoded ASN) form of the key which feels circuitous (and I would need to construct).
Update:
See the answers below: andrew-w-phillips# and kelsnare# provided the (same|correct) solution. Thanks to both of them!
For posterity, Bitcoin (and Ethereum) use an elliptic curve defined by secp256k1. The following code from andrew-w-phillips# and kelsnare# using Ethereum's implementation of this curve, works:
import (
"crypto/ecdsa"
"crypto/elliptic"
"fmt"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
)
func Public(privateKey string) (publicKey string) {
var e ecdsa.PrivateKey
e.D, _ = new(big.Int).SetString(privateKey, 16)
e.PublicKey.Curve = secp256k1.S256()
e.PublicKey.X, e.PublicKey.Y = e.PublicKey.Curve.ScalarBaseMult(e.D.Bytes())
return fmt.Sprintf("%x", elliptic.Marshal(secp256k1.S256(), e.X, e.Y))
}
func main() {
privateKey := "E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75"
log.Println(strings.ToUpper(Public(privateKey)))
}
yields:
04369D83469A66920F31E4CF3BD92CB0BC20C6E88CE010DFA43E5F08BC49D11DA87970D4703B3ADBC9A140B4AD03A0797A6DE2D377C80C369FE76A0F45A7A39D3F
After reading the answer by Andrew W. Phillips and a little help from https://github.com/bitherhq/go-bither/tree/release/1.7/crypto
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"fmt"
"log"
"math/big"
)
func PubBytes(pub *ecdsa.PublicKey) []byte {
if pub == nil || pub.X == nil || pub.Y == nil {
return nil
}
return elliptic.Marshal(elliptic.P256(), pub.X, pub.Y)
}
func toECDSAFromHex(hexString string) (*ecdsa.PrivateKey, error) {
pk := new(ecdsa.PrivateKey)
pk.D, _ = new(big.Int).SetString(hexString, 16)
pk.PublicKey.Curve = elliptic.P256()
pk.PublicKey.X, pk.PublicKey.Y = pk.PublicKey.Curve.ScalarBaseMult(pk.D.Bytes())
return pk, nil
}
func main() {
pHex := "E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75"
pk, err := toECDSAFromHex(pHex)
if err != nil {
log.Fatal(err.Error())
}
fmt.Printf("Generated Public Key: %x\n", PubBytes(&pk.PublicKey))
hash := []byte("Hello Gopher!")
fmt.Printf("\nSigning...\n\n")
r, s, err := ecdsa.Sign(rand.Reader, pk, hash)
if err != nil {
log.Fatal(err.Error())
}
fmt.Printf("\nVerifying..\n\n")
if ecdsa.Verify(&pk.PublicKey, hash, r, s) {
fmt.Println("Success!!")
} else {
fmt.Println("Failure!!")
}
}
// Output
// Generated Public Key: 04265a5015c0cfd960e5a41f35e0a87874c1d8a28289d0d6ef6ac521ad49c3d80a8a7019ceef189819f066a947ad5726db1a4fe70a3208954c46b0e60f2bf7809c
//
// Signing...
//
//
// Verifying..
//
// Success!!
======== ORIGINAL ANSWER ===========
Dunno much of crypto but crypto/elliptic has a Marshal function
So once you have a *PrivateKey maybe the below will work
import (
"crypto/elliptic"
"crypto/ecdsa"
)
var privKey *ecdsa.PrivateKey
func main() {
// some init to privKey
pk := privKey.PublicKey()
keybuf := elliptic.Marshal(pk.Curve, pk.X, pk.Y)
log.Printf("Key: %s\n", string(keybuf))
}
I'm shooting completely in the dark with this. Hope it helps
I haven't got that low-level but maybe something like this:
var pri ecdsa.PrivateKey
pri.D, _ = new(big.Int).SetString("E83385AF76B2B1997326B567461FB73DD9C27EAB9E1E86D26779F4650C5F2B75",16)
pri.PublicKey.Curve = elliptic.P256()
pri.PublicKey.X, pri.PublicKey.Y = pri.PublicKey.Curve.ScalarBaseMult(pri.D.Bytes())

Casting a string to a func type in GoLang

I have a string which is the name of a function in GoLang.
I want to treat them as function. How should I do this? I tried to achieve it through reflect.* but I didn't find a valid path for my purpose.
I get the name fo handlers in a JSON file, and I want to execute those handlers. Something like this:
{
"students/show" : "ShowStudents",
"students/add" : "AddStudents"
}
Then I want to execute ShowStudents(), but don't know how to treat it like a variable of type func
Your task can be broken down into two steps:
Extract function names
Run those functions (assuming that they are defined somewhere)
For step 1, I would unmarshal the JSON into a map[string]string, something like this:
b, err := ioutil.ReadFile(fname)
mp := make(map[string]string)
json.Unmarshal(b, &mp)
Coming to Step 2. In Go, it's not possible to convert string directly to a function call, but it is possible to enumerate the methods of an object using reflect package. This can be used as a workaround in this case. Instead of writing those functions directly, bind them to a dummy type, something like this:
type T int
func (t T) ShowStudents() {
fmt.Println("Showing Students")
}
func (t T) AddStudents() {
fmt.Println("Adding Students")
}
func main() {
var t T
reflect.ValueOf(t).MethodByName("ShowStudents").Call(nil)
}
Run this example
establish a mapping between the keys in the json file and the functions, then use that to call the functions as they appear in the json
package main
import (
"encoding/json"
"fmt"
)
func AddStudents() {
fmt.Println("woo")
}
func ShowStudents() {
fmt.Println("lots of students")
}
func main() {
js := `{
"students/show" : "ShowStudents",
"students/add" : "AddStudents"
}`
lookup := make(map[string]string)
json.Unmarshal([]byte(js), &lookup)
dispatch := make(map[string]func())
dispatch["students/show"] = ShowStudents
dispatch["students/add"] = AddStudents
for v, _ := range lookup {
print(v)
dispatch[v]()
}
}

Can I make an optional return value in golang? [duplicate]

In Go, the following works (note one use of the map has one return, the other has two returns)
package main
import "fmt"
var someMap = map[string]string { "some key": "hello" }
func main() {
if value, ok := someMap["some key"]; ok {
fmt.Println(value)
}
value := someMap["some key"]
fmt.Println(value)
}
However, I have no idea how to do this same thing with my own function. Is it possible to have similar behavior with an optional return like map?
For example:
package main
import "fmt"
func Hello() (string, bool) {
return "hello", true
}
func main() {
if value, ok := Hello(); ok {
fmt.Println(value)
}
value := Hello()
fmt.Println(value)
}
Wont compile (due to the error multiple-value Hello() in single-value context) ... is there a way to make this syntax work for the function Hello()?
map is different because it is a built-in type and not a function. The 2 forms of accessing an element of a map is specified by the Go Language Specification: Index Expressions and backed by the compiler.
With functions you can't do this. If a function has 2 return values, you have to "expect" both of them or none at all.
However you are allowed to assign any of the return values to the Blank identifier:
s, b := Hello() // Storing both of the return values
s2, _ := Hello() // Storing only the first
_, b3 := Hello() // Storing only the second
You can also choose not to store any of the return values:
Hello() // Just executing it, but storing none of the return values
Note: you could also assign both of the return values to the blank identifier, although it has no use (other than validating that it has exactly 2 return values):
_, _ = Hello() // Storing none of the return values; note the = instead of :=
You can also try these on the Go Playground.
Helper function
If you use it many times and you don't want to use the blank identifier, create a helper function which discards the 2nd return value:
func Hello2() string {
s, _ := Hello()
return s
}
And now you can do:
value := Hello2()
fmt.Println(value)
Go 1.18 generics update: Go 1.18 adds generics support, it is now possible to write a generic First() function which discards the second (or any further) return values:
func First[T any](first T, _ ...any) T {
return first
}
This is available in github.com/icza/gog, as gog.First() (disclosure: I'm the author).
Using it:
value := First(Hello())
fmt.Println(value)
In addition to the explanation of #icza:
I don't recommend using a helper function there. Especially if the Hello function is your own function.
However, if you can't control it, then it's fine to use a helper.
If it's your own function, it's better to change the signature of your function. Probably, you made a design mistake somewhere.
You can also do this:
package main
import "fmt"
func Hello() (string, bool) {
return "hello", true
}
func main() {
// Just move it one line above: don't use a short-if
value, ok := Hello()
if ok {
fmt.Println(value)
}
}

Return map like 'ok' in Golang on normal functions

In Go, the following works (note one use of the map has one return, the other has two returns)
package main
import "fmt"
var someMap = map[string]string { "some key": "hello" }
func main() {
if value, ok := someMap["some key"]; ok {
fmt.Println(value)
}
value := someMap["some key"]
fmt.Println(value)
}
However, I have no idea how to do this same thing with my own function. Is it possible to have similar behavior with an optional return like map?
For example:
package main
import "fmt"
func Hello() (string, bool) {
return "hello", true
}
func main() {
if value, ok := Hello(); ok {
fmt.Println(value)
}
value := Hello()
fmt.Println(value)
}
Wont compile (due to the error multiple-value Hello() in single-value context) ... is there a way to make this syntax work for the function Hello()?
map is different because it is a built-in type and not a function. The 2 forms of accessing an element of a map is specified by the Go Language Specification: Index Expressions and backed by the compiler.
With functions you can't do this. If a function has 2 return values, you have to "expect" both of them or none at all.
However you are allowed to assign any of the return values to the Blank identifier:
s, b := Hello() // Storing both of the return values
s2, _ := Hello() // Storing only the first
_, b3 := Hello() // Storing only the second
You can also choose not to store any of the return values:
Hello() // Just executing it, but storing none of the return values
Note: you could also assign both of the return values to the blank identifier, although it has no use (other than validating that it has exactly 2 return values):
_, _ = Hello() // Storing none of the return values; note the = instead of :=
You can also try these on the Go Playground.
Helper function
If you use it many times and you don't want to use the blank identifier, create a helper function which discards the 2nd return value:
func Hello2() string {
s, _ := Hello()
return s
}
And now you can do:
value := Hello2()
fmt.Println(value)
Go 1.18 generics update: Go 1.18 adds generics support, it is now possible to write a generic First() function which discards the second (or any further) return values:
func First[T any](first T, _ ...any) T {
return first
}
This is available in github.com/icza/gog, as gog.First() (disclosure: I'm the author).
Using it:
value := First(Hello())
fmt.Println(value)
In addition to the explanation of #icza:
I don't recommend using a helper function there. Especially if the Hello function is your own function.
However, if you can't control it, then it's fine to use a helper.
If it's your own function, it's better to change the signature of your function. Probably, you made a design mistake somewhere.
You can also do this:
package main
import "fmt"
func Hello() (string, bool) {
return "hello", true
}
func main() {
// Just move it one line above: don't use a short-if
value, ok := Hello()
if ok {
fmt.Println(value)
}
}

How to validate UUID v4 in Go?

I have the following piece of code:
func GetUUIDValidator(text string) bool {
r, _ := regexp.Compile("/[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12}/")
return r.Match([]byte(text))
}
But when I pass fbd3036f-0f1c-4e98-b71c-d4cd61213f90 as a value, I got false, while indeed it is an UUID v4.
What am I doing wrong?
Regex is expensive. The following approach is ~18x times faster than the regex version.
Use something like https://godoc.org/github.com/google/uuid#Parse instead.
import "github.com/google/uuid"
func IsValidUUID(u string) bool {
_, err := uuid.Parse(u)
return err == nil
}
Try with...
func IsValidUUID(uuid string) bool {
r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
return r.MatchString(uuid)
}
Live example: https://play.golang.org/p/a4Z-Jn4EvG
Note: as others have said, validating UUIDs with regular expressions can be slow. Consider other options too if you need better performance.
You can utilize satori/go.uuid package to accomplish this:
import "github.com/satori/go.uuid"
func IsValidUUID(u string) bool {
_, err := uuid.FromString(u)
return err == nil
}
This package is widely used for UUID operations: https://github.com/satori/go.uuid
In case you would be validating it as attribute of a struct, there is an awesome golang library straight from the Go called validator https://godoc.org/gopkg.in/go-playground/validator.v9 which you can use to validate all kinds of fields nested structures by provided built-in validators as well as complete custom validation methods. All you need to do is just add proper tags to the fields
import "gopkg.in/go-playground/validator.v9"
type myObject struct {
UID string `validate:"required,uuid4"`
}
func validate(obj *myObject) {
validate := validator.New()
err := validate.Struct(obj)
}
It provides structured field errors and other relevant data from it.

Resources