func GetHMAC(hashType int, input, key []byte) []byte { var hash func() hash.Hash switch hashType { case HASH_SHA1: { hash = sha1.New } case HASH_SHA256: { hash = sha256.New } case HASH_SHA512: { hash = sha512.New } case HASH_SHA512_384: { hash = sha512.New384 } } hmac := hmac.New(hash, []byte(key)) hmac.Write(input) return hmac.Sum(nil) }
// Creates a new master extended key from a seed func NewMasterKey(seed []byte) (*Key, error) { // Generate key and chaincode hmac := hmac.New(sha512.New, []byte("Bitcoin seed")) hmac.Write([]byte(seed)) intermediary := hmac.Sum(nil) // Split it into our key and chain code keyBytes := intermediary[:32] chainCode := intermediary[32:] // Validate key err := validatePrivateKey(keyBytes) if err != nil { return nil, err } // Create the key struct key := &Key{ Version: PrivateWalletVersion, ChainCode: chainCode, Key: keyBytes, Depth: 0x0, ChildNumber: []byte{0x00, 0x00, 0x00, 0x00}, FingerPrint: []byte{0x00, 0x00, 0x00, 0x00}, IsPrivate: true, } return key, nil }
// Derives a child key from a given parent as outlined by bip32 func (key *Key) NewChildKey(childIdx uint32) (*Key, error) { hardenedChild := childIdx >= FirstHardenedChild childIndexBytes := uint32Bytes(childIdx) // Fail early if trying to create hardned child from public key if !key.IsPrivate && hardenedChild { return nil, errors.New("Can't create hardened child for public key") } // Get intermediary to create key and chaincode from // Hardened children are based on the private key // NonHardened children are based on the public key var data []byte if hardenedChild { data = append([]byte{0x0}, key.Key...) } else { data = publicKeyForPrivateKey(key.Key) } data = append(data, childIndexBytes...) hmac := hmac.New(sha512.New, key.ChainCode) hmac.Write(data) intermediary := hmac.Sum(nil) // Create child Key with data common to all both scenarios childKey := &Key{ ChildNumber: childIndexBytes, ChainCode: intermediary[32:], Depth: key.Depth + 1, IsPrivate: key.IsPrivate, } // Bip32 CKDpriv if key.IsPrivate { childKey.Version = PrivateWalletVersion childKey.FingerPrint = hash160(publicKeyForPrivateKey(key.Key))[:4] childKey.Key = addPrivateKeys(intermediary[:32], key.Key) // Validate key err := validatePrivateKey(childKey.Key) if err != nil { return nil, err } // Bip32 CKDpub } else { keyBytes := publicKeyForPrivateKey(intermediary[:32]) // Validate key err := validateChildPublicKey(keyBytes) if err != nil { return nil, err } childKey.Version = PublicWalletVersion childKey.FingerPrint = hash160(key.Key)[:4] childKey.Key = addPublicKeys(keyBytes, key.Key) } return childKey, nil }
func GetIronValue(name, value string, key []byte, timestamped bool) (val string, ok bool) { split := strings.SplitN(value, ":", 2) if len(split) != 2 { return } expected, value := []byte(split[0]), split[1] message := fmt.Sprintf("%s|%s", strings.Replace(name, "|", `\|`, -1), value) hmac := ironHMAC(key) hmac.Write([]byte(message)) digest := hmac.Sum() mac := make([]byte, base64.URLEncoding.EncodedLen(len(digest))) base64.URLEncoding.Encode(mac, digest) if subtle.ConstantTimeCompare(mac, expected) != 1 { return } if timestamped { split = strings.SplitN(value, ":", 2) if len(split) != 2 { return } timestring, val := split[0], split[1] timestamp, err := strconv.Atoi64(timestring) if err != nil { return } if time.Seconds() > timestamp { return } return val, true } return value, true }
// hkdfExpand implements HKDF-Expand from RFC 5869. func hkdfExpand(hash func() hash.Hash, prk, info []byte, length int) []byte { hashSize := hash().Size() if length > 255*hashSize { panic("hkdfExpand: length too long") } if len(prk) < hashSize { panic("hkdfExpand: prk too short") } var lastBlock []byte counter := byte(0) okm := make([]byte, length) hmac := hmac.New(hash, prk) for length > 0 { hmac.Reset() counter++ hmac.Write(lastBlock) hmac.Write(info) hmac.Write([]byte{counter}) block := hmac.Sum(nil) lastBlock = block copy(okm[(int(counter)-1)*hashSize:], block) length -= hashSize } return okm }
// Generates an OAuth signature using signatureBase // and secret keys func (t *Twitter) generateOAuthSignature(signatureBase string) string { signingKey := fmt.Sprintf("%s&%s", t.ConsumerSecret, t.OAuthTokenSecret) hmac := hmac.New(sha1.New, []byte(signingKey)) hmac.Write([]byte(signatureBase)) return base64.StdEncoding.EncodeToString(hmac.Sum(nil)) }
// Returns the signature to be used in the query string or Authorization header func Signature(secret, toSign string) string { // Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( YourSecretAccessKeyID, StringToSign ) ) ); // Need to confirm what encoding go strings are when converted to []byte hmac := hmac.NewSHA1([]byte(secret)) hmac.Write([]byte(toSign)) return base64.StdEncoding.EncodeToString(hmac.Sum()) }
func signHMAC(key []byte, data string) ([]byte, error) { hmac := hmac.New(sha256.New, []byte(key)) _, err := hmac.Write([]byte(data)) if err != nil { return nil, err } return hmac.Sum(nil), nil }
// hkdfExtract implements HKDF-Extract from RFC 5869. func hkdfExtract(hash func() hash.Hash, salt, ikm []byte) []byte { if salt == nil { salt = make([]byte, hash().Size()) } hmac := hmac.New(hash, salt) hmac.Write(ikm) return hmac.Sum(nil) }
// MakePermSignature returns a string representing the signed permission // hint for the blob identified by blob_hash, api_token and expiration timestamp. func MakePermSignature(blob_hash string, api_token string, expiry string) string { hmac := hmac.New(sha1.New, PermissionSecret) hmac.Write([]byte(blob_hash)) hmac.Write([]byte("@")) hmac.Write([]byte(api_token)) hmac.Write([]byte("@")) hmac.Write([]byte(expiry)) digest := hmac.Sum(nil) return fmt.Sprintf("%x", digest) }
// calcMac calculates HMAC-SHA-256 over the message using the passed secret key as // input to the HMAC. func calcMac(key [keyLen]byte, msg []byte) [securityParameter]byte { hmac := hmac.New(sha256.New, key[:]) hmac.Write(msg) h := hmac.Sum(nil) var mac [securityParameter]byte copy(mac[:], h[:securityParameter]) return mac }
func (t *Token) VerifySignature(key string) error { sig_base := "rter_consumer=" + t.consumer + "&rter_resource=" + t.Resource + "&rter_valid_until=" + t.Valid_until hmac := hmac.New(sha256.New, bytes.NewBufferString(key).Bytes()) checksig := url.QueryEscape(base64.StdEncoding.EncodeToString(hmac.Sum(bytes.NewBufferString(url.QueryEscape(sig_base)).Bytes()))) if t.Signature == checksig { return nil } return errors.New("signature verification failed") }
// makePermSignature generates a SHA-1 HMAC digest for the given blob, // token, expiry, and site secret. func makePermSignature(blobHash, apiToken, expiry string, permissionSecret []byte) string { hmac := hmac.New(sha1.New, permissionSecret) hmac.Write([]byte(blobHash)) hmac.Write([]byte("@")) hmac.Write([]byte(apiToken)) hmac.Write([]byte("@")) hmac.Write([]byte(expiry)) digest := hmac.Sum(nil) return fmt.Sprintf("%x", digest) }
func IronString(name, value string, key []byte, duration int64) string { if duration > 0 { value = fmt.Sprintf("%d:%s", time.Seconds()+duration, value) } message := fmt.Sprintf("%s|%s", strings.Replace(name, "|", `\|`, -1), value) hmac := ironHMAC(key) hmac.Write([]byte(message)) mac := base64.URLEncoding.EncodeToString(hmac.Sum()) return fmt.Sprintf("%s:%s", mac, value) }
func (sk *SKEME) mkmac(masterkey, Xb1, Xb2 []byte) (cipher.Stream, []byte) { keylen := sk.ms.KeySize() hmac := hmac.New(sk.suite.Hash, masterkey) hmac.Write(Xb1) hmac.Write(Xb2) key := hmac.Sum(nil)[:keylen] stream := sk.suite.Cipher(key) mac := random.Bytes(keylen, stream) return stream, mac }
// Create hash_ref suitable for later invocation of Check() func (s ScryptAuth) Hash(pw_cost uint, user_password, salt []byte) (hash_ref []byte, err error) { scrypt_hash, err := scrypt.Key(user_password, salt, 1<<pw_cost, s.R, s.P, KEYLENGTH) if err != nil { return } hmac := hmac.New(sha256.New, s.HmacKey) if _, err = hmac.Write(scrypt_hash); err != nil { return } hash_ref = hmac.Sum(nil) return }
// WithHMAC derives key of length outlen from the provided password, salt, // and the number of iterations using PKCS#5 PBKDF2 with the provided // hash function in HMAC. // // Caller is responsible to make sure that outlen < (2^32-1) * hash.Size(). func WithHMAC(hash func() hash.Hash, password []byte, salt []byte, iterations int, outlen int) []byte { out := make([]byte, outlen) hashSize := hash().Size() ibuf := make([]byte, 4) block := 1 p := out for outlen > 0 { clen := outlen if clen > hashSize { clen = hashSize } ibuf[0] = byte((block >> 24) & 0xff) ibuf[1] = byte((block >> 16) & 0xff) ibuf[2] = byte((block >> 8) & 0xff) ibuf[3] = byte((block) & 0xff) hmac := hmac.New(hash, password) hmac.Write(salt) hmac.Write(ibuf) tmp := hmac.Sum() for i := 0; i < clen; i++ { p[i] = tmp[i] } for j := 1; j < iterations; j++ { hmac.Reset() hmac.Write(tmp) tmp = hmac.Sum() for k := 0; k < clen; k++ { p[k] ^= tmp[k] } } outlen -= clen block++ p = p[clen:] } return out }
// Compute an authentication tag func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte { buffer := make([]byte, len(aad)+len(nonce)+len(ciphertext)+8) n := 0 n += copy(buffer, aad) n += copy(buffer[n:], nonce) n += copy(buffer[n:], ciphertext) binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad)*8)) // According to documentation, Write() on hash.Hash never fails. hmac := hmac.New(ctx.hash, ctx.integrityKey) _, _ = hmac.Write(buffer) return hmac.Sum(nil)[:ctx.authtagBytes] }
func (mp *MerkleProof) calcRootHash(seed []byte, lastNode []byte) []byte { hmac := hmac.New(sha256.New, seed) for i := len(mp.Level) - 1; i >= 0; i-- { hmac.Reset() if mp.Level[i].NodeHash != nil { if mp.Level[i].IsLeft { hmac.Write(mp.Level[i].NodeHash) hmac.Write(lastNode) } else { hmac.Write(lastNode) hmac.Write(mp.Level[i].NodeHash) } lastNode = hmac.Sum(nil) } } return lastNode }
// test signing function independent of others func TestTokenSigning(t *testing.T) { tok := FakeToken(TEST_TOKEN_URI, TEST_TOKEN_CONSUMER, TEST_TOKEN_LIFETIME_STR, "") if err := tok.Sign(TEST_TOKEN_SECRET); err != nil { t.Fatal("Sign() failed") } // verify signature manually var sig_base string sig_base = "rter_consumer=" + TEST_TOKEN_CONSUMER + "&rter_resource=" + TEST_TOKEN_URI + "&rter_valid_until=" + TEST_TOKEN_LIFETIME_STR hmac := hmac.New(sha256.New, bytes.NewBufferString(TEST_TOKEN_SECRET).Bytes()) sig := url.QueryEscape(base64.StdEncoding.EncodeToString(hmac.Sum(bytes.NewBufferString(url.QueryEscape(sig_base)).Bytes()))) if sig != tok.Signature { t.Error("signature mismatch") } }
func (bucket *Bucket) Sign(req *http.Request) { // gather the string to be signed // method msg := req.Method + "\n" // md5sum if md5, present := req.Header["Content-MD5"]; present { msg += md5 } msg += "\n" // content-type if contentType, present := req.Header["Content-Type"]; present { msg += contentType } msg += "\n" // date msg += req.Header["Date"] + "\n" // add headers for _, key := range AWS_HEADERS { if value, present := req.Header[key]; present { msg += key + ":" + value + "\n" } } // resource: the path components should be URL-encoded, but not the slashes resource := http.URLEscape("/" + bucket.bucket + req.URL.Path) resource = strings.Replace(resource, "%2f", "/", -1) msg += resource // create the signature hmac := hmac.NewSHA1([]byte(bucket.secret)) hmac.Write([]byte(msg)) // get a base64 encoding of the signature encoded := new(bytes.Buffer) encoder := base64.NewEncoder(base64.StdEncoding, encoded) encoder.Write(hmac.Sum()) encoder.Close() signature := encoded.String() req.Header["Authorization"] = "AWS " + bucket.key + ":" + signature }
func (bucket *Bucket) sign(req *http.Request) { accessKeyId := bucket.Key secretAccessKey := bucket.Secret hmac := hmac.NewSHA1([]byte(secretAccessKey)) // method msg := req.Method + "\n" // md5sum if md5, present := req.Header["Content-MD5"]; present { msg += md5 } msg += "\n" // content-type if contentType, present := req.Header["Content-Type"]; present { msg += contentType } msg += "\n" // date msg += req.Header["Date"] + "\n" // write out first four hmac.Write([]byte(msg)) // add headers rawpath := req.URL.Path path := strings.TrimLeft(rawpath, "/") // resource resource := "/" + bucket.MainBucket + "/" + path hmac.Write([]byte(resource)) // get a base64 encoding of the signature encoded := new(bytes.Buffer) encoder := base64.NewEncoder(base64.StdEncoding, encoded) encoder.Write(hmac.Sum()) encoder.Close() signature := encoded.String() req.Header["Authorization"] = "AWS " + accessKeyId + ":" + signature }
// Compute the HMAC based on the given alg value func (ctx symmetricMac) hmac(payload []byte, alg SignatureAlgorithm) ([]byte, error) { var hash func() hash.Hash switch alg { case HS256: hash = sha256.New case HS384: hash = sha512.New384 case HS512: hash = sha512.New default: return nil, ErrUnsupportedAlgorithm } hmac := hmac.New(hash, ctx.key) // According to documentation, Write() on hash never fails _, _ = hmac.Write(payload) return hmac.Sum(nil), nil }
func (p *Propolis) SignRequest(req *http.Request) { // gather the string to be signed // method msg := req.Method + "\n" // md5sum msg += req.Header.Get("Content-MD5") + "\n" // content-type msg += req.Header.Get("Content-Type") + "\n" // date msg += req.Header.Get("Date") + "\n" // add headers for _, key := range AWS_HEADERS { if value := req.Header.Get(key); value != "" { msg += strings.ToLower(key) + ":" + value + "\n" } } // resource: the path components should be URL-encoded, but not the slashes u := new(url.URL) u.Path = "/" + p.Bucket + req.URL.Path msg += u.String() // create the signature hmac := hmac.NewSHA1([]byte(p.Secret)) hmac.Write([]byte(msg)) // get a base64 encoding of the signature var encoded bytes.Buffer encoder := base64.NewEncoder(base64.StdEncoding, &encoded) encoder.Write(hmac.Sum()) encoder.Close() signature := encoded.String() req.Header.Set("Authorization", "AWS "+p.Key+":"+signature) }
func (api Api) auth(request *Request) error { // extract api version number version, err := strconv.ParseInt(request.Path[0:1], 10, 8) if err != nil { return err } if version < 0 || version > 2 { return InvalidVersion(version) } // add the nonce value to the request parameters request.Parameters.Add("tonce", strconv.FormatInt(time.Now().UnixNano()/1000, 10)) // first decode secret b64 := base64.StdEncoding secret, err := b64.DecodeString(api.ApiSecret) if err != nil { return err } // the data we want to encode encodedData := request.Parameters.Encode() if version == 2 { // version 2 add the pathname for more entropy encodedData = request.Path[2:] + "\x00" + encodedData } // retrieve a sha512 hmac generator hmac := hmac.New(sha512.New, secret) // write our encoded data hmac.Write([]byte(encodedData)) signature := b64.EncodeToString(hmac.Sum(nil)) // add headers to request request.HttpRequest.Header.Add("Rest-Key", api.ApiKey) request.HttpRequest.Header.Add("Rest-Sign", signature) return nil }
func TestTokenSignatureVerification(t *testing.T) { // generate a valid token signature, ut do not use Token.Sign() var sig_base string sig_base = "rter_consumer=" + TEST_TOKEN_CONSUMER + "&rter_resource=" + TEST_TOKEN_URI + "&rter_valid_until=3600" hmac := hmac.New(sha256.New, bytes.NewBufferString(TEST_TOKEN_SECRET).Bytes()) sig := url.QueryEscape(base64.StdEncoding.EncodeToString(hmac.Sum(bytes.NewBufferString(url.QueryEscape(sig_base)).Bytes()))) // fake and test a valid token for testing tok := FakeToken(TEST_TOKEN_URI, TEST_TOKEN_CONSUMER, "3600", sig) if tok.VerifySignature(TEST_TOKEN_SECRET) != nil { t.Error("valid signature rejected") } // fake and test a token with invalid URI tok = FakeToken("http://invalid.uri", TEST_TOKEN_CONSUMER, "3600", sig) if tok.VerifySignature(TEST_TOKEN_SECRET) == nil { t.Error("invalid uri validated") } // fake and test a token with invalid livetime tok = FakeToken(TEST_TOKEN_URI, TEST_TOKEN_CONSUMER, "1", sig) if tok.VerifySignature(TEST_TOKEN_SECRET) == nil { t.Error("invalid lifetime validated") } // fake and test a token with invalid signature tok = FakeToken(TEST_TOKEN_URI, TEST_TOKEN_CONSUMER, "3600", sig+"x") if tok.VerifySignature(TEST_TOKEN_SECRET) == nil { t.Error("invalid signature validated") } // fake and test a token with empty signature tok = FakeToken(TEST_TOKEN_URI, TEST_TOKEN_CONSUMER, "3600", "") if tok.VerifySignature(TEST_TOKEN_SECRET) == nil { t.Error("empty signature validated") } }
func (app Application) ParseSignedRequest(r string) (parsed Map, err error) { var malformed = errors.New("Malformed Signed Request") parts := strings.Split(r, ".") if len(parts) != 2 { return nil, malformed } for _, part := range parts { if part == "" { return nil, malformed } } payload, err := base64.URLEncoding.DecodeString(pad64(parts[1])) if err != nil { return nil, malformed } err = json.Unmarshal(payload, &parsed) if err != nil { return nil, errors.New("Malformed Signed Request") } if parsed["algorithm"] != "HMAC-SHA256" { return nil, errors.New("Unknown algorithm " + parsed["algorithm"].(string)) } hmac := hmac.New(sha256.New, []byte(app.Secret)) hmac.Write([]byte(parts[1])) sig := base64.URLEncoding.EncodeToString(hmac.Sum(nil)) if pad64(parts[0]) != sig { return nil, errors.New("Bad Signature") } return }
func sign(auth Auth, method string, canonicalPath string, headers map[string][]string) { var md5, ctype, date string method = strings.ToLower(method) for k, v := range headers { k = strings.ToLower(k) switch k { case "content-md5": md5 = v[0] case "content-type": ctype = v[0] case "date": date = v[0] } } payload := method + "\n" + md5 + "\n" + ctype + "\n" + date + "\n" + canonicalPath hmac := hmac.New(sha1.New, []byte(auth.SecretKey)) hmac.Write([]byte(payload)) signature := make([]byte, base64.StdEncoding.EncodedLen(hmac.Size())) base64.StdEncoding.Encode(signature, hmac.Sum(nil)) headers["Authorization"] = []string{"AWS " + auth.AccessKey + ":" + string(signature)} }
func (t *Token) Sign(key string) error { sig_base := "rter_consumer=" + t.consumer + "&rter_resource=" + t.Resource + "&rter_valid_until=" + t.Valid_until hmac := hmac.New(sha256.New, bytes.NewBufferString(key).Bytes()) t.Signature = url.QueryEscape(base64.StdEncoding.EncodeToString(hmac.Sum(bytes.NewBufferString(url.QueryEscape(sig_base)).Bytes()))) return nil }
//HMAC func HMACFunction(data string) string { hmac := hmac.New(sha256.New, []byte(data)) return string(hmac.Sum(nil)) }