I'm working on project which is required SSO implementation between WebShpere and PHP web application.
However after i take a look at possible ways to implement SSO i find the LTPA token which is used to implement SSO between different IBM technologies.
but LTPA token 2 is encrypted cookie file. which i should decrypt if i want to use information inside this file such as (userid, username, email ... etc).
i have make deep search about LTPA token 2 and below is the best definition i find from IBM.
LTPA2 signatures are generated using SHA-1 as the hash algorithm, and
RSA (1024-bit key) as the encryption algorithm. After the digital
signature has been attached, the user data and signature are encrypted
with a 3DES or AES key obtained from the LTPA key file (refer to
“Consuming LTPA tokens” and “Generating LTPA tokens”).
But i'm still trying to decrypt this token with no luck.
Any help ?
The Alfresco project did this. Take a look at this blog post for pointers, including working code.
To clarify things, the contents of LTPA tokens are strings that are more or less like "uid=user,cn=users,ou=myorg,dc=com#ldaprealm%timeout%[RSA signature]", encrypted with the shared AES key and encoded with Base64. LTPA v2 will not use 3DES, but only AES. So what you need really to do is to AES decrypt the cookie, and you can already read the username. You don't have to verify the RSA signature.
Why do you need to decrypt it from file? Isn't the token passed along with the calls that you made? When passed, LTPA token is encoded via Base64 and you can easily decode it. Below is an example of how to obtain information from token:
import javax.security.auth.Subject;
import javax.xml.bind.DatatypeConverter;
import com.ibm.websphere.security.cred.WSCredential;
import com.ibm.wsspi.security.token.Token;
Subject subject = ...; // obtain current JAAS subject
Set<?> publicCredentials = subject.getPublicCredentials();
for (Object credential : publicCredentials) {
if (credential instanceof Token) {
System.out.println(DatatypeConverter.printBase64Binary(((Token) credential).getBytes()));
System.out.println(((Token) credential).getName());
System.out.println(((Token) credential).getUniqueID());
System.out.println(((Token) credential).getAttributeNames());
}
}
Related
I wrote an app that queries a Jira API which requires authentication that I provide through Basic Authentication (base64 in the header). The password was stored in the code which has to stop now because I want to hand over the code.
When the users changes their passwords due to the password schedule, the app should prompt the user for the new Jira password, save it securely, and pass it to the Jira API via Basic Authentication.
What's the best way to do this?
Normally, we would hash it but that's not possible because hashing is one-way direction and we need to pass in the real password to Jira instead of a hash.
In case of storing a string which needs to be protected in case of breaches or as a general software data security concern, encryptions should be done. For example, in your case, when the password is taken by the user then it shall be encrypted by the software before storing. While retrieving, the password is decrypted and converted to the hash(or base64) which Jira accepts for the login handshake.
Apart from the simply encrypting and decrypting, a better approach will be to use salts while encrypting and using multiple encryptions in the loop to avoid brute force attempts.
Pseudocode:
unsafe_password = getPasswordFromUser()
salt = getRandomString();
safePassword = encrypt(unsafe_password, salt, key)
// Store the password
putEntryInDB(user, safePassword, salt)
// Retrieve password
[passwordSalt, encryptedPassword] = getSaltAndEncryptedPasswordFromDB()
unsafePassword = decrypt(encryptedPassword, passwordSalt, key)
// Now login into Jira with the actual user's password (unsafePassword)
P.S. You'll be needing to store a key in the code or in some software's configuration.
Source: Attempt 4&5 https://nakedsecurity.sophos.com/2013/11/20/serious-security-how-to-store-your-users-passwords-safely/
I am working with JWT api , i have generated a token using:
public void addAuthentication(HttpServletResponse response, String name) {
// We generate a token now.
String JWT = Jwts.builder()
.setSubject(name)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
response.addHeader(headerString, tokenPrefix + " " + JWT);
}
abd secret token prefix being string , however it does generate token, but when i copy it into
https://jwt.io/#debugger
It does undecode it and reveal all informations stored inside it , did i do something wrong or its as it should be? This does not seem secure at all.
Thanks for answers
This is secure at all. Don't worry about it. Just store your key in a secure way.
The remarkable point is decoded information can not be changed or token can not be generated without the key.
Avoid storing essential information in token like credit card number or password etc. I'm sure that you are not using the JWT for this purpose.
If you want to hide the payload, the JWT specification allows use encryption (see Json Web Encryption-JWE at RFC). If auth0 does not support it, you have a lot of libraries listed in jwt.io
Check this topics
Is JWT that secure?
Why are JWT's secure?
It's secure in the sense it tells you who the user is and what claims they have. You can verify that the user's identity and claims are valid by checking the JWTs signature.
Also, see this: https://stackoverflow.com/a/38459231/2115684
If you want to hide the payload, the JWT specification allows use encryption (see Json Web Encryption-JWE at RFC). If auth0 does not support it, you have a lot of libraries listed in jwt.io
I need some help with this lib. Fetching the following examples code BouncyCastle and I do not understand how this works.
My code: http://pastebin.com/RieDfUd9
Dictionary: chain[0], is sender cert.
conv, is the receiver cert.
My problem is this, I need to encrypt an email using smime with the public key personnel which I am sending the email. At the moment in my test environment I have access to both certificates. But in a production environment I will have only access to my certificate (who is sending) chain [0], and the public key of those who receive. I need encryptar email so that I can open with the public key of who is reading (and which was used to encrypt the message).
I already tried several ways, but I always have problems when decrypting.
You cannot do that. You will have to store the cert instead of just the public keys.
When a mail client receive a email, it has to know which private key to use to decrypt it - or it will just fail to decrypt.
How does the mail client knows which private key to use? Because recipient information is also in the encrypted mail.
You can't just encrypt your data encryption key with any random public key and hope the receiver knows which key can be used to decrypt it.
That's why the BouncyCastle API takes a certificate instead of a key.
You can more read about the details of SMIME encryption here:
https://security.stackexchange.com/questions/45222/smime-email-decryption-key-with-openssl
This link has more about how the decryption process is done for multiple recipients:
SMIME decryption for multiple recipients
I am generating JWT using Node.js with require('jsonwebtoken') using public key which is generated by puttygen tool in windows. Then i will pass that token to other application in headers. The Other application is not developed in Node.js. Using java I need to validate the token with public key. But none of the sites i found a valid sample to verify using public/private key.
Can any one please provide me steps how i can load public/private key in java and verify jwt token. Please provide me examples if any you have. Thanks in advance.
Sample public key (public.pem) :-
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "rsa-key-20160721"
AAAAB3NzaC1yc2EAAAABJQAAAQEAhk1i7Jwz2M6zakReDgg0NkVPn1kK1R8qAp2p
Ayh0eUPCb2XICDDVRnpUIK7/4k4dlLeeSi10TwwXe85zZ0gXcNMIOpnEKIWcnqJM
ctbYwyrl2tAb/tKjvBCvHMA9ZnfNADkN6reBZq8u7kYJ3bF9PxvS3QM+vgJ8/8ZS
qkRWcsmRZdq+wthwGt43J3NSKFfhMVP08/V/hTASq06vvFYApHsEH6zLxNNQ63Tt
Bzedh+C5efyqYqEVqnA7S9bXimyY2ViqpqFTx1lM9dV+12dSOxd7CQzX8eo00Phi
EAnY2hfoTooUeCO3/L6YavRl+CXgjhvA9mg4QO554qI1YCUvBw==
---- END SSH2 PUBLIC KEY ----
Node JS code:-
var privateKey = fs.readFileSync("public.pem");
var userData = {username:'John'};
var token = jwt.sign(userData, privateKey);
Java Code:-
Needed java code which can verify above token using above public key.
Cryptographic operations are independent of programming language. You can perfectly generate a JWT in nodeJS and verify in Java.
JWT is digitally signed with the private key and signature is verified with public key. In case of HMAC symmetric keys, the key to sign and verify is the same.
Use a JWT library for Java like https://github.com/jwtk/jjwt
Jwts.parser().setSigningKey(key).parseClaimsJws(compactJws);
In the page you can see the supported algorithms.
Putty uses its own key format. Java does not supports it. You need to export the Putty SSH2 key to the OpenSSH format. See
How can I read RSA keys in Java?
I am trying to digitally sign an http - web response. Essentially, I create the HTML and multipart content-type response, sign the response then append the digital signature to the response. I think I am close but off a few steps as this is not a true PGP signature since the appended signature is actually HEXtoString. Big thing is to be able to represent the signature correctly so that response can be interpreted correctly. Could use some suggestions here as I am fairly green with this. Thanks in advance.. below is snippets of code I am using now.
StringBuffer myResponse = new StringBuffer("");
myResponse.append(getHttpHeader());
KeyPair pair2 = loadKeyPair();//loads a key pair from generated files
if (signer==null)
signer = Signature.getInstance("MD5withRSA");
signer.initSign(pair2.getPrivate());
signer.update(message.getBytes());
byte[] b = signer.sign();
FileOutputStream sigfos = new FileOutputStream(getFileLocation(0,localTest));
sigfos.write(b);
sigfos.close();
//verify
signer.initVerify(pair2.getPublic());//pubKey);
signer.update(message.getBytes());
if (signer.verify(b)){
myResponse.append(message);
}
StringBuffer signed= new StringBuffer("");
signed.append(boundary);
signed.append(CRLF);
signed.append("content-type: application/pgp-signature");
signed.append(CRLF);
signed.append("-----BEGIN PGP MESSAGE-----");
signed.append(CRLF);
signed.append("Version: 1");//update this
signed.append(CRLF);
signed.append(CRLF);
signed.append(digSignature);//generated as HexString representation of signed file from above
signed.append(CRLF);
signed.append("-----END PGP MESSAGE-----");
signed.append(CRLF);
signed.append(boundary+"--");
myResponse.append (signed);
ServletOutputStream.println(myResponse);
The resulting "signature" that is transmitted is a byte-hashing hexToString representation of the signed files. I am using standard java classes, but not sure if other libraries would give me a true PGP representation with characters outside of the 0-9a-f representation. ideas??
How is the verification code downloaded to the client? More details about the application in question? If it's a verification script downloaded via HTTP then the scheme is fundamentally broken. You probably need to use SSL, especially if you already argued as such.
Without knowing more about your system, it sounds like an adversary in a man-in-the-middle attack need only to:
Replace the public key in the verification code with their own.
Resign all "secure" communications with their own signature.
Your script sees nothing wrong because the public key it checks was modified by the adversary.
Not to mention all communication is in plain-text (so hopefully no personal/sensitive information being transmitted?)
SSL works around this problem because all the certificates have to be signed by a root certificate authority trusted by / installed with the web browser. CAs are supposed to only issue certificates for domains to people that control/own them; therefore, the previous attack would not work.
Now, if your client is installed in a trusted fashion such that an adversary cannot tamper with it, then you can continue with your scheme and still be secure. For example, if the client is installed on a client PC by hand, or delivered securely some other way (like via SSL, and/or using code signing).
(I did notice a reference to MD5 hashing. Do not use MD5 hashes; MD5 has been broken.)
This issue is due to a NAESB-EDI standard. Where a file has been submitted in an http request and we are required to produce a particular response. We are using SSL and the original payload is supposed to be encrypted. The response is plain html (of 4 items) with an additional digital signature of the response. What I have figured to do is to create the response, have existing pgp software create the signature based upon the generated response and then append the signature to the response. Thus I am not using MD5 anymore and I am not exposing keys to public use (except to those that we specifically trade). So James answer is partially correct and without SSL, this offers little if any protection against sniffing since the response is clear text. Yet without the required information in the request, they would not even get a proper response. Likely wouldnt get a response (let alone a proper one).