Showing posts with label JWT. Show all posts
Showing posts with label JWT. Show all posts

Monday, 26 May 2025

RS256 vs HS256, JWT

Note: HS256 and RS256 are both not used for ecnryption/decription, 

HS256 and RS256 use to make  a signature, then remake one to verify whether its same or not 


sign: creates an HMAC-SHA256 of message using your secret.

verify: recomputes and compares in constant time (to avoid timing attacks).

for ecnryption decryption use 

Use a symmetric cipher like AES-GCM:


RS256 vs HS256

 https://auth0.com/blog/rs256-vs-hs256-whats-the-difference/


HS256 (HMAC with SHA-256) is a symmetric keyed hashing algorithm that uses one secret key. Symmetric means two parties share the secret key. The key is used for both generating the signature and validating it.

RS256 (RSA Signature with SHA-256) is an asymmetric algorithm that uses a public/private key pair. The identity provider has a private key to generate the signature. The receiver of the JWT uses a public key to validate the JWT signature.


JWT token, is just base 64 encode string, that any one can decrypt, 

but its signature is unable to be changed because it signed using HS256 or RS256


https://jwt.io/introduction#:~:text=Decoding%20a%20JWT%20reverses%20this,parts%20without%20needing%20a%20key.


JWT token structure :

In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:

  • Header
  • Payload
  • Signature

Any one can decrypt this !


Monday, 25 March 2024

JWT -GO add claims and decode claims

 https://github.com/golang-jwt/jwt


https://pkg.go.dev/github.com/golang-jwt/jwt/v5


// add fileName to claim , sign

token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{

"exp": time.Now().Add(10 * time.Hour).Unix(),

"fileName": os.Getenv(<my_file>),

})

// sign token with private key

tokenString, err := token.SignedString(<my_public_key>)

----------------------------------------------------------------------

// middleware validation

tokenString := c.Query("token")

// fileName := c.Query("file")

if tokenString == "" {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: No token found"})

c.Abort()

return

}

// if fileName == "" {

// c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: No file found"})

// c.Abort()

// return

// }

// Parse validate token

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {

// Validate the signing method

if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {

return nil, jwt.ErrSignatureInvalid

}

return jwtSignKey, nil

})

if err != nil {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: " + err.Error()})

c.Abort()

return

}

// token valid

if !token.Valid {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: Invalid token"})

c.Abort()

return

}

// token expired

claims, ok := token.Claims.(jwt.MapClaims)

// _, ok := token.Claims.(jwt.MapClaims)

if !ok {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: Invalid token claims"})

c.Abort()

return

}

expirationTime := time.Unix(int64(claims["exp"].(float64)), 0)

if time.Now().After(expirationTime) {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: Token expired"})

c.Abort()

return

}

fileName, ok := claims["fileName"].(string)

fileLocation = fileName

if !ok {

c.JSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized: File not found in request"})

c.Abort()

return

}


Saturday, 23 March 2024

JWT token based download url some bestpractices

 https://stackoverflow.com/questions/29452031/how-to-handle-file-downloads-with-jwt-based-authentication


AWS soln:


Technique

Based on this advice of Matias Woloski from Auth0, known JWT evangelist, I solved it by generating a signed request with Hawk.

Quoting Woloski:

The way you solve this is by generating a signed request like AWS does, for example.

Here you have an example of this technique, used for activation links.

backend

I created an API to sign my download urls:

Request:

POST /api/sign
Content-Type: application/json
Authorization: Bearer...
{"url": "https://path.to/protected.file"}

Response:

{"url": "https://path.to/protected.file?bewit=NTUzMDYzZTQ2NDYxNzQwMGFlMDMwMDAwXDE0NTU2MzU5OThcZDBIeEplRHJLVVFRWTY0OWFFZUVEaGpMOWJlVTk2czA0cmN6UU4zZndTOD1c"}

With a signed URL, we can get the file

Request:

GET https://path.to/protected.file?bewit=NTUzMDYzZTQ2NDYxNzQwMGFlMDMwMDAwXDE0NTU2MzU5OThcZDBIeEplRHJLVVFRWTY0OWFFZUVEaGpMOWJlVTk2czA0cmN6UU4zZndTOD1c

Response:

Content-Type: multipart/mixed; charset="UTF-8"
Content-Disposition': attachment; filename=protected.file
{BLOB}

frontend (by jojoyuji)

This way you can do it all on a single user click:

function clickedOnDownloadButton() {

  postToSignWithAuthorizationHeader({
    url: 'https://path.to/protected.file'
  }).then(function(signed) {
    window.location = signed.url;
  });

}