I'd like to use HTTP Basic auth to do password-less authentication between trusted services in a private network. Is it acceptable to leave out the password field entirely when using Basic auth? Is there a better authentication mechanism I should research?
RFC 2617 defines them as
user-pass = userid ":" password
userid = *<TEXT excluding ":">
password = *TEXT
and * in the ABNF means "0 or more."
Meaning the userid and password can be empty, in which case : is encoded into Base64.
In HTTP Basic auth, the username and password are concatenated using a colon then encoded in base64 and the resulting header looks something like:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
The Basic part specified basic authentication and the second part is the base64 encoded token. It doesn't have to be a username/password combo, but can just be a username with a blank password, or a username alone. You just have to be aware of that when decoding the authorization header.
Related
Is it possible to use basic authentication when the username and password fields do not make any restrictions on the type of characters to be used?
Example, could exist a user with the following values:
username: iamThe:User
password: My#Secure:Password
To convert to basic authentication:
concat username:password = iamThe:User:My#Secure:Password
convert to base64 and add to header Authorization: Basic aWFtVGhlOlVzZXI6TXlAU2VjdXJlOlBhc3N3b3Jk
How do I get back the username and password from the following field aWFtVGhlOlVzZXI6TXlAU2VjdXJlOlBhc3N3b3Jk? is there a solution for this?
I am creating symmetrically signed Tokens with HMAC + SHA-256. As expected the header looks like this:
{
"alg": "HS256",
"typ": "JWT"
}
But when I encrypt the token with the AES_128_CBC_HMAC_SHA_256, the header changed to this:
{
"alg": "A128KW",
"enc": "A128CBC-HS256",
"typ": "JWT"
}
The "enc" parameter looks like expected, but why does the "alg" parameter change when encrypted?
From what I understand about encrypting JWTs:
The payload is signed (or symmetrically encrypted) and appended to the token;
payload + signature are encrypted with the algorithm specified in "enc" if applicable.
This does not appear to apply though. How would a potential recipient know that the decrypted token was signed with HMAC + SHA-256 now?
Isn't signing and encrypting done in this manner? I also noted that the distinct "." separating the signature and the payload is still present in the encrypted token, which seems odd considering the whole content should be encrypted as one (excluding the header).
I am using Microsoft.IdentityModel to generate the tokens if that matters.
The "enc" parameter looks like expected, but why does the "alg" parameter change when encrypted?
The header claim alg has different meanings when used in a JWS (signed token) and JWE (encrypted token).
With JWS (extract from the RFC7515 section 4.1.1)
The "alg" (algorithm) Header Parameter identifies the cryptographic
algorithm used to secure the JWS.
With JWE (extract from the RFC7516 section 4.1.1)
This parameter has the same meaning, syntax, and processing rules as
the "alg" Header Parameter defined in Section 4.1.1 of [JWS], except
that the Header Parameter identifies the cryptographic algorithm used
to encrypt or determine the value of the CEK.
About you assumption
From what I understand about encrypting JWTs:
* The payload is signed (or symmetrically encrypted) and appended to the token;
* payload + signature are encrypted with the algorithm specified in "enc" if applicable.
This is not correct. With JWE, the payload is not digitally signed by the issuer.
If you need both encryption and signature, you will have to issue a JWS (e.g. with {"alg":"HS256","typ":"JWT"}).
This JWS will be encrypted (e.g. with {"alg": "A128KW","enc": "A128CBC-HS256","typ": "JWT"}
I also noted that the distinct "." separating the signature and the payload is still present in the encrypted token
THe difference between JWS and JWE is that the number of . is not the same:
2 . for JWS
4 . for JWE
Disctinction between the 2 token types is detailed in the RFC7516 section 9
I am looking for a solution on how to improve security for JWT without using encrytpion and in the same time allow user a multisessions.
The standard algorithm of creating a signature is:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
What if we combine some unique client identifier (IP/ MAC address/ browser Fingerprint) (smth that could be exported from the request itself without passing in request body) with our secret?
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret + UNIQUEIDENTIFIER)
Such a solution will prevents the hacker to access our data even if the whole JWT will be stolen.
Unfortunately the usage of IP is not the best for UNIQUEIDENTIFIER, because the client can use dynamic IP.
Any ideas which parameter of http request can be used as UNIQUEIDENTIFIER?
I am pulling data from a server using this API. In order to get an authToken I need to pass my username and password. The password input description says "Hashed password. May be passed as clear text, or as RSA-encrypted hash
(see above for RSA public key)."
To encrypt the password I am using the below code.
library(openssl)
aqKey <- read_pubkey("public_key.pem")
user_name <- "UserName"
password <- rsa_encrypt(charToRaw(askpass()), aqKey)
pw <- rawToChar(password)
This gives me a string with a bunch of unusable characters that produce a 400 error when used in the URL.
/GetAuthToken?user=USERNAME&encPwd=ˆ Ù\026Õ©1tÐÆ®IßÊ/ÛÅÆwéÙeµèB¾kz–V\t–ü˜ÞO«~=ñcѪÿC'p‰-zòjEü,\r¯eÑ}d‹ã\fÀ\030DR·W\026Â\022‰Å:™¶í©«cózÆlE\032Ï4$é¹Þ,ù«…s\021…–ì\026}h¯~?\nC\021ôj-†\032K}ò\026
If I use base64_encode() or URLencode() on either password or pw I get a 200 status but do not receive a token. This is equivalent to an incorrect password. When I pass the password as plaintext I get a token.
My question is, how should I be formatting the password once it has been encrypted so that the server will recognize it as an encrypted password?
In unrealscript, I'm attempting to connect to server using a TCPLink client I wrote. I can connect to the domain, but when I attempt to access a welcome message I receive a 401 error. What am I doing wrong in my authorization field?
Note: username and password are plain-text string variables filled in by the user
SendText("GET /crud/welcome HTTP/1.0"$chr(13)$chr(10));
SendText("Host: "$TargetHost$chr(13)$chr(10));
SendText("Authorization: "$USERNAME$":"$PASSWORD$chr(13)$chr(10));
SendText("Connection: Close"$chr(13)$chr(10));
SendText(chr(13)$chr(10));
You may want to read RFC 2617.