Documentation ¶
Index ¶
- Constants
- Variables
- func ExtractJWTParts(jwtStr string) (headerBase64, payloadBase64, signatureBase64 string, err error)
- func PadPKCS7(src []byte, blockSize int) []byte
- func UnpadPKCS7(src []byte) ([]byte, error)
- func VerifyJWT(jwtStr string, signKey crypto.PublicKey) error
- type Algorithm
- type ContentEncryptAlgorithm
- type JOSEHeaders
- type JWE
- type JWK
- type JWKID
- type JWT
- type JWTHeader
- type JWTPayload
- type PrivateClaims
- type RSAPrivateJWK
- type RSAPublicJWK
- type RegisteredClaims
- type TokenID
- type Usage
Examples ¶
Constants ¶
View Source
const ( // Signing - JWK is intended to be used for signature Signing Usage = "sig" // RS256 - RSASSA-PKCS1-v1_5 + SHA256 RS256 Algorithm = "RS256" // PS256 - RSASSA-PSS + SHA256 PS256 Algorithm = "PS256" )
View Source
const ( // Encryption - JWK is intended to be used for encryption Encryption Usage = "enc" // ROAEP - RSAES OAEP ROAEP Algorithm = "RSA-OAEP" // RSA15 - RSAES-PKCS1-v1_5 RSA15 Algorithm = "RSA1_5" )
Variables ¶
View Source
var ( // ErrUnsupportedAlgorithm - ErrUnsupportedAlgorithm = errors.New("ErrUnsupportedAlgorithm") // ErrUnsupportedEncryption - ErrUnsupportedEncryption = errors.New("ErrUnsupportedEncryption") )
View Source
var ( // JWTBase64Encoding - encoding used to encode and decode tokens JWTBase64Encoding = base64.URLEncoding.WithPadding(base64.NoPadding) // ErrJWTUnparsable - ErrJWTUnparsable = errors.New("ErrJWTUnparsable") )
View Source
var ( // ErrCompactJWEUnparsable - ErrCompactJWEUnparsable = errors.New("ErrCompactJWEUnparsable") )
View Source
var ( // ErrJWKValueOutOfRangeParsingBigInt - ErrJWKValueOutOfRangeParsingBigInt = errors.New("ErrJWKValueOutOfRangeParsingBigInt") )
Functions ¶
func ExtractJWTParts ¶
func ExtractJWTParts(jwtStr string) (headerBase64, payloadBase64, signatureBase64 string, err error)
ExtractJWTParts return base64 encoded string of the header, the payload and the signature
Types ¶
type ContentEncryptAlgorithm ¶
type ContentEncryptAlgorithm string
ContentEncryptAlgorithm -
const ( // A128CBCHS256 - A128CBC-HS256 A128CBCHS256 ContentEncryptAlgorithm = "A128CBC-HS256" // A192CBCHS384 - A192CBC-HS384 A192CBCHS384 ContentEncryptAlgorithm = "A192CBC-HS384" // A256CBCHS512 - A256CBC-HS512 A256CBCHS512 ContentEncryptAlgorithm = "A256CBC-HS512" // A128GCM - A128GCM A128GCM ContentEncryptAlgorithm = "A128GCM" // A192GCM - A192GCM A192GCM ContentEncryptAlgorithm = "A192GCM" // A256GCM - A256GCM A256GCM ContentEncryptAlgorithm = "A256GCM" )
type JOSEHeaders ¶
type JOSEHeaders struct { Algorithm Algorithm `json:"alg"` Encryption ContentEncryptAlgorithm `json:"enc"` AdditionalAuthenticatedDataB64 string `json:"aad,omitempty"` Type string `json:"typ,omitempty"` ContentType string `json:"cty,omitempty"` KeyID JWKID `json:"kid,omitempty"` JWKURI string `json:"jku,omitempty"` JWK *JWK `json:"jwk,omitempty"` Zip string `json:"zip,omitempty"` Critical []string `json:"crit,omitempty"` }
JOSEHeaders JWE header
type JWE ¶
type JWE struct { ProtectedB64 string `json:"protected"` UnprotectedB64 string `json:"unprotected,omitmepty"` AdditionalAuthenticatedData string `json:"add,omitempty"` CipherCEKB64 string `json:"encrypted_key"` InitVectorB64 string `json:"iv"` CiphertextB64 string `json:"ciphertext"` TagB64 string `json:"tag,omitempty"` }
JWE -
Example ¶
package main import ( "bytes" "crypto/rand" "crypto/rsa" "encoding/json" "fmt" "github.com/khezen/jwc" ) func main() { var ( privateKey, _ = rsa.GenerateKey(rand.Reader, 2042) jwkid = jwc.JWKID("52d510e3-8d0a-4ef8-a81a-c8cd7ce06472") publicJWK, _ = jwc.RSAToPublicJWK(&privateKey.PublicKey, jwkid, jwc.ROAEP, nil) publicJWKBytes, _ = json.Marshal(publicJWK) message = []byte("lorem ipsum ipsa occaecati aut velit facilis enim dolorum id eius magni ducimus sed illum similique cupiditate sit id perferendis alias sint") ) compactJWE := encrypt(message, publicJWKBytes) plaintext := decrypt(compactJWE, privateKey) fmt.Println(bytes.EqualFold(message, plaintext)) } func encrypt(plaintext, jwkBytes []byte) []byte { var jwk jwc.RSAPublicJWK err := json.Unmarshal(jwkBytes, &jwk) if err != nil { panic(err) } pubKey, err := jwk.PublicRSA() if err != nil { panic(err) } jwe, err := jwc.NewJWE( &jwc.JOSEHeaders{Algorithm: jwc.ROAEP, Encryption: jwc.A256GCM}, pubKey, plaintext, ) if err != nil { panic(err) } jweString, err := jwe.Compact() if err != nil { panic(err) } return jweString } func decrypt(compactJWE []byte, privateKey *rsa.PrivateKey) []byte { jwe, err := jwc.ParseCompactJWE(compactJWE) if err != nil { panic(err) } plaintext, err := jwe.Plaintext(privateKey) if err != nil { panic(err) } return plaintext }
Output:
type JWK ¶
type JWK struct { Type string `json:"kty"` ID JWKID `json:"kid"` Usage Usage `json:"use"` Algorithm Algorithm `json:"alg"` CertificateChainBase64 []string `json:"x5c,omitempty"` ThumbprintBase64 string `json:"x5t,omitempty"` ExpirationTime *time.Time `json:"exp,omitempty"` }
JWK - JSON Web Key
type JWT ¶
type JWT struct { Header JWTHeader Payload JWTPayload }
JWT - JSON Web Token
Example ¶
package main import ( "crypto/rand" "crypto/rsa" "encoding/json" "fmt" "time" "github.com/khezen/jwc" ) func main() { var ( privateKey, _ = rsa.GenerateKey(rand.Reader, 1024) jwkid = jwc.JWKID("52d510e3-8d0a-4ef8-a81a-c8cd7ce06472") jwk, _ = jwc.RSAToPublicJWK(&privateKey.PublicKey, jwkid, jwc.PS256, nil) jwkBytes, _ = json.Marshal(jwk) ) jwtStr := issueJWT(jwkid, privateKey) token := verify(jwtStr, jwkBytes) fmt.Println(jwtStr) fmt.Println() fmt.Println(token) // eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjRkYjY2NzgwLWYzNjMtNDdmZC05MDlkLTQ0MWM1ZmUyM2Q2MSJ9.eyJleHAiOjE1NDYzNjk0NTIsImlhdCI6MTU0NjM2OTM5MiwiaXNzIjoiZ2l0aHViLmNvbS9raGV6ZW4vandjL2p3dF90ZXN0LmdvIiwic3ViIjoidGVzdCIsInByaXYiOnsiYXVkIjoiYW5kcm9pZC5teWFwcC5jb20iLCJjYyI6ImR1bW15Q29kZUNoYWxsZW5nZSIsImNjbSI6IlMyNTYiLCJjaWQiOiIwMTA4YmZiZC0yZjc2LTQyMmEtYTNiZC0yNjMxZmVhYWNiZWUiLCJkaWQiOiJkZXZpY2VJRCIsInNjbyI6Im9mZmxpbmUiLCJ0aWQiOiJiMGIwZWM5Mi1jZTNjLTQ3ZjUtODQ5Ny03Y2FiMjkxNDcyZDAifX0.WktA5tt_Tt6R-qZuTqpSB7xnYDrMlJXjz7aTzQys1UjMAEjLFHCWqmLp33DRlUboZiZQWa_6D4c6fzS-UHFQ9pQ_73s_Rg83i6XEMJIlr2k420g_cO-N_y425gnoJ2GDOpVSGxMS5uofh8JoE6OZpPNauJo_Z5MNpEKp5XZDEAE // // &{{PS256 JWT 4db66780-f363-47fd-909d-441c5fe23d61} {{1546369452 1546369392 github.com/khezen/jwc/jwt_test.go test } map[tid:b0b0ec92-ce3c-47f5-8497-7cab291472d0 aud:android.myapp.com cc:dummyCodeChallenge ccm:S256 cid:0108bfbd-2f76-422a-a3bd-2631feaacbee did:deviceID sco:offline]}} } func issueJWT(keyID jwc.JWKID, privateKey *rsa.PrivateKey) string { now := time.Now().UTC() nowUnix := now.Unix() exp := now.Add(time.Minute) expUnix := exp.Unix() jwt, err := jwc.NewJWT( jwc.JWTPayload{ RegisteredClaims: jwc.RegisteredClaims{ IssuedAtTimestamp: nowUnix, ExpirationTimestamp: expUnix, Issuer: "github.com/khezen/jwc/jwt_test.go", Subject: "customer_id", Audiance: "android.myapp.com", }, PrivateClaims: jwc.PrivateClaims{ "id": "token_id", "did": "device_id", "sco": "offline", "cc": "dummy_code_challenge", "ccm": "S256", }, }, jwc.PS256, ) if err != nil { panic(err) } jwtStr, err := jwt.Encode(keyID, privateKey) if err != nil { panic(err) } return jwtStr } func verify(jwtStr string, jwkBytes []byte) *jwc.JWT { var pubJWK jwc.RSAPublicJWK err := json.Unmarshal(jwkBytes, &pubJWK) if err != nil { panic(err) } pubKey, err := pubJWK.PublicRSA() if err != nil { panic(err) } token, err := jwc.DecodeVerifyJWT(jwtStr, pubKey) if err != nil { panic(err) } return token }
Output:
func DecodeVerifyJWT ¶
DecodeVerifyJWT - parse a base64 string into a jwt
type JWTHeader ¶
type JWTHeader struct { Algorithm Algorithm `json:"alg"` Type string `json:"typ,omitempty"` ContentType string `json:"cty,omitempty"` SignKeyID JWKID `json:"kid,omitempty"` JWKURI string `json:"jku,omitempty"` Critical []string `jon:"crit,omitempty"` Zip string `json:"zip,omitempty"` JWK *JWK `json:"jwk,omitmepty"` }
JWTHeader JWT header
type JWTPayload ¶
type JWTPayload struct { RegisteredClaims PrivateClaims `json:"priv"` }
JWTPayload - JWT payload
type PrivateClaims ¶
type PrivateClaims map[string]interface{}
PrivateClaims - app specific data embedded in JWT
type RSAPrivateJWK ¶
type RSAPrivateJWK struct { JWK ModulusBase64 string `json:"n"` PublicExponentBase64 string `json:"e"` PrivateExponentBase64 string `json:"d"` FirstPrimeFactorBase64 string `json:"p"` SecondPrimeFactorBase64 string `json:"q"` // precomputed fields PrivateExpModFirstPrimeMinusOneBase64 string `json:"dp"` // d mod(p-1) PrivateExpModSecondPrimeMinusOneBase64 string `json:"dq"` // d mod(q-1) SecondPrimeInverseModFirstPrimeBase64 string `json:"qi"` // q^-1 mod p }
RSAPrivateJWK - rsa private JSON web key
func RSAToPrivateJWK ¶
func RSAToPrivateJWK(privateKey *rsa.PrivateKey, jwkID JWKID, algo Algorithm, expirationTime *time.Time) (*RSAPrivateJWK, error)
RSAToPrivateJWK - takes rsa private key and returns it as JWK
func (*RSAPrivateJWK) PrivateRSA ¶
func (jwk *RSAPrivateJWK) PrivateRSA() (*rsa.PrivateKey, error)
PrivateRSA - takes JWK and return it as rsa private key
type RSAPublicJWK ¶
type RSAPublicJWK struct { JWK ModulusBase64 string `json:"n"` PublicExponentBase64 string `json:"e"` }
RSAPublicJWK - rsa public JSON web key
func RSAToPublicJWK ¶
func RSAToPublicJWK(publicKey *rsa.PublicKey, jwkID JWKID, algo Algorithm, expirationTime *time.Time) (*RSAPublicJWK, error)
RSAToPublicJWK - takes rsa public key and returns it as JWK
type RegisteredClaims ¶
type RegisteredClaims struct { ExpirationTimestamp int64 `json:"exp,omitempty"` IssuedAtTimestamp int64 `json:"iat,omitempty"` Issuer string `json:"iss,omitempty"` Subject string `json:"sub,omitempty"` Audiance string `json:"aud,omitempty"` }
RegisteredClaims - common data embedded in JWT
Click to show internal directories.
Click to hide internal directories.