Brute forcing Passwords in Android
A brute force attack is a hacking method that uses trial and error to crack passwords, login credentials, and encryption keys. It is a simple yet reliable tactic for gaining unauthorized access to individual accounts and organizations’ systems and networks. The hacker tries multiple usernames and passwords, often using a computer to test a wide range of combinations, until they find the correct login information.
The name "brute force" comes from attackers using excessively forceful attempts to gain access to user accounts. Despite being an old cyberattack method, brute force attacks are tried and tested and remain a popular tactic with hackers.
Let's understand in the Android App
To prevent brute force attacks without deleting anything in the given code, you can implement several key strategies such as limiting login attempts, introducing exponential backoff, logging suspicious activity, and using CAPTCHAs or additional multi-factor authentication mechanisms. Below are the specific steps applied to your existing code:
Rate Limiting & Account Lockout: Limit the number of failed login attempts to a certain threshold and lock the account for a period of time after the limit is reached. You can store the number of failed attempts in
SharedPreferences
or a server-side database.Add a CAPTCHA: After a certain number of failed login attempts, display a CAPTCHA for human verification before proceeding further.
Delay Mechanism (Exponential Backoff): Add a delay (increasing over time) after each failed login attempt to slow down brute-force attacks.
Supppose you are making a login dashboard with username and password
Step 1: Define Shared Preferences to Track Failed Attempts
Step 2: Check Failed Attempts and Lock Time
Modify the start of the checkLogin()
method to check if the account is locked due to too many failed attempts.
Step 3: Apply Exponential Backoff
After multiple failed attempts, lock the account for a specific duration that increases after each failed attempt.
Step 4: Introduce CAPTCHA after multiple failed attempts
If you want to add a CAPTCHA after, say, 3 failed attempts:
Step 5: Add CAPTCHA Validation (Placeholder)
You can add a placeholder for the CAPTCHA validation function:
Step 6: Reset Failed Attempts After Successful Login
Once the login is successful, reset the failed_attempts
counter:
Step 7: Logging Suspicious Activity
Log failed login attempts on the server side or locally to analyze patterns that may indicate brute force attempts.
By following this approach, you can prevent brute-force attacks while keeping all your original logic intact.
Have an Example here-I am here writing the logic only
public class Login extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login1);
login = (Button) findViewById(R.id.login); // continue on hitloginPrefsBF = getSharedPreferences("loginPrefsBruteforce", MODE_PRIVATE);
long lockEndTime = loginPrefsBF.getLong("lock_time_count", 0);
long currentTime = System.currentTimeMillis();
Log.d("CHECKIKLOCKING", "onCreate: lockEndTime=" + lockEndTime + " currentTime=" + currentTime);
if (lockEndTime > currentTime) {
long remainingLockTime = lockEndTime - currentTime;
Log.d("remainingLockTime", "Remaining lock time: " + remainingLockTime);
if (remainingLockTime > 0) {
lockLoginButton(remainingLockTime);
} else {
Log.e("CountDownTimer", "Remaining lock time is negative or zero.");
}
}private void checkLogin() {
EMPNO = mobile_number.getText().toString();
CODE = password.getText().toString();SharedPreferences.Editor editor = loginPrefsBF.edit();
editor.putInt("failed_attempts", 0); // Reset failed attempts
editor.apply();StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.forget_password,new Response.Listener<String>() {
@Override
public void onResponse(String response) {
loading.dismiss();
Log.d("forget_response:", "onResponse: " + response);
try {
//Creating the json object from the response
JSONObject jsonResponse = new JSONObject(response);
int msg = jsonResponse.getInt("success");
String suucess= jsonResponse.getString("1");if(suucess){write your code to call the intent} else {
Log.d("FAILURE", "onResponse: "+success);
// Login failure (Invalid credentials)
Log.d("Login Failure", "Invalid credentials or other failure."); // Log this case
failedAttempts++;
// Apply exponential backoff after 3 failed attempts
if (failedAttempts >= 3) {
long lockDuration = 10000 * (failedAttempts - 2) * (failedAttempts - 2); // 10s * (failedAttempts - 2)^2
long lockEndTime = System.currentTimeMillis() + lockDuration;
SharedPreferences.Editor editor = loginPrefsBF.edit();
editor.putInt("failed_attempts", failedAttempts);
editor.putLong("lock_time_count", lockEndTime);
boolean isSaved = editor.commit(); // Use commit for synchronous saving
Log.d("SaveStatus", "Saved lockEndTime: " + lockEndTime + ", Status: " + isSaved);
// Disable the login button
lockLoginButton(lockDuration);
Toast.makeText(Login.this, "Too many failed attempts. Account locked for " + lockDuration / 1000 + " seconds.", Toast.LENGTH_LONG).show();
}
if (failedAttempts >= 3) {
// Show CAPTCHA here
validateCaptcha();
} else {
Toast.makeText(Login.this, "Invalid Credentials", Toast.LENGTH_LONG).show();
}}}
}private void lockLoginButton(long lockDuration) {
login.setEnabled(false); // Disable the button
login.setTextColor(Color.RED);
// Using CountDownTimer instead of Handler for better performance and handling long delays
new CountDownTimer(lockDuration, 1000) {
public void onTick(long millisUntilFinished) {
// You can update the UI every tick if needed
login.setText("Locked for " + millisUntilFinished / 1000 + "s");
}
public void onFinish() {
login.setEnabled(true); // Enable the button after lock duration
login.setText("Login"); // Reset text
login.setTextColor(Color.YELLOW);
Toast.makeText(Login.this, "You can now attempt to login again.", Toast.LENGTH_SHORT).show();
}
}.start();
}
}
Post a Comment
0Comments