// Decode decodes the given token and return its data // and creation time in UTC. func (tok *T) Decode(token []byte) (data []byte, creation time.Time, err error) { raw := make([]byte, base64.RawURLEncoding.DecodedLen(len(token))) n, err := base64.RawURLEncoding.Decode(raw, token) if err != nil { return nil, time.Time{}, err } raw = raw[:n] hash := tok.hmac() if len(raw) < aes.BlockSize*2+hash.Size() { return nil, time.Time{}, ErrInvalidToken } soff := len(raw) - hash.Size() // signature offset hash.Write(raw[:soff]) want := hash.Sum(nil) have := raw[soff:] if !hmac.Equal(want, have) { return nil, time.Time{}, ErrInvalidTokenSignature } iv := raw[:aes.BlockSize] body := raw[aes.BlockSize:soff] if len(body)%aes.BlockSize != 0 { return nil, time.Time{}, ErrInvalidToken } mode := cipher.NewCBCDecrypter(tok.aes, iv) mode.CryptBlocks(body, body) ts := time.Unix(int64(binary.BigEndian.Uint32(body)), 0) body, err = pkcs7Unpad(body, aes.BlockSize) if err != nil { return nil, time.Time{}, err } return body[4:], ts.UTC(), nil }
func signPayload(payload, secret string, hashFunc func() hash.Hash) string { hash := hmac.New(hashFunc, []byte(secret)) hash.Write([]byte(payload)) signature := make([]byte, b64.EncodedLen(hash.Size())) b64.Encode(signature, hash.Sum(nil)) return string(signature) }
// Encode encodes the given byte slice and returns a token. func (tok *T) Encode(data []byte) (token []byte, err error) { if data == nil { data = []byte{} } body := make([]byte, 4+len(data)) now := uint32(time.Now().UTC().Unix()) binary.BigEndian.PutUint32(body, now) copy(body[4:], data) body, err = pkcs7Pad(body, aes.BlockSize) if err != nil { return nil, err } iv := NewKey(aes.BlockSize) mode := cipher.NewCBCEncrypter(tok.aes, iv) mode.CryptBlocks(body, body) hash := tok.hmac() // size = len(iv + aesblocks + signature) token = make([]byte, len(iv)+len(body)+hash.Size()) copy(token, iv) offset := len(iv) copy(token[offset:], body) offset += len(body) hash.Write(token[:offset]) copy(token[offset:], hash.Sum(nil)) b := make([]byte, base64.RawURLEncoding.EncodedLen(len(token))) base64.RawURLEncoding.Encode(b, token) return b, nil }
// Calculates the key and iv for AES decryption given a password and salt. func calcAes30Params(pass []uint16, salt []byte) (key, iv []byte) { p := make([]byte, 0, len(pass)*2+len(salt)) for _, v := range pass { p = append(p, byte(v), byte(v>>8)) } p = append(p, salt...) hash := sha1.New() iv = make([]byte, 16) s := make([]byte, 0, hash.Size()) for i := 0; i < hashRounds; i++ { hash.Write(p) hash.Write([]byte{byte(i), byte(i >> 8), byte(i >> 16)}) if i%(hashRounds/16) == 0 { s = hash.Sum(s[:0]) iv[i/(hashRounds/16)] = s[4*4+3] } } key = hash.Sum(s[:0]) key = key[:16] for k := key; len(k) >= 4; k = k[4:] { k[0], k[1], k[2], k[3] = k[3], k[2], k[1], k[0] } return key, iv }
// An implementation of PBKDF2 (Password-Based Key Derivation Function 2) as // specified in PKCS #5 v2.0 from RSA Laboratorie and in `RFC 2898 // <http://www.ietf.org/rfc/rfc2898.txt>`. func PBKDF2(hashfunc func([]byte) hash.Hash, password, salt []byte, iterations, keylen int) (key []byte) { var ( digest []byte i, j, k, length int ) key = make([]byte, keylen) slice := key hash := hashfunc(password) hashlen := hash.Size() scratch := make([]byte, 4) for keylen > 0 { if hashlen > keylen { length = keylen } else { length = hashlen } i += 1 scratch[0] = byte(i >> 24) scratch[1] = byte(i >> 16) scratch[2] = byte(i >> 8) scratch[3] = byte(i) hash.Write(salt) hash.Write(scratch) digest = hash.Sum() hash.Reset() for j = 0; j < length; j++ { slice[j] = digest[j] } for k = 1; k < iterations; k++ { hash.Write(digest) digest = hash.Sum() for j = 0; j < length; j++ { slice[j] ^= digest[j] } hash.Reset() } keylen -= length slice = slice[length:] } return }
func (self *FileNode) Signature() ([]byte, error) { if self.sig != nil { return self.sig, nil } hash := fnv.New64a() err := HashFile(self.Name(), hash) if err != nil { return nil, err } signature := make([]byte, 0, hash.Size()) signature = hash.Sum(signature) self.sig = signature return signature, nil }
func (x *Xsrf) sign(data []byte) []byte { hash := x.hash() hash.Write(data) signing := hash.Sum(nil) bs := x.Pool.Get(len(data)+hash.Size(), false) // data+signature buf := bytes.NewBuffer(bs) buf.Write(data) buf.Write(signing) dst := x.Pool.Get(_ENCODING.EncodedLen(buf.Len()), true) _ENCODING.Encode(dst, buf.Bytes()) x.Pool.Put(bs) return dst }
func (c *Cipher) encrypt(now int64, str string) string { hash := hmac.New(c.Hash, unsafe2.Bytes(c.SecretKey)) if now == 0 { now = time.Now().Add(c.TTL).UnixNano() } hash.Write(unsafe2.Bytes(str)) hash.Write(unsafe2.Bytes(c.segSep())) nows := strconv.FormatInt(now, 10) hash.Write(unsafe2.Bytes(nows)) hash.Write(unsafe2.Bytes(c.segSep())) hash.Write(unsafe2.Bytes(c.SecretKey)) sig := hash.Sum(nil) sigStr := hex.EncodeToString(sig[:hash.Size()/2]) return str + c.segSep() + nows + c.segSep() + sigStr[:len(sigStr)/2] }
func (x *Xsrf) verify(signing []byte) []byte { dst := x.Pool.Get(_ENCODING.DecodedLen(len(signing)), true) n, err := _ENCODING.Decode(dst, signing) if err == nil { dst = dst[:n] hash := x.hash() sep := len(dst) - hash.Size() if sep > 0 { data := dst[:sep] hash.Write(data) if bytes.Equal(hash.Sum(nil), dst[sep:]) { return data } } } x.Pool.Put(dst) return nil }
// PayloadSign generates a sign based on the Algorithm instance variable. // This fulfills the `PayloadSigner` interface func (s EcdsaSign) PayloadSign(payload []byte) ([]byte, error) { hash, err := ecdsaHashForAlg(s.SignatureAlgorithm()) if err != nil { return nil, err } privkey := s.PrivateKey if privkey == nil { return nil, errors.New("cannot proceed with Sign(): no private key available") } keysiz := hash.Size() curveBits := privkey.Curve.Params().BitSize if curveBits != keysiz*8 { return nil, errors.New("key size does not match curve bit size") } h := hash.New() h.Write(payload) signed := h.Sum(nil) if debug.Enabled { debug.Printf("payload = %s, signed -> %x", payload, signed) } r, v, err := ecdsa.Sign(rand.Reader, privkey, signed) if err != nil { return nil, err } out := make([]byte, keysiz*2) keys := [][]byte{r.Bytes(), v.Bytes()} for i, data := range keys { start := i * keysiz padlen := keysiz - len(data) copy(out[start+padlen:], data) } return out, nil }
// Decrypt decrypts an ECIES ciphertext. func (prv *PrivateKey) Decrypt(rand io.Reader, c, s1, s2 []byte) (m []byte, err error) { if c == nil || len(c) == 0 { err = ErrInvalidMessage return } params := prv.PublicKey.Params if params == nil { if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil { err = ErrUnsupportedECIESParameters return } } hash := params.Hash() var ( rLen int hLen int = hash.Size() mStart int mEnd int ) switch c[0] { case 2, 3, 4: rLen = ((prv.PublicKey.Curve.Params().BitSize + 7) / 4) if len(c) < (rLen + hLen + 1) { err = ErrInvalidMessage return } default: err = ErrInvalidPublicKey return } mStart = rLen mEnd = len(c) - hLen R := new(PublicKey) R.Curve = prv.PublicKey.Curve R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen]) if R.X == nil { err = ErrInvalidPublicKey return } if !R.Curve.IsOnCurve(R.X, R.Y) { err = ErrInvalidCurve return } z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen) if err != nil { return } K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen) if err != nil { return } Ke := K[:params.KeyLen] Km := K[params.KeyLen:] hash.Write(Km) Km = hash.Sum(nil) hash.Reset() d := messageTag(params.Hash, Km, c[mStart:mEnd], s2) if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 { err = ErrInvalidMessage return } m, err = symDecrypt(rand, params, Ke, c[mStart:mEnd]) return }