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
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())
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]()
}
}
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)
}
}
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)
}
}
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.