I have received a JWT token created by a java program using jjwt module.
Now, when I try to verify the token using pyjwt, it throws exception.
import jwt token
token='eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMDAiLCJyb2xlcyI6IkJVU0lORVNTVVNFUiIsIm1vZGUiOiJzdG9yZWFwcCIsImlhdCI6MTQ5NDg1ODk4MCwiZXhwIjoxNDk0ODY0OTgwfQ.ckFnGv1NT-Ui2S90DNr50YoHSXc1ZLBNnEErnGMWL-E'
secret ='123456AB'
jwt.decode(token,secret,algorithms='HS256')
Traceback (most recent call last): File "", line 1, in
File
"/Applications/anaconda/envs/modulename/lib/python3.5/site-packages/jwt/api_jwt.py",
line 64, in decode
options, **kwargs) File "/Applications/anaconda/envs/modulename/lib/python3.5/site-packages/jwt/api_jws.py",
line 116, in decode
key, algorithms) File "/Applications/anaconda/envs/modulename/lib/python3.5/site-packages/jwt/api_jws.py",
line 186, in _verify_signature
raise DecodeError('Signature verification failed') jwt.exceptions.DecodeError: Signature verification failed
If i use the same token in jwt.io, with base64 encrypted option checked, it seems to work.
This is because when Java created the token it thought the plain text you used as a secret was base64 encoded. I am assuming Java was expecting the string secret to be base64 encoded version of some binary. Try base64 decoding the secret before decoding jwt.
import base64
jwt.decode(token,base64.b64decode(secret))
#The token in your question was expired so I ended up passing verify expiration = False
jwt.decode(token,base64.b64decode(secret), options={ 'verify_exp': False})
{u'iat': 1494858980, u'exp': 1494864980, u'sub': u'100', u'roles': u'BUSINESSUSER', u'mode': u'storeapp'}
You may try to verify the signature of the incoming token in your Python application using the same SecretKey as you have used in your Java application.
Related
I'm trying to achieve the authentication for office 365 accounts by using oauth 2.0 ,
i'm using PublicClientApplication and InteractiveRequestParameters method for acquiring access token and in result successfully received access token ,refresh token and id token but when i am using access_token to connect to imap, i am getting error as authentication failure, can anyone please help me out what am i missing here.
have given all the required permissions from azure portal.
here is my code through which i am trying to connect to server
store.connect("outlook.office365.com", "my_email_id, access_token); //here store is imap
properties i have set are:
properties.put("mail.smtp.port", "587");
properties.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.setProperty("mail.imap.socketFactory.fallback", "false");
properties.setProperty("mail.imap.port", "993");
properties.setProperty("mail.imap.socketFactory.port", "993");
properties.put("incomingHost", "outlook.office365.com");
properties.put("mail.imap.ssl.enable", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("outgoingHost", "smtp.office365.com");
properties.setProperty("mail.imaps.ssl.trust", "*");
Note: when i am providing password instead of access_token , i am successfully able to login but failure while using access_token.
Thank you !!
You cannot use your access token in place of a password. IMAP requires that your client use SASL XOAUTH2 to authenticate. Details can be found here.
For example, the SASL XOAUTH2 format to access test#contoso.onmicrosoft.com with access token EwBAAl3BAAUFFpUAo7J3Ve0bjLBWZWCclRC3EoAA is:
base64("user=test#contoso.onmicrosoft.com^Aauth=Bearer EwBAAl3BAAUFFpUAo7J3Ve0bjLBWZWCclRC3EoAA^A^A")
After base64 encoding, this translates to the following string. Note that line breaks are inserted for readability.
dXNlcj10ZXN0QGNvbnRvc28ub25taWNyb3NvZnQuY29tAWF1dGg9QmVhcmVy
IEV3QkFBbDNCQUFVRkZwVUFvN0ozVmUwYmpMQldaV0NjbFJDM0VvQUEBAQ==
I am using a flask client to perform openid authentication. However I get the following warning
Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
When fetching the token a request is done using requests.Session.requests here.
Adpating the request method of OAuth2Session fixes the warning.
def request(self, method, url, withhold_token=False, auth=None, **kwargs):
"""Send request with auto refresh token feature (if available)."""
if not withhold_token and auth is None:
if not self.token:
raise MissingTokenError()
auth = self.token_auth
return super(OAuth2Session, self).request(
method, url, auth=auth, verify=True, **kwargs)
Should verification not be enabled by default? Is there a more elegant way to pass verify=True?
You can pass verify directly to the methods of the registered RemoteApp when you fetch the token like this:
token = oauth.remote_app_name.authorize_access_token(verify=True)
I believe SSL verification is enabled by default, however, I use an env var to enable/disable the verification for the requests on a development environment.
I am using the http api for initialising vault and encrypting the seal keys and root token, but I am getting
{"errors":["error decoding given PGP key: illegal base64 data at input byte 21"]}
But when I use the CLI it works.
How do I get it working for the http api??
This done using ubuntu 18.04 and gpg (GnuPG) v2.2.4, base64 v8.28, latest vault
Here is the command for command line interface that works, and returns the seal keys and root token encrypted:
./vault operator init -key-shares=2 -key-threshold=2 -address="http://127.0.0.1:8200" -format="json" -root-token-pgp-key="mo.asc" -pgp-keys="mo.asc,mo.asc"
The above was run in the same directory as the vault instance was started using
./vault server -config=vaultconfig.hcl
The vaultconfig.hcl contains
storage "inmem" {}
listener "tcp" {
address = "127.0.0.1:8200"
tls_disable = 1
}
mo.asc was obtained using the following:
gpg --gen-key
gpg --export <generated key> | base64 > mo.asc
The command for using the http api that does not work
curl --request PUT --data #payload.json http://127.0.0.1:8200/v1/sys/init
payload.json is
{
"secret_shares": 2,
"secret_threshold": 2,
"pgp_keys": [
"mo.asc",
"mo.asc"
],
"root_token_pgp_key": "mo.asc"
}
This returns:
{"errors":["error decoding given PGP key: illegal base64 data at input byte 21"]}
But if I change the payload.json to
{
"secret_shares": 2,
"secret_threshold": 2
}
it works returning
{
"keys": [
"227e3b43a76b54008249b39285ae1063db0e2bff94bad0f349f4b7fa89195fb7d7",
"2ab2f5ec67191c26735116f5a1cc9b3bab406eff7b57d9632359a0797f2cf5fd3e"
],
"keys_base64": [
"In47Q6drVACCSbOSha4QY9sOK/+UutDzSfS3+okZX7fX",
"KrL17GcZHCZzURb1ocybO6tAbv97V9ljI1mgeX8s9f0+"
],
"root_token": "s.s2GZsomY2tGJfQzHGFjqlYNu"
}
It seems the CLI command accepts that my gpg is base64 encrypted, but the http api does not accept it is encrypted. Although it seems the CLI is using the http api underneath. The http api is working, but only when I add the asc file to the payload.json it does not work.
Am I missing something?
How do I think this so I get encrypted root token and keys when initialising vault via http api?
Thanks
I'm trying to secure a REST API using TLS/SSL, to do so I needed to update my client to use the public key and certificate.
The client is written in dart and here's how I implemented the SecurityContext :
SecurityContext clientContext = SecurityContext.defaultContext;
var certificate = (await rootBundle.load("assets/ssl/coastr.crt")).buffer.asInt8List();
print(certificate.toString());
clientContext.setTrustedCertificatesBytes(certificate);
/*var authorities = (await rootBundle.load('assets/ssl/coastr.ca-bundle')).buffer.asUint8List();
print(authorities.toString());
clientContext.setClientAuthoritiesBytes(authorities);*/
var key = (await rootBundle.load("assets/ssl/coastr_public.key")).buffer.asInt8List();
print(key.toString());
clientContext.usePrivateKeyBytes(key);
HttpClient client = HttpClient(context: clientContext);
HttpClientRequest request = await client.getUrl(Uri.parse(url));
HttpClientResponse response = await request.close();
The certificate (.crt file) is added without issue to the clientContext but adding the key to it returns me this error :
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception:
TlsException: Failure in usePrivateKeyBytes (OS Error:
BAD_PKCS12_DATA(pkcs8_x509.c:606)
passed a null parameter(ssl_privkey.cc:375), errno = 0)
The files I'm using are :
coastr.crt with this as a header : -----BEGIN CERTIFICATE-----
coastr_public.key with header : -----BEGIN PUBLIC KEY-----
I have no idea if I'm providing the wrong files to the client or if the error comes from elsewhere.
The files where generated using openssl.
Thank you for your help.
In general, you shouldn't have to add anything to the client to allow it to connect to a correctly configured HTTPS server. Hopefully, the server has a signed server side certificate. If that certificate is signed by a reputable CA, the client should automatically trust it. If it is signed by an in house CA, or self signed, you need to do some work. You need to provide the client with the signing certificate. In the former case that would be the root CA's certificate. In the latter case, supplying the server's certificate may work, though it's probably easier to disable the client check altogether.
The signing certificate is likely to be in CRT form as you've found. And you need to supply that exactly as you are doing. There's no need to supply any public keys as the are distributed in the certificates sent with the server hello.
Unless you want to use a client side certificate, there's no need to supply a private key, so you can skip the step that is failing. And supplying a public key to it is definitely not going to work, anyway.
I am trying to implement Digital certificate validity utility using java. I can able to read the certification information(subjectDN, Issure info, validitity..etc) if the certificate in .cert,.cer but can't able to read certificate information from .p7b and .p12 certificate format. I have used the BouncyCastle security provider to read .p7b and .p12 certificate content but not able to get with that security provider might be i was missing on this. I am referring online resources to get some idea on this but not get guideline for this.Could you please someone give suggestion on this.
I suggest if you're looking for validity of the certificate from p12, it can be done as below :
try {
Security.addProvider(new BouncyCastleProvider());
KeyStore keyStore = KeyStore.getInstance("pkcs12");
InputStream input = new FileInputStream("pathToYourP12");
keyStore.load(input, "password");
certFromKeyStore = (X509Certificate)keyStore.getCertificate("keyStoreAllias");
certFromKeyStore.checkValidity();
}
catch(Exception e)
{
// catch exception like if no valid p12 existing at the location, invalid password, or any other exception should get catch properly.
}