User password is now stored encrypted
This commit is contained in:
parent
eb6a52f097
commit
892712e6cb
|
@ -8,5 +8,5 @@
|
||||||
# project structure.
|
# project structure.
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-17
|
target=android-18
|
||||||
android.library=false
|
android.library=false
|
||||||
|
|
|
@ -20,8 +20,10 @@
|
||||||
package es.ugr.swad.swadroid;
|
package es.ugr.swad.swadroid;
|
||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.SharedPreferences.Editor;
|
import android.content.SharedPreferences.Editor;
|
||||||
|
@ -35,14 +37,15 @@ import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.bugsense.trace.BugSenseHandler;
|
import com.bugsense.trace.BugSenseHandler;
|
||||||
|
|
||||||
import es.ugr.swad.swadroid.model.DataBaseHelper;
|
import es.ugr.swad.swadroid.model.DataBaseHelper;
|
||||||
import es.ugr.swad.swadroid.sync.SyncUtils;
|
import es.ugr.swad.swadroid.sync.SyncUtils;
|
||||||
import es.ugr.swad.swadroid.utils.Base64;
|
import es.ugr.swad.swadroid.utils.Crypto;
|
||||||
import es.ugr.swad.swadroid.utils.Utils;
|
import es.ugr.swad.swadroid.utils.Utils;
|
||||||
import es.ugr.swad.swadroid.widget.SeekBarDialogPreference;
|
import es.ugr.swad.swadroid.widget.SeekBarDialogPreference;
|
||||||
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,6 +54,10 @@ import java.security.NoSuchAlgorithmException;
|
||||||
* @author Juan Miguel Boyero Corral <juanmi1982@gmail.com>
|
* @author Juan Miguel Boyero Corral <juanmi1982@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class Preferences extends PreferenceActivity implements OnPreferenceChangeListener {
|
public class Preferences extends PreferenceActivity implements OnPreferenceChangeListener {
|
||||||
|
/**
|
||||||
|
* Login tag name for Logcat
|
||||||
|
*/
|
||||||
|
public static final String TAG = Constants.APP_TAG + " Preferences";
|
||||||
/**
|
/**
|
||||||
* Application preferences
|
* Application preferences
|
||||||
*/
|
*/
|
||||||
|
@ -340,20 +347,29 @@ public class Preferences extends PreferenceActivity implements OnPreferenceChang
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypts user password with SHA-512 and encodes it to Base64UrlSafe
|
* Shows an error message.
|
||||||
*
|
*
|
||||||
* @param password Password to be encrypted
|
* @param message Error message to show.
|
||||||
* @return Encrypted password
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
*/
|
*/
|
||||||
private String encryptPassword(String password) throws NoSuchAlgorithmException {
|
protected void error(String tag, String message, Exception ex, boolean sendException) {
|
||||||
String p;
|
new AlertDialog.Builder(this)
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
.setTitle(R.string.title_error_dialog)
|
||||||
md.update(password.getBytes());
|
.setMessage(message)
|
||||||
p = Base64.encodeBytes(md.digest());
|
.setNeutralButton(R.string.close_dialog,
|
||||||
p = p.replace('+', '-').replace('/', '_').replace('=', ' ').replaceAll("\\s+", "").trim();
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}).setIcon(R.drawable.erroricon).show();
|
||||||
|
|
||||||
return p;
|
if (ex != null) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
|
||||||
|
// Send exception details to Bugsense
|
||||||
|
if (sendException) {
|
||||||
|
BugSenseHandler.sendExceptionMessage(tag, message, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -362,16 +378,11 @@ public class Preferences extends PreferenceActivity implements OnPreferenceChang
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
*/
|
*/
|
||||||
public void upgradeCredentials() throws NoSuchAlgorithmException {
|
public void upgradeCredentials() throws NoSuchAlgorithmException {
|
||||||
String stars = getStarsSequence(STARS_LENGTH);
|
|
||||||
|
|
||||||
editor = prefs.edit();
|
editor = prefs.edit();
|
||||||
userPassword = prefs.getString(USERPASSWORDPREF, "");
|
userPassword = prefs.getString(USERPASSWORDPREF, "");
|
||||||
userPassword = encryptPassword(userPassword);
|
userPassword = Crypto.encryptPassword(userPassword);
|
||||||
editor.putString(USERPASSWORDPREF, userPassword);
|
editor.putString(USERPASSWORDPREF, userPassword);
|
||||||
editor.commit();
|
editor.commit();
|
||||||
|
|
||||||
userIDPref.setSummary(prefs.getString(USERIDPREF, ""));
|
|
||||||
userPasswordPref.setSummary(stars);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -513,7 +524,11 @@ public class Preferences extends PreferenceActivity implements OnPreferenceChang
|
||||||
*/
|
*/
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
userPassword = prefs.getString(USERPASSWORDPREF, "");
|
userPassword = prefs.getString(USERPASSWORDPREF, "");
|
||||||
//userPassword = encryptPassword(userPassword);
|
try {
|
||||||
|
userPassword = Crypto.encryptPassword(userPassword);
|
||||||
|
} catch (NoSuchAlgorithmException ex) {
|
||||||
|
error(TAG, ex.getMessage(), ex, true);
|
||||||
|
}
|
||||||
editor.putString(USERPASSWORDPREF, userPassword);
|
editor.putString(USERPASSWORDPREF, userPassword);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,8 +247,8 @@ public class SWADMain extends MenuExpandableListActivity {
|
||||||
lastVersion = prefs.getLastVersion();
|
lastVersion = prefs.getLastVersion();
|
||||||
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
|
currentVersion = getPackageManager().getPackageInfo(getPackageName(), 0).versionCode;
|
||||||
dbHelper.initializeDB();
|
dbHelper.initializeDB();
|
||||||
//lastVersion = 45;
|
//lastVersion = 51;
|
||||||
//currentVersion = 46;
|
//currentVersion = 52;
|
||||||
|
|
||||||
//If this is the first run, show configuration dialog
|
//If this is the first run, show configuration dialog
|
||||||
if (lastVersion == 0) {
|
if (lastVersion == 0) {
|
||||||
|
@ -273,12 +273,19 @@ public class SWADMain extends MenuExpandableListActivity {
|
||||||
//showUpgradeDialog();
|
//showUpgradeDialog();
|
||||||
dbHelper.upgradeDB(this);
|
dbHelper.upgradeDB(this);
|
||||||
|
|
||||||
|
//If the app is updating from an unencrypted user password version, encrypt user password
|
||||||
|
if(lastVersion < 52) {
|
||||||
|
prefs.upgradeCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
//If the app is updating from an unencrypted version, encrypt already downloaded notifications
|
//If the app is updating from an unencrypted version, encrypt already downloaded notifications
|
||||||
if (lastVersion < 45) {
|
if (lastVersion < 45) {
|
||||||
dbHelper.encryptNotifications();
|
dbHelper.encryptNotifications();
|
||||||
|
|
||||||
//If the app is updating from the bugged encrypted version,
|
/*
|
||||||
//re-encrypt the notifications using the new method
|
* If the app is updating from the bugged encrypted version,
|
||||||
|
* re-encrypt the notifications using the new method
|
||||||
|
*/
|
||||||
} else if (lastVersion == 45) {
|
} else if (lastVersion == 45) {
|
||||||
dbHelper.reencryptNotifications();
|
dbHelper.reencryptNotifications();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,18 +20,18 @@
|
||||||
package es.ugr.swad.swadroid.modules;
|
package es.ugr.swad.swadroid.modules;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
import es.ugr.swad.swadroid.Constants;
|
import es.ugr.swad.swadroid.Constants;
|
||||||
import es.ugr.swad.swadroid.R;
|
import es.ugr.swad.swadroid.R;
|
||||||
import es.ugr.swad.swadroid.model.User;
|
import es.ugr.swad.swadroid.model.User;
|
||||||
import es.ugr.swad.swadroid.modules.rollcall.RollCallUtil;
|
import es.ugr.swad.swadroid.utils.Utils;
|
||||||
import es.ugr.swad.swadroid.utils.Base64;
|
|
||||||
import org.ksoap2.SoapFault;
|
import org.ksoap2.SoapFault;
|
||||||
import org.ksoap2.serialization.KvmSerializable;
|
import org.ksoap2.serialization.KvmSerializable;
|
||||||
import org.ksoap2.serialization.SoapObject;
|
import org.ksoap2.serialization.SoapObject;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +48,7 @@ public class Login extends Module {
|
||||||
/**
|
/**
|
||||||
* Digest for user password.
|
* Digest for user password.
|
||||||
*/
|
*/
|
||||||
private MessageDigest md;
|
//private MessageDigest md;
|
||||||
/**
|
/**
|
||||||
* User ID.
|
* User ID.
|
||||||
*/
|
*/
|
||||||
|
@ -56,7 +56,7 @@ public class Login extends Module {
|
||||||
/**
|
/**
|
||||||
* User password.
|
* User password.
|
||||||
*/
|
*/
|
||||||
private String userPassword;
|
//private String userPassword;
|
||||||
/**
|
/**
|
||||||
* Login tag name for Logcat
|
* Login tag name for Logcat
|
||||||
*/
|
*/
|
||||||
|
@ -91,16 +91,6 @@ public class Login extends Module {
|
||||||
startConnection(false, progressDescription, progressTitle);
|
startConnection(false, progressDescription, progressTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInteger(String str) {
|
|
||||||
try {
|
|
||||||
Integer.parseInt(str);
|
|
||||||
return true;
|
|
||||||
} catch (NumberFormatException nfe) {
|
|
||||||
nfe.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects to SWAD and gets user data.
|
* Connects to SWAD and gets user data.
|
||||||
*
|
*
|
||||||
|
@ -123,27 +113,28 @@ public class Login extends Module {
|
||||||
userID = prefs.getUserID().trim();
|
userID = prefs.getUserID().trim();
|
||||||
|
|
||||||
//If the user ID is a DNI
|
//If the user ID is a DNI
|
||||||
if (RollCallUtil.isValidDni(userID)) {
|
if (Utils.isValidDni(userID)) {
|
||||||
//If the DNI has no letter, remove left zeros
|
//If the DNI has no letter, remove left zeros
|
||||||
if (isInteger(userID)) {
|
if (Utils.isInteger(userID)) {
|
||||||
userID = String.valueOf(Integer.parseInt(userID));
|
userID = String.valueOf(Integer.parseInt(userID));
|
||||||
|
|
||||||
//If the last position of the DNI is a char, remove it
|
//If the last position of the DNI is a char, remove it
|
||||||
} else if (isInteger(userID.substring(0, userID.length() - 1))) {
|
} else if (Utils.isInteger(userID.substring(0, userID.length() - 1))) {
|
||||||
userID = String.valueOf(Integer.parseInt(userID.substring(0, userID.length() - 1)));
|
userID = String.valueOf(Integer.parseInt(userID.substring(0, userID.length() - 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Encrypts user password with SHA-512 and encodes it to Base64UrlSafe
|
//Encrypts user password with SHA-512 and encodes it to Base64UrlSafe
|
||||||
md = MessageDigest.getInstance("SHA-512");
|
/*md = MessageDigest.getInstance("SHA-512");
|
||||||
md.update(prefs.getUserPassword().getBytes());
|
md.update(prefs.getUserPassword().getBytes());
|
||||||
userPassword = Base64.encodeBytes(md.digest());
|
userPassword = Base64.encodeBytes(md.digest());
|
||||||
userPassword = userPassword.replace('+', '-').replace('/', '_').replace('=', ' ').replaceAll("\\s+", "").trim();
|
userPassword = userPassword.replace('+', '-').replace('/', '_').replace('=', ' ').replaceAll("\\s+", "").trim();*/
|
||||||
|
|
||||||
//Creates webservice request, adds required params and sends request to webservice
|
//Creates webservice request, adds required params and sends request to webservice
|
||||||
createRequest();
|
createRequest();
|
||||||
addParam("userID", userID);
|
addParam("userID", userID);
|
||||||
addParam("userPassword", userPassword);
|
//addParam("userPassword", userPassword);
|
||||||
|
addParam("userPassword", prefs.getUserPassword());
|
||||||
addParam("appKey", Constants.SWAD_APP_KEY);
|
addParam("appKey", Constants.SWAD_APP_KEY);
|
||||||
sendRequest(User.class, true);
|
sendRequest(User.class, true);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import es.ugr.swad.swadroid.model.DataBaseHelper;
|
||||||
import es.ugr.swad.swadroid.model.SWADNotification;
|
import es.ugr.swad.swadroid.model.SWADNotification;
|
||||||
import es.ugr.swad.swadroid.model.User;
|
import es.ugr.swad.swadroid.model.User;
|
||||||
import es.ugr.swad.swadroid.ssl.SecureConnection;
|
import es.ugr.swad.swadroid.ssl.SecureConnection;
|
||||||
import es.ugr.swad.swadroid.utils.Base64;
|
|
||||||
import org.ksoap2.SoapEnvelope;
|
import org.ksoap2.SoapEnvelope;
|
||||||
import org.ksoap2.SoapFault;
|
import org.ksoap2.SoapFault;
|
||||||
import org.ksoap2.serialization.KvmSerializable;
|
import org.ksoap2.serialization.KvmSerializable;
|
||||||
|
@ -47,7 +46,6 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
@ -322,14 +320,14 @@ public class NotificationsSyncAdapterService extends Service {
|
||||||
Log.d(TAG, "Not logged");
|
Log.d(TAG, "Not logged");
|
||||||
|
|
||||||
METHOD_NAME = "loginByUserPasswordKey";
|
METHOD_NAME = "loginByUserPasswordKey";
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
/* MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||||
md.update(prefs.getUserPassword().getBytes());
|
md.update(prefs.getUserPassword().getBytes());
|
||||||
String userPassword = Base64.encodeBytes(md.digest());
|
String userPassword = Base64.encodeBytes(md.digest());
|
||||||
userPassword = userPassword.replace('+', '-').replace('/', '_').replace('=', ' ').replaceAll("\\s+", "").trim();
|
userPassword = userPassword.replace('+', '-').replace('/', '_').replace('=', ' ').replaceAll("\\s+", "").trim();*/
|
||||||
|
|
||||||
createRequest();
|
createRequest();
|
||||||
addParam("userID", prefs.getUserID());
|
addParam("userID", prefs.getUserID());
|
||||||
addParam("userPassword", userPassword);
|
addParam("userPassword", prefs.getUserPassword());
|
||||||
addParam("appKey", Constants.SWAD_APP_KEY);
|
addParam("appKey", Constants.SWAD_APP_KEY);
|
||||||
sendRequest(true);
|
sendRequest(true);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,9 @@ import javax.crypto.SecretKey;
|
||||||
import javax.crypto.SecretKeyFactory;
|
import javax.crypto.SecretKeyFactory;
|
||||||
import javax.crypto.spec.PBEKeySpec;
|
import javax.crypto.spec.PBEKeySpec;
|
||||||
import javax.crypto.spec.PBEParameterSpec;
|
import javax.crypto.spec.PBEParameterSpec;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.spec.AlgorithmParameterSpec;
|
import java.security.spec.AlgorithmParameterSpec;
|
||||||
import java.security.spec.KeySpec;
|
import java.security.spec.KeySpec;
|
||||||
|
|
||||||
|
@ -137,4 +140,21 @@ public class Crypto {
|
||||||
private static void appendHex(StringBuffer sb, byte b) {
|
private static void appendHex(StringBuffer sb, byte b) {
|
||||||
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
|
sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypts user password with SHA-512 and encodes it to Base64UrlSafe
|
||||||
|
*
|
||||||
|
* @param password Password to be encrypted
|
||||||
|
* @return Encrypted password
|
||||||
|
* @throws NoSuchAlgorithmException
|
||||||
|
*/
|
||||||
|
public static String encryptPassword(String password) throws NoSuchAlgorithmException {
|
||||||
|
String p;
|
||||||
|
MessageDigest md = MessageDigest.getInstance("SHA-512");
|
||||||
|
md.update(password.getBytes());
|
||||||
|
p = Base64.encodeBytes(md.digest());
|
||||||
|
p = p.replace('+', '-').replace('/', '_').replace('=', ' ').replaceAll("\\s+", "").trim();
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user