🔐 Store credentials

This commit is contained in:
Mylloon 2021-08-28 13:47:32 +02:00
parent 34eb6f2ec4
commit 7d89a8d409
2 changed files with 109 additions and 33 deletions

View file

@ -1,11 +1,13 @@
package com.mylloon.mobidl package com.mylloon.mobidl
import android.content.Context.MODE_PRIVATE
import android.os.Build import android.os.Build
import android.security.keystore.KeyProperties import android.security.keystore.KeyProperties
import javax.crypto.Cipher import javax.crypto.Cipher
import android.security.keystore.KeyGenParameterSpec import android.security.keystore.KeyGenParameterSpec
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import java.security.* import java.security.*
import java.util.*
class Credentials { class Credentials {
@ -13,6 +15,7 @@ class Credentials {
private val provider = "AndroidKeyStore" // location of the key private val provider = "AndroidKeyStore" // location of the key
private val aliasKeyStore = "MobiDL" // name of the key private val aliasKeyStore = "MobiDL" // name of the key
private val transformation = "RSA/ECB/PKCS1Padding" // 'type' of the key private val transformation = "RSA/ECB/PKCS1Padding" // 'type' of the key
private val sharedPref = "com.mylloon.MobiDL" // shared pref name
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
fun generateKey() { // generate RSA Keys fun generateKey() { // generate RSA Keys
@ -56,4 +59,43 @@ class Credentials {
val decryptedBytes = cipher.doFinal(message) val decryptedBytes = cipher.doFinal(message)
return decryptedBytes.decodeToString() return decryptedBytes.decodeToString()
} }
fun store(user: String, password: String) { // Store combo encrypted user/pass in shared preferences
val userEncrypted = encrypt(user) // encrypt user
val passwordEncrypted = encrypt(password) // encrypt password
val context = MainActivity.applicationContext() // get app context
// show key : Base64.getEncoder().encodeToString(encryptedData)
// write encrypted data to the app preference
val sharedPref = context.getSharedPreferences(sharedPref, MODE_PRIVATE)
with(sharedPref?.edit()) {
this?.putString("username", userEncrypted.contentToString())
this?.putString("password", passwordEncrypted.contentToString())
this?.apply()
}
}
fun get(type: Int): String? { // type 0 -> username | type 1 -> password [ return null if there is nothing
val context = MainActivity.applicationContext() // get app context
// read encrypted data from the app preference
val sharedPref = context.getSharedPreferences(sharedPref, MODE_PRIVATE)
var data: String? = null
when (type) {
0 -> { data = sharedPref.getString("username", null) }
1 -> { data = sharedPref.getString("password", null) }
}
return if (data != null) {
val split: List<String> =
data.substring(1, data.length - 1).split(", ")
val array = ByteArray(split.size)
for (i in split.indices) {
array[i] = split[i].toByte()
}
decrypt(array)
} else null
}
} }

View file

@ -2,6 +2,7 @@ package com.mylloon.mobidl
import android.Manifest import android.Manifest
import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -24,6 +25,18 @@ class MainActivity : AppCompatActivity() {
private var inSettings: Boolean = false // by default your not in settings page private var inSettings: Boolean = false // by default your not in settings page
var prefs: SharedPreferences? = null // first run detection var prefs: SharedPreferences? = null // first run detection
init {
instance = this
}
companion object {
private var instance: MainActivity? = null
fun applicationContext() : Context {
return instance!!.applicationContext
}
}
private fun toggleSettingsButtonVisibility() { // Change Settings button visibility private fun toggleSettingsButtonVisibility() { // Change Settings button visibility
val visibility: Boolean = settingsButton?.findItem(R.id.settingsButton)?.isVisible == true val visibility: Boolean = settingsButton?.findItem(R.id.settingsButton)?.isVisible == true
settingsButton?.findItem(R.id.settingsButton)?.isVisible = !visibility settingsButton?.findItem(R.id.settingsButton)?.isVisible = !visibility
@ -32,39 +45,61 @@ class MainActivity : AppCompatActivity() {
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) { // Main function override fun onCreate(savedInstanceState: Bundle?) { // Main function
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login) // show login page
prefs = getSharedPreferences("com.mylloon.MobiDL", MODE_PRIVATE) prefs = getSharedPreferences("com.mylloon.MobiDL", MODE_PRIVATE)
val userInput = findViewById<EditText>(R.id.usernameInput) fun loginPage() {
val passwordInput = findViewById<EditText>(R.id.passwordInput) setContentView(R.layout.activity_login) // show login page
val buttonInput = findViewById<Button>(R.id.loginButton)
fun changeButtonStatus() { // function who enable/disable the login button val userInput = findViewById<EditText>(R.id.usernameInput)
val text1: String = userInput.text.toString() val passwordInput = findViewById<EditText>(R.id.passwordInput)
val text2: String = passwordInput.text.toString() val buttonInput = findViewById<Button>(R.id.loginButton)
buttonInput.isEnabled = text1.isNotEmpty() && text2.isNotEmpty()
fun changeButtonStatus() { // function who enable/disable the login button
val text1: String = userInput.text.toString()
val text2: String = passwordInput.text.toString()
buttonInput.isEnabled = text1.isNotEmpty() && text2.isNotEmpty()
}
userInput.addTextChangedListener(object : TextWatcher { // looking user input changes
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(editable: Editable) {
changeButtonStatus()
}
})
passwordInput.addTextChangedListener(object :
TextWatcher { // looking password input changes
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(editable: Editable) {
changeButtonStatus()
}
})
buttonInput.setOnClickListener { // show main page when clicking the login button
val user = userInput.text.toString()
val password = passwordInput.text.toString()
Credentials().store(user, password)
mainPage()
}
} }
if (Credentials().get(0) == null) { // test if credentials have already been registered
userInput.addTextChangedListener(object : TextWatcher { // looking user input changes loginPage() // if no ask for
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} } else {
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} mainPage() // if yes go to main page
override fun afterTextChanged(editable: Editable) { changeButtonStatus() }
})
passwordInput.addTextChangedListener(object : TextWatcher { // looking password input changes
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(editable: Editable) { changeButtonStatus() }
})
buttonInput.setOnClickListener { // show main page when clicking the login button
setContentView(R.layout.activity_main)
toggleSettingsButtonVisibility()
callScript() // call script
} }
} }
private fun mainPage() {
setContentView(R.layout.activity_main)
toggleSettingsButtonVisibility()
// user = Credentials().get(0).toString()
// password = Credentials().get(1).toString()
// callScript(user, password) // call script
}
@RequiresApi(Build.VERSION_CODES.M) @RequiresApi(Build.VERSION_CODES.M)
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@ -72,7 +107,7 @@ class MainActivity : AppCompatActivity() {
println("Generate RSA keys...") println("Generate RSA keys...")
Credentials().generateKey() Credentials().generateKey()
println("Done!") println("Done!")
prefs!!.edit().putBoolean("firstrun", false).commit() // first run done, now the next ones won't be "first". prefs!!.edit().putBoolean("firstrun", false).apply() // first run done, now the next ones won't be "first".
} }
} }
@ -95,20 +130,19 @@ class MainActivity : AppCompatActivity() {
override fun onBackPressed() { // allow user to use back button to go back to main page override fun onBackPressed() { // allow user to use back button to go back to main page
if (inSettings) { if (inSettings) {
setContentView(R.layout.activity_main) mainPage()
toggleSettingsButtonVisibility()
inSettings = false inSettings = false
} else super.onBackPressed() } else super.onBackPressed()
} }
private fun callScript() { private fun callScript(user: String, password: String) {
if(ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.INTERNET) if(ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.INTERNET)
!= PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this@MainActivity, "No permission to use internet", Toast.LENGTH_SHORT).show() Toast.makeText(this@MainActivity, "No permission to use internet", Toast.LENGTH_SHORT).show()
this.finishAffinity() this.finishAffinity()
} else { } else {
println("test du script") println("test du script")
Scraper("Mylloon", "Hd59NGB4Me8WSM", app = "Plex", debug = true).search() Scraper(user, password, app = "Plex", debug = true).search()
} }
} }
} }