示例#1
0
// IsCurrent returns true if the parameters used to generate the encoded password
// are at least as good as those in params.
// If IsCurrent returns false the encoding is out of date and should be regenerated,
// the application should call mcf.Create() to produce a new encoding to replace the current one.
func (enc *Encoder) IsCurrent(encoded []byte) (isCurrent bool, err error) {

	passwd := password.New(enc.name)

	err = passwd.Parse(encoded)
	if err != nil {
		return
	}

	imp := enc.implementer()
	err = imp.SetParams(string(passwd.Params))
	if err != nil {
		return
	}

	return imp.AtLeast(enc.implementer()), nil
}
示例#2
0
func TestKey(t *testing.T) {
	for i, v := range good {

		err := setConfig(len(v.output), len(v.salt), v.N, v.r, v.p)
		if err != nil {
			t.Errorf("%d: unexpected error setting config: %s", i, err)
		}

		setSalt(v.salt)

		encoded, err := mcf.Create(v.password)
		if err != nil {
			t.Errorf("%d: got unexpected error: %s", i, err)
		}

		passwd := password.New([]byte("scrypt"))
		err = passwd.Parse([]byte(encoded))
		if err != nil {
			t.Errorf("%d: unexpected error creating password instance: %s", err)
		}

		if !bytes.Equal(passwd.Salt, []byte(v.salt)) {
			t.Errorf("%d: salt: expected %s, got %s", i, v.salt, string(passwd.Salt))
		}

		if !bytes.Equal(passwd.Key, v.output) {
			t.Errorf("%d: expected %x, got %x", i, v.output, passwd.Key)
		}
	}

	for i, v := range bad {
		err := setConfig(32, len(v.salt), v.N, v.r, v.p)
		if err == nil {
			t.Errorf("%d: expected error, got nil", i)
		}

		setSalt(v.salt)

		_, err = mcf.Create(v.password)
		if err == nil {
			t.Errorf("%d: expected error, got nil", i)
		}
	}
}
示例#3
0
// Create produces an encoded password from a plaintext password using the current configuration.
// The application must store the encoded password for future use.
func (enc *Encoder) Create(plaintext []byte) (encoded []byte, err error) {

	imp := enc.implementer()

	passwd := password.New(enc.name)
	passwd.Params = []byte(imp.Params())

	passwd.Salt, err = imp.Salt()
	if err != nil {
		return
	}

	passwd.Key, err = imp.Key(plaintext, passwd.Salt)
	if err != nil {
		return
	}

	return passwd.Bytes(), nil
}
示例#4
0
// Verify returns true if the proffered plaintext password,
// when encoded using the same parameters, matches the encoded password.
func (enc *Encoder) Verify(plaintext, encoded []byte) (isValid bool, err error) {

	passwd := password.New(enc.name)

	err = passwd.Parse(encoded)
	if err != nil {
		return
	}

	imp := enc.implementer()
	err = imp.SetParams(string(passwd.Params))
	if err != nil {
		return
	}

	testKey, err := imp.Key(plaintext, passwd.Salt)
	if err != nil {
		return
	}

	return subtle.ConstantTimeCompare(passwd.Key, testKey) == 1, nil
}
示例#5
0
func TestVectors(t *testing.T) {
	for i, v := range testVectors {

		key, err := hex.DecodeString(v.key)
		if err != nil {
			t.Errorf("%d: could not decode key: %s: %s", i, v.key, err)
			continue
		}

		config, err := setConfig(len(key), v.iterations, len(v.salt))
		if err != nil {
			t.Errorf("%d: unexpected error setting config: %s", i, err)
		}

		setSalt(v.salt)

		encoded, err := mcf.Create(v.plain)
		if err != nil {
			t.Errorf("%d: got unexpected error: %s", i, err)
		}

		passwd := password.New([]byte("pbkdf2"))
		err = passwd.Parse([]byte(encoded))
		if err != nil {
			t.Errorf("%d: unexpected error creating password instance: %s", i, err)
		}

		if p, q := []byte(config.Params()), passwd.Params; !bytes.Equal(p, q) {
			t.Errorf("%d: params: expected %s, got %s", i, string(p), string(q))
		}

		if p, q := []byte(v.salt), passwd.Salt; !bytes.Equal(p, q) {
			t.Errorf("%d: salt: expected %s, got %s", i, string(p), string(q))
		}

		if p, q := key, passwd.Key; !bytes.Equal(p, q) {
			t.Errorf("%d: key: expected %x, got %x", i, p, q)
		}

		isValid, err := mcf.Verify(v.plain, encoded)
		if err != nil {
			t.Errorf("%d: verify: unexpected failure on %q: %s", i, encoded, err)
			continue
		}
		if !isValid {
			t.Errorf("%d: verify - unexpectedly returned false", i)
			continue
		}

		// perturb configuration...
		newConfig := *config
		newConfig.KeyLen += 1

		for j, c := range []*Config{config, &newConfig} {
			setConfig(c.KeyLen, c.Iterations, c.SaltLen)
			isCurrent, err := mcf.IsCurrent(encoded)
			if err != nil {
				t.Errorf("%d-%d: IsCurrent: unexpected failure: %", i, j, err)
				continue
			}
			//old configuration says yes, new configuration says no
			if answer := c == config; isCurrent != answer {
				t.Errorf("%d-%d: IsCurrent: expecting %t got %t", i, j, answer, isCurrent)
				continue
			}
		}
	}
}