IOS authentication and Java application on JBoss - java

I have a Java application running on Jboss AS. I'm coding ios application and I need code for authentication in it.
Is it will be good possible way using REST service on Java app that will be check userName and hash of password.
Now I'm try this:
On Java I write REST method:
#GET
#Path("/checkAuth/{userName}/{passHash}")
#Produces("application/json")
public AuthResult checkAuth(#PathParam("userName") String userName, #PathParam("passHash") String passwordHash) {
// code for checking hash of Password with that in SQL base
}
On IOS app:
NSString *authRequest = [ NSString stringWithFormat: pathToRestWithParams, login, md5PassHash];
NSURL *restURL = [NSURL URLWithString:authRequest];
NSMutableURLRequest *restRequest = [NSMutableURLRequest requestWithURL:restURL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:180];
NSHTTPURLResponse *response = nil;
NSError *restError = nil;
NSData *authResult = [NSURLConnection sendSynchronousRequest:restRequest returningResponse:&response error:&restError];
Is it secure?
I want to add Java code that will be returned Session Key (Generated on Java app) for any user. This session key will be send with REST request for updating data from ios app.
Is it more secure?

My Opinion is NO, because it is more vulnerable to man in middle attacks by stealing session id, Also MD5 is outdated now you can use SHA-256 or 512 for hashing and salted password hashing will improve the security.
Refer this link for more secure hashing
For good security you need to apply encryption like AES-256 to your payload , especially for authentication service and other sensitive data transmission.
Refer This link for more about java-iOS AES encryption-decryption

Related

Store password for passing to another service

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/

AES encryption & security flaw

Check update#1
This logic is a candidate for a authentication procedure, done by simple HTTP requests:
I'm sending: userName + encrypted_userName (encrypted_userName is actually the encrypted result of userName, done using AES & as key i use the md5 hash of the password). NOTE: I'm not sending the md5 hashed Password.
on the server I'm comparing: encrypted_userName with own_encrypted_userName (since on server i have access to full info on user, i calculate own encrypted_userName).
Question: is this a security flaw? Say bad guy captures full HTTP request, can he extract password from this 2 infos?
CODE DETAILS, if needed:
private static Cipher getCipher(String key, int mode) throws Exception{
byte[] rawKey = getRawKey(key.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Key key2 = skeySpec;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(mode, key2);
return cipher;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
/* BEFORE:
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
*/
byte[] raw = MD5Util.getMD5HashRaw(seed);
return raw;
}
(NOTE: reason why i use the hash of the password is that code is compatible among platforms (client is Android device), while the commented version is NOT)
UPDATE#1
Short answer:
Presented logic is not even close to be considered a secure authentication mecanism
(for Why? check Michael's answer bellow)
Decided to use Kerberos (AND not https, since I am not familiar + seems complicated to setup):
It is not a true version of Kerberos (like v4 or v5), it is just my own implementation so lets call it "similar with Kerberos" (I know, I know: DONT "roll your own encryption"!!!),
Here are some details:
it works on UDP (now)
authentication is done only once, by:
client sending a Authenticator message (contains: [userId] in plain text & [something_ecrypted] with [entered_user_password] (curently [something_ecrypted] contains just a timestamp, call it [authenticator_creation_timestamp])) NOTE: password is not transmited
server upon receiving message, tryies to decrypt the [something_ecrypted] with [actual_user_password] -> if SUCCESS then client is who it pretends to be, so i send him back a OK response (as in Kerberos this response contains some stuff, like a [public_key] (a RSA key, but encrypted with user_password) + ticket granting ticket (call it [TGT], encrypted with a password known only by server, currently it doenst expire, this [TGT] also contains some stuff, like these 2 timestamps: [TGT_creation_time_stamp] + [authenticator_creation_timestamp] (the one received in the Authenticator message))
after receiving this OK message, client has procured a valid [public_key].. so nice!
protection agains "reply attack" is not a 100% guarantee, but I see it "safe enought":
on each next HTTP reaquest, i attach as headers these 2 guys [new_request_creation_timestamp] (encrypted with [public_key], procured above) + the [TGT] (untouched, as received above)
on server I just need to validate [new_request_creation_timestamp] agains some math (obvious [TGT] needs to be valid too):
** i expect that the following variables to be almost equal
delta1 = [TGT_creation_time_stamp] - [authenticator_creation_timestamp]
delta2 = now()-[new_request_creation_timestamp]
(I actually allow a difference between them of 5 seconds, but from my tests, its just a matter of some 10-20 millis,
** So initial delta (calculated when creating OK response to Authenticator) should perpetuate on next interactions.
I do find this new approach quite trust-worthy, but if you have an opinion or see a BUG in logic, please share.. Thanks
Yes, this is a weak security mechanism.
Anyone who captures the information sent to the server can easily replay it to authenticate themselves (replay attack).
It is vulnerable to offline password guessing - anyone who captures the information sent to the server can then very quickly test a password list to find what password your user has chosen (by encrypting the observed username using the hash of each password in turn). The hashing can even be precomputed, speeding the attack up further.
Password based authentication protocols should be resistant to replay attacks and offline password guessing attacks.
Simply using an HTTPS (TLS) connection to your server and sending the username and password in plaintext would normally be a better solution.
In response to your update 1:
I strongly advise using HTTPS. It is used everywhere for a reason - it has undergone immense security review and been found to be (largely) secure - far better than what you can get through a SO post.
I haven't considered your updated scheme thoroughly, but as it is based on Kerberos it is also subject to offline password guessing attacks as I described above.
Having successfully authenticated, don't forget about then actually protecting your data - you'll likely need to derive a shared symmetric key then use authentication + encryption on your data...
What i understand is : you are sending Username + Encrypted Username to the server.
Ans:
Since you are sending the Username and the encrypted Username which is : UserName + AES(UserName + MD5 Hashed Password)
If anyone knows or find that you give the Username and also gets the Username from your data to server: No worries. There you stand with AES. If you have doubt in AES encryption check this. Your data is secure.
I don't think this is a security flaw per se because even knowing both the plaintext message and the encrypted one, it is practically impossible to get the AES key. But I still wouldn't recommend to store the passwords hashed with MD5.

How to decrypt LTPA token version 2

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());
}
}

Is it secure to pass a password to Java from Jquery ajax callback in plain text?

Or do I need to encrypt it first. I'm using a password text field, grabbing it with
var pwd = $("#userpassword").val();
and then
$.post('JavaServlet', { formData: formData, pwd: pwd, date: date }, function(data) {
The java piece encrypts it and stores it in the ldap.
If you suggest to encrypt, please suggest the best way to accomplish the task.
Thanks in advance!
Answer: We are using SSL. So it seems redundant to encrypt the password.
It's not secure, unless you use SSL/TLS (Https). All information you send over HTTP is sent from the client to the server in clear text.
It is not considered secure unless you use SSL of at least 128-bit encryption, which by the way, it was broken in 2010's. Using as hashed password is a bit safer than plaintext, easier, less resource intensive and might be enough for you, depending on your requirements.
More info on Protecting Passwords with javascript md5 (a hash) and some libraries in javascript here. I understand one of them was used by yahoo many years.

BlackBerry App Security

Users log in to my BlackBerry app with a username and password provided at registration. My app connects to a Java Web Service that does all the logic.
How do I go about storing the password and username in a safe manner on my server? Everybody says salting and hashing, but I have no idea how to do this since I've never worked with it. How can I do this in Java?
How do I manage sending the password securely from the app to the server?
To store the credentials, one possibility is to use PBKDF2. A Java implementation (that I have not used) is available here. Run the password with the salt value through that and store the resulting hash data. The salt value is typically a newly generated random value (one for each password). This helps prevent dictionary attacks via rainbow tables (pre-computed tables of hashed passwords). Using java.security.SecureRandom is a possibility for generating those.
The client application should probably connect to the server using SSL/TLS. That will provide the encryption to protect the credentials when passed from client to your server application.
Edit Based on our conversation in the comments, it sounds as if the goal is not to use SSL. Assuming that is true and no other end-to-end communications encryption is planned, then it seems to imply that the security of the communications is not a high priority. If that is true, then maybe the described scheme for authenticating is sufficient for the application. Nonetheless, it seems worth pointing out the potential issues so you can consider them.
The proposed scheme (I think) is to send from the client to the server this value: Hash(Hash(password,origsalt),randomsalt). What this really means is that the password is effectively Hash(password,origsalt). If the attacker can get that information, then they can login as that user because they take that value and hash it with the new salt value to authenticate. In other words, if the database of hashed passwords is compromised, then the attacker can easily gain access. That somewhat defeats the purpose of salting and hashing the passwords in the first place.
Without SSL (or some other end-to-end encryption), there is the possibility of a man-in-the-middle attack. They can either listen in or even impersonate one end of the conversation.
Seems like your question has a few parts...
The most secure way to store the password in the database is to use a hash with a Salt + Pepper seed as described here. If you want to find a good way of implementing that specific technique in Java, try opening a new question.
I can see why it would make sense to encrypt a username/password hash prior to sending to the server, since SSL proxies can be a man-in-the-middle for that operation.
As a solution try creating a token in JSON or XML format that has the following properties:
Username.ToUpper() // Dont want this to be case sensitive
ExpiryDate (Say now plus 5 minutes)
Nonce (a random number that is saved on the backend to prevent replay attacks)
SHA 256 signature
Use the locally entered username and password to create a SHA256 signature, as it will be a constant. Use this signature to sign the JSON or XML you send to the server with each request.
In other words you're using a symmetric key based on the username and password, without sending it across the wire. Of course you may want to salt and pepper the generation of that symmetric key for more security.
That's all I got for a high level design, since I'm not intimately familiar with Java. Do share your links/code when you do find the answers.
So here's what I ended up doing:
package Utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
/**
*
* #author octavius
*/
public class SalterHasher {
private String salt;
private String pepper = "******************";
private String hash;
private String password;
public SalterHasher(String password, String username)
{
this.password = password;
salt = RandomStringUtils.random(40, username);
hash = DigestUtils.md5Hex(password + salt + pepper);
}
public String getHash(){
return hash;
}
/**
* #return the salt
*/
public String getSalt() {
return salt;
}
public String makeHash(String salt){
return DigestUtils.md5Hex(password + salt + pepper);
}
}
A very simple class that generates a salt and the hash for me and has a pepper included for added security, the makeHash() function I use for verification when the user logs in. In view of what I previously mentioned in the comments above I didn't end up using the verification process I proposed and chose to simply add the pepper to my server side code since hashing I believe would prove to be heavy on the BlackBerry device. Thanks again to those who helped me. Good discussions were had :)

Categories

Resources