Explorar o código

Worked on encryption and decryption using AES, hashing, convert password to hash for login screen

Khubaib hai 3 meses
pai
achega
72bb8e15f4

+ 1 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -1,6 +1,7 @@
 <component name="InspectionProjectProfileManager">
   <profile version="1.0">
     <option name="myName" value="Project Default" />
+    <inspection_tool class="AndroidLintUnsafeImplicitIntentLaunch" enabled="false" level="ERROR" enabled_by_default="false" />
     <inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
       <option name="composableFile" value="true" />
       <option name="previewFile" value="true" />

+ 1 - 1
app/src/main/AndroidManifest.xml

@@ -6,7 +6,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
 
     <application
-        android:name="com.fastest.pass.app.App"
+        android:name=".app.App"
         android:allowBackup="true"
         android:dataExtractionRules="@xml/data_extraction_rules"
         android:fullBackupContent="@xml/backup_rules"

+ 21 - 9
app/src/main/java/com/fastest/pass/account/presentation/ui/components/AccountScreen.kt

@@ -1,5 +1,6 @@
 package com.fastest.pass.account.presentation.ui.components
 
+import android.util.Base64
 import android.util.Log
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.ExperimentalFoundationApi
@@ -79,8 +80,16 @@ import androidx.compose.ui.window.DialogProperties
 import com.fastest.pass.R
 import com.fastest.pass.account.domain.model.SliderPasswordType
 import com.fastest.pass.account.domain.model.sliderPasswordTypeList
+import com.fastest.pass.app.Utils
 import com.google.gson.annotations.SerializedName
+import okio.Utf8
 import java.security.MessageDigest
+import java.security.SecureRandom
+import javax.crypto.Cipher
+import javax.crypto.KeyGenerator
+import javax.crypto.SecretKey
+import javax.crypto.spec.IvParameterSpec
+import javax.crypto.spec.SecretKeySpec
 import kotlin.math.roundToInt
 import kotlin.random.Random
 
@@ -182,15 +191,18 @@ fun AccountScreen(clickType: (ClickType) -> Unit) {
         }
     }
 
-    val hash = sha256("FastestPass")
-    Log.d("hash_sha256", "input text: FastestPass")
-    Log.d("hash_sha256", "hash text: $hash")
-}
-
-
-fun sha256(input: String): String {
-    val bytes = MessageDigest.getInstance("SHA-256").digest(input.toByteArray())
-    return bytes.joinToString("") { "%02x".format(it) }
+//    val inputText = "test1234"
+//    val hash = Utils.sha256(inputText)
+//    val plainText = "FastestPass"
+//
+//    val encryptedData = Utils.encryptData(
+//        plainText,
+//        "1234567890abcdef",
+//        ivString = "abcdefghijklmnop",
+//        saltString = "saltString"
+//    )
+//
+//    val decryptedData = Utils.decryptData(encryptedData.first, encryptedData.second, "1234567890abcdef")
 }
 
 @Composable

+ 1 - 1
app/src/main/java/com/fastest/pass/app/BaseUseCase.kt

@@ -3,7 +3,7 @@ package com.fastest.pass.app
 sealed class Result<out T> {
     data class Success<out T>(val data: T) : Result<T>()
     data class Failure(val exception: Throwable) : Result<Nothing>()
-    object Loading : Result<Nothing>()
+    data object Loading : Result<Nothing>()
 }
 
 abstract class BaseUseCase<in Params, ResultType> {

+ 67 - 0
app/src/main/java/com/fastest/pass/app/Utils.kt

@@ -0,0 +1,67 @@
+package com.fastest.pass.app
+
+import android.util.Base64
+import java.security.MessageDigest
+import javax.crypto.Cipher
+import javax.crypto.KeyGenerator
+import javax.crypto.SecretKey
+import javax.crypto.spec.IvParameterSpec
+import javax.crypto.spec.SecretKeySpec
+
+class Utils {
+    companion object {
+
+        fun hashing_sha256(text: String): String {
+            val bytes = MessageDigest.getInstance("SHA-256").digest(text.toByteArray())
+            return bytes.joinToString("") { "%02x".format(it) }
+        }
+
+        fun sha256(input: String): String {
+            val bytes = MessageDigest.getInstance("SHA-256").digest(input.toByteArray())
+            return bytes.joinToString("") { "%02x".format(it) }
+        }
+
+        fun generateKey() : SecretKey {
+            val keyGen = KeyGenerator.getInstance("AES")
+            keyGen.init(256)
+            return keyGen.generateKey()
+        }
+
+        fun encryptData(
+            data: String,
+            secretKeyString: String,
+            ivString: String,
+            saltString: String
+        ) : Pair<String, String> {
+            val ivKey: IvParameterSpec = IvParameterSpec(ivString.toByteArray(Charsets.UTF_8))
+            val secKey: SecretKey = SecretKeySpec(secretKeyString.toByteArray(Charsets.UTF_8), "AES")
+            val encryptionWithSalt = saltString.toByteArray(Charsets.UTF_8) + data.toByteArray(Charsets.UTF_8)
+
+            val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
+            cipher.init(Cipher.ENCRYPT_MODE, secKey, ivKey)
+
+            val encryptedData = cipher.doFinal(data.toByteArray())
+
+//    val encryptedData = cipher.doFinal(data.toByteArray())
+            val ivBase64 = Base64.encodeToString(ivString.toByteArray(Charsets.UTF_8), Base64.DEFAULT)
+            val encryptedDataBase64 = Base64.encodeToString(encryptedData, Base64.DEFAULT)
+
+            return Pair(ivBase64, encryptedDataBase64)
+        }
+
+        fun decryptData(ivBase64: String, encryptedBase64: String, secretKeyString: String) : String {
+            val iv = Base64.decode(ivBase64, Base64.DEFAULT)
+            val encryptedBytes = Base64.decode(encryptedBase64, Base64.DEFAULT)
+            val ivSpec = IvParameterSpec(iv)
+            val secKey: SecretKey = SecretKeySpec(secretKeyString.toByteArray(Charsets.UTF_8), "AES")
+
+            val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
+            cipher.init(Cipher.DECRYPT_MODE, secKey, ivSpec)
+
+            val decryptedData = cipher.doFinal(encryptedBytes)
+            val decryptedString = String(decryptedData, Charsets.UTF_8)
+
+            return decryptedString
+        }
+    }
+}

+ 2 - 3
app/src/main/java/com/fastest/pass/login/presentation/ui/LoginFragment.kt

@@ -58,7 +58,6 @@ class LoginFragment : BaseFragment() {
 
                             val loginResponse = viewmodel.loginResponse.value
 
-
                             loginResponse.response?.data?.let {
                                 viewmodel.navigateTo(LoginRoute.OpenDashBoardScreen)
                             }
@@ -81,11 +80,11 @@ class LoginFragment : BaseFragment() {
                                         viewmodel.navigateTo(LoginRoute.OpenDashBoardScreen)
                                     }
                                     ClickType.LOGIN_CLICK -> {
-                                        Log.d("test_api_login", "LOGIN_CLICK => LoginFragment")
-                                        viewmodel.login("eng.asix@gmail.com", "password")
+//                                        viewmodel.login("eng.asix@gmail.com", "password")
                                     }
                                 }
                             }, onLoginClickCredentials = { email , password ->
+                                Log.d("test_api_login", "onLoginClickCredentials => LoginFragment : $email , $password")
                                 viewmodel.login(email, password)
                             })
 

+ 12 - 4
app/src/main/java/com/fastest/pass/login/presentation/ui/components/LoginScreen.kt

@@ -65,9 +65,11 @@ import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import com.fastest.pass.R
+import com.fastest.pass.app.Utils
 import com.fastest.views.ShowCustomSnackBar
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
+import java.security.MessageDigest
 
 enum class ClickType {
     SIGNUP_CLICK,
@@ -144,7 +146,9 @@ fun LoginScreen(
                     onLoginClickCredentials = { email, password ->
                     onLoginClickCredentials.invoke(email, password)
                 },
-                    snackBarStateRed = snackBarStateRed
+                    snackBarStateRed = snackBarStateRed,
+                    keyboardController,
+                    focusManager
                 )
                 ForgotPasswordText() { clickType ->
                     clickType(clickType)
@@ -407,7 +411,9 @@ fun ColumnScope.LoginButton(
     email: String,
     password: String,
     onLoginClickCredentials: (String, String) -> Unit,
-    snackBarStateRed: SnackbarHostState
+    snackBarStateRed: SnackbarHostState,
+    keyboardController: SoftwareKeyboardController?,
+    focusManager: FocusManager
 ) {
     val coroutineScope = rememberCoroutineScope()
     val context = LocalContext.current
@@ -420,11 +426,13 @@ fun ColumnScope.LoginButton(
             .height(60.dp)
             .clickable() { },
         onClick = {
-            Log.d("test_api_login", "ClickType.LOGIN_CLICK")
 //            clickType.invoke(ClickType.LOGIN_CLICK)
 
             if (email.isNotEmpty() && password.isNotEmpty()) {
-                onLoginClickCredentials.invoke(email, password)
+                focusManager.clearFocus()
+                keyboardController?.hide()
+                val hashPassword = Utils.hashing_sha256(password)
+                onLoginClickCredentials.invoke(email, hashPassword)
             } else if (email.isEmpty()) {
                 coroutineScope.launch {
                     snackBarStateRed.showSnackbar(context.getString(R.string.email_field_req))

+ 1 - 0
app/src/main/java/com/fastest/pass/login/presentation/viewmodels/LoginViewModel.kt

@@ -15,6 +15,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.launch
 import javax.inject.Inject
 import com.fastest.pass.app.Result
+
 @HiltViewModel
 class LoginViewModel @Inject constructor(
     private val loginUseCase: LoginUseCase