Skip to content

vk-rv/pvx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ac00bc3 · Sep 12, 2021

History

41 Commits
Mar 24, 2021
Sep 12, 2021
Jan 12, 2021
Jan 12, 2021
Jan 15, 2021
Apr 20, 2021
Aug 12, 2021
Jan 15, 2021
Jan 12, 2021
Jan 12, 2021
Sep 12, 2021
Jan 15, 2021
Jan 15, 2021
Jan 15, 2021
Jan 15, 2021
Jan 15, 2021
Aug 12, 2021
Aug 8, 2021
Aug 12, 2021
Aug 11, 2021
Aug 12, 2021
Aug 12, 2021

Repository files navigation

PVX

PVX is a (work in progress) PASETO implementation for Go programming language. Currently, library supports version 2 and version 4, and partially version 3 local purpose (if you need NIST-approved algorithms), but it is under active development, does not have unnecessary dependencies and has greater than 86% of test coverage.

You can use https://github.com/o1egl/paseto if you are looking for version 1.

Why this library exists:

  1. https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid
  2. https://www.howmanydayssinceajwtalgnonevuln.com

Check "Intended Use-Cases for PASETO" before using this library. https://paseto.io/rfc/draft-00

Go Reference

Go version

A minimal version is 1.14

Installation

go get -u github.com/vk-rv/pvx

General usage

Version 4 (local)

Recommended

Encrypt / Decrypt

k, err := hex.DecodeString("707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f")
if err != nil {
    return err 
}
symK := pvx.NewSymmetricKey(k, pvx.Version4)
pv4 := pvx.NewPV4Local()
token, err := pv4.Encrypt(symK, claims, pvx.WithAssert([]byte("test")))
if err != nil {
	return err
}
cc := MyClaims{}
err = pv4.
    Decrypt(token, symK, pvx.WithAssert([]byte("test"))).
    ScanClaims(&cc)
if err != nil {
    return err 
}
// work with cc claims ...

// or without assert
token, err := pv4.Encrypt(symK, claims)
if err != nil {
	return err
}
err = pv4.Decrypt(token, symK).ScanClaims(&cc)

// more info about implicit asserts is here
// https://github.com/paseto-standard/paseto-spec/blob/master/docs/Rationale-V3-V4.md#implicit-assertions-feature

Version 4 (public)

Recommended

Sign / Verify

publicKey, privateKey, _ := ed25519.GenerateKey(nil)
sk := pvx.NewAsymmetricSecretKey(privateKey, pvx.Version4)
pk := pvx.NewAsymmetricPublicKey(publicKey, pvx.Version4)

pv4 := pvx.NewPV4Public()

token, err := pv4.Sign(sk, claims, pvx.WithAssert([]byte("test")))
if err != nil {//...}

var claims MyClaims 
if err := pv4.Verify(token, pk, pvx.WithAssert([]byte("test")).ScanClaims(&claims); err != nil {//...}

// more info about implicit asserts is here
// https://github.com/paseto-standard/paseto-spec/blob/master/docs/Rationale-V3-V4.md#implicit-assertions-feature

Version 3 (local)

If you need NIST-approved algorithms

k, err := hex.DecodeString("707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f")
if err != nil {
    return err 
}
symK := pvx.NewSymmetricKey(k, pvx.Version3)
pv3 := pvx.NewPV3Local()
token, err := pv3.Encrypt(symK, claims, pvx.WithAssert([]byte("test")))
if err != nil {
	return err
}
cc := MyClaims{}
err = pv3.
    Decrypt(token, symK, pvx.WithAssert([]byte("test"))).
    ScanClaims(&cc)
if err != nil {
    return err 
}
// work with cc claims ...

// or without assert
token, err := pv3.Encrypt(symK, claims)
if err != nil {
	return err
}
err = pv3.Decrypt(token, symK).ScanClaims(&cc)

// more info about implicit asserts is here
// https://github.com/paseto-standard/paseto-spec/blob/master/docs/Rationale-V3-V4.md#implicit-assertions-feature

Claims validation

PVX adds extra layer of security by adding validation of time-based registered claims during a scan by default. During validation multiple errors can occur, and you can check every of them by calling sugar routines on special type.

 // For additional layer of safety, 
 // ScanClaims verifies exp, iss and nbf claims automatically under the hood and you can check whether validation error occurred or not 
 if err := decrypted.ScanClaims(&myClaimsScanned); err != nil {
    var validationErr *pvx.ValidationError
    if errors.As(err, &validationErr) {
        if validationErr.HasExpiredErr() { 
                // handle 
		}
		if validationErr.HasNotBeforeErr() { 
                // handle 
		}
	}
}

You can also use extend validation rules implementing Claims interface on your custom type

type MyClaims struct {
	pvx.RegisteredClaims
	AdditionalData string
	OtherData string 
} 

func (c *MyClaims) Valid() error {

	validationErr := &pvx.ValidationError{}
	
	// first, check the validity of registered claims
	if err := c.RegisteredClaims.Valid(); err != nil {
		errors.As(err, &validationErr)
	}
	
	//  then, perform custom validation
	
	
	return nil 
	
}

To disable validation of registered claims you should implement Claims interface explicitly returning nil in your checks. This is from design.

PASETO V3 and V4

A library has a work in progress status because currently is the next iteration of the PASETO specification. https://paragonie.com/blog/2021/08/paseto-is-even-more-secure-alternative-jose-standards-jwt-etc

About

PASETO implementation for Go programming language

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages