Skip to content

Commit f75a4d8

Browse files
committed
QuickPass 2.0 beta 9 p1
- Password encrypting! -- You can now encrypt your password to know that nobody will see it even if hack your root storage data - Password View and Adding design improved - All new main screen -- Smooth panel for all passwords -- Statistic copied to main screen - Optimization for some constructions - Fixes - Translation updated - Duration of animation adjusted - Added back buttons - Smooth transitions through screens - UX update -- You can now restore your pass (Check Setting =)) -- Alert screen for log out in Account page - Settings update -- Auto asking permission for writing to storage -- New icons for export/import -- Tips for export/import now always available - Libraries updated (16/10/20)
1 parent 6cbc12d commit f75a4d8

13 files changed

+378
-133
lines changed

app/src/main/java/com/mikhailgrigorev/quickpass/EditPassActivity.kt

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class EditPassActivity : AppCompatActivity() {
3737
private var useNumbers = false
3838
private lateinit var login: String
3939
private lateinit var passName: String
40-
4140
@SuppressLint("Recycle", "SetTextI18n", "ClickableViewAccessibility")
4241
override fun onCreate(savedInstanceState: Bundle?) {
4342
val pref = getSharedPreferences(_preferenceFile, Context.MODE_PRIVATE)
@@ -139,6 +138,7 @@ class EditPassActivity : AppCompatActivity() {
139138
pdbHelper.KEY_TIME,
140139
pdbHelper.KEY_DESC,
141140
pdbHelper.KEY_TAGS,
141+
pdbHelper.KEY_CIPHER,
142142
pdbHelper.KEY_LOGIN
143143
),
144144
"NAME = ?", arrayOf(passName),
@@ -154,11 +154,18 @@ class EditPassActivity : AppCompatActivity() {
154154
val descIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_DESC)
155155
val tagsIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_TAGS)
156156
val loginIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_LOGIN)
157+
val cryptIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_CIPHER)
157158
do {
158159
dbLogin = pCursor.getString(nameIndex).toString()
159160
helloTextId.text = dbLogin
160161
newNameField.setText(dbLogin)
162+
val dbCryptIndex = pCursor.getString(cryptIndex).toString()
161163
dbPassword = pCursor.getString(passIndex).toString()
164+
if (dbCryptIndex == "crypted") {
165+
cryptToggle.isChecked = true
166+
val pm = PasswordManager()
167+
dbPassword = pm.decrypt(dbPassword).toString()
168+
}
162169
genPasswordIdField.setText(dbPassword)
163170
if (dbPassword != "") {
164171
length = dbPassword.length
@@ -183,6 +190,7 @@ class EditPassActivity : AppCompatActivity() {
183190
symToggles.isChecked = myPasswordManager.isSymbols(genPasswordIdField.text.toString())
184191
}
185192
val db2FAIndex = pCursor.getString(aIndex).toString()
193+
186194
if (db2FAIndex == "1") {
187195
authToggle.isChecked = true
188196
}
@@ -424,8 +432,26 @@ class EditPassActivity : AppCompatActivity() {
424432
}
425433
else {
426434
val contentValues = ContentValues()
427-
contentValues.put(pdbHelper.KEY_NAME, newNameField.text.toString())
428435
contentValues.put(pdbHelper.KEY_PASS, genPasswordIdField.text.toString())
436+
437+
val pm = PasswordManager()
438+
439+
if (cryptToggle.isChecked) {
440+
val dc = pm.encrypt(genPasswordIdField.text.toString())
441+
contentValues.put(
442+
pdbHelper.KEY_PASS,
443+
dc)
444+
contentValues.put(pdbHelper.KEY_CIPHER, "crypted")
445+
}
446+
else{
447+
contentValues.put(pdbHelper.KEY_PASS, genPasswordIdField.text.toString())
448+
contentValues.put(pdbHelper.KEY_CIPHER, "none")
449+
}
450+
451+
452+
453+
454+
contentValues.put(pdbHelper.KEY_NAME, newNameField.text.toString())
429455
contentValues.put(pdbHelper.KEY_LOGIN, emailField.text.toString())
430456
var keyFA = "0"
431457
if (authToggle.isChecked)
@@ -451,6 +477,7 @@ class EditPassActivity : AppCompatActivity() {
451477
putString("__PASSNAME", newNameField.text.toString())
452478
commit()
453479
}
480+
pdbHelper.close()
454481
setResult(1, intent)
455482
finish()
456483
}

app/src/main/java/com/mikhailgrigorev/quickpass/NewPasswordActivity.kt

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,20 @@ class NewPasswordActivity : AppCompatActivity() {
371371
} else {
372372
contentValues.put(pdbHelper.KEY_ID, Random.nextInt(0, 10000))
373373
contentValues.put(pdbHelper.KEY_NAME, newNameField.text.toString())
374-
contentValues.put(pdbHelper.KEY_PASS, genPasswordIdField.text.toString())
374+
val pm = PasswordManager()
375+
if (cryptToggle.isChecked) {
376+
val dc = pm.encrypt(genPasswordIdField.text.toString())
377+
contentValues.put(
378+
pdbHelper.KEY_PASS,
379+
dc)
380+
contentValues.put(pdbHelper.KEY_CIPHER, "crypted")
381+
}
382+
else{
383+
contentValues.put(pdbHelper.KEY_PASS, genPasswordIdField.text.toString())
384+
contentValues.put(pdbHelper.KEY_CIPHER, "none")
385+
}
386+
387+
375388
contentValues.put(pdbHelper.KEY_TAGS, keyWordsField.text.toString())
376389
contentValues.put(pdbHelper.KEY_LOGIN, emailField.text.toString())
377390
var keyFA = "0"
@@ -385,11 +398,12 @@ class NewPasswordActivity : AppCompatActivity() {
385398
contentValues.put(pdbHelper.KEY_TIME, getDateTime())
386399
contentValues.put(pdbHelper.KEY_DESC, noteField.text.toString())
387400
passDataBase.insert(pdbHelper.TABLE_USERS, null, contentValues)
388-
val intent = Intent(this, PassGenActivity::class.java)
389-
intent.putExtra("login", login)
390401

402+
val intent = Intent()
403+
intent.putExtra("login", login)
391404

392-
startActivity(intent)
405+
pdbHelper.close()
406+
setResult(1, intent)
393407
finish()
394408
}
395409
}

app/src/main/java/com/mikhailgrigorev/quickpass/PassGenActivity.kt

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ class PassGenActivity : AppCompatActivity() {
104104
}
105105
setContentView(R.layout.activity_pass_gen)
106106

107-
108-
109107
val args: Bundle? = intent.extras
110108
login = args?.get("login").toString()
111109
val newLogin = getSharedPreferences(_preferenceFile, Context.MODE_PRIVATE).getString(_keyUsername, login)
@@ -192,8 +190,8 @@ class PassGenActivity : AppCompatActivity() {
192190
pdbHelper.KEY_NAME, pdbHelper.KEY_PASS,
193191
pdbHelper.KEY_TIME, pdbHelper.KEY_2FA,
194192
pdbHelper.KEY_TAGS, pdbHelper.KEY_GROUPS,
195-
pdbHelper.KEY_USE_TIME
196-
),
193+
pdbHelper.KEY_USE_TIME, pdbHelper.KEY_CIPHER
194+
),
197195
null, null,
198196
null, null, null
199197
)
@@ -217,7 +215,7 @@ class PassGenActivity : AppCompatActivity() {
217215
val tagsIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_TAGS)
218216
val groupIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_GROUPS)
219217
val timeIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_TIME)
220-
val tIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_USE_TIME)
218+
val cIndex: Int = pCursor.getColumnIndex(pdbHelper.KEY_CIPHER)
221219
var j = 0
222220
do {
223221
val pass = pCursor.getString(passIndex).toString()
@@ -258,12 +256,12 @@ class PassGenActivity : AppCompatActivity() {
258256
}
259257

260258
val fa = pCursor.getString(aIndex).toString()
261-
val tl= pCursor.getString(tIndex).toString()
259+
val tl= pCursor.getString(cIndex).toString()
262260

263261
if(fa == "1")
264262
faNum += 1
265263

266-
if(tl == "1")
264+
if(tl == "crypted")
267265
tlNum += 1
268266
when (qualityNum) {
269267
"1" -> safePass += 1

app/src/main/java/com/mikhailgrigorev/quickpass/PasswordManager.kt

Lines changed: 78 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
package com.mikhailgrigorev.quickpass
2+
3+
import android.util.Base64
24
import java.security.SecureRandom
35
import java.util.*
6+
import javax.crypto.Cipher
7+
import javax.crypto.SecretKeyFactory
8+
import javax.crypto.spec.IvParameterSpec
9+
import javax.crypto.spec.PBEKeySpec
10+
import javax.crypto.spec.SecretKeySpec
411
import kotlin.math.max
512

613
class PasswordManager {
@@ -11,11 +18,13 @@ class PasswordManager {
1118
private val maxPasswordLength : Float = 20F //Max password length that my app creates
1219
private val maxPasswordFactor : Float = 13F //Max password factor based on chars inside password
1320

14-
fun generatePassword(isWithLetters: Boolean,
15-
isWithUppercase: Boolean,
16-
isWithNumbers: Boolean,
17-
isWithSpecial: Boolean,
18-
length: Int) : String {
21+
fun generatePassword(
22+
isWithLetters: Boolean,
23+
isWithUppercase: Boolean,
24+
isWithNumbers: Boolean,
25+
isWithSpecial: Boolean,
26+
length: Int
27+
) : String {
1928

2029
var result = ""
2130
var i = 0
@@ -65,10 +74,10 @@ class PasswordManager {
6574
var factor = 0
6675
val length = passwordToTest.length
6776

68-
if( passwordToTest.matches( Regex(".*["+this.letters+"].*") ) ) { factor += 3 }
69-
if( passwordToTest.matches( Regex(".*["+this.uppercaseLetters+"].*") ) ){ factor += 3 }
70-
if( passwordToTest.matches( Regex(".*["+this.numbers+"].*") ) ){ factor += 3 }
71-
if( passwordToTest.matches( Regex(".*["+this.special+"].*") ) ){ factor += 4 }
77+
if( passwordToTest.matches(Regex(".*[" + this.letters + "].*")) ) { factor += 3 }
78+
if( passwordToTest.matches(Regex(".*[" + this.uppercaseLetters + "].*")) ){ factor += 3 }
79+
if( passwordToTest.matches(Regex(".*[" + this.numbers + "].*")) ){ factor += 3 }
80+
if( passwordToTest.matches(Regex(".*[" + this.special + "].*")) ){ factor += 4 }
7281

7382
if((passwordToTest.length == 4) and (isNumbers(passwordToTest))
7483
and (!isLetters(passwordToTest))
@@ -85,10 +94,10 @@ class PasswordManager {
8594
var factor = 0
8695
val length = passwordToTest.length
8796

88-
if( passwordToTest.matches( Regex(".*["+this.letters+"].*") ) ) { factor += 3 }
89-
if( passwordToTest.matches( Regex(".*["+this.uppercaseLetters+"].*") ) ){ factor += 3 }
90-
if( passwordToTest.matches( Regex(".*["+this.numbers+"].*") ) ){ factor += 3 }
91-
if( passwordToTest.matches( Regex(".*["+this.special+"].*") ) ){ factor += 4 }
97+
if( passwordToTest.matches(Regex(".*[" + this.letters + "].*")) ) { factor += 3 }
98+
if( passwordToTest.matches(Regex(".*[" + this.uppercaseLetters + "].*")) ){ factor += 3 }
99+
if( passwordToTest.matches(Regex(".*[" + this.numbers + "].*")) ){ factor += 3 }
100+
if( passwordToTest.matches(Regex(".*[" + this.special + "].*")) ){ factor += 4 }
92101

93102
val strong = (factor*length)/(maxPasswordFactor*max(maxPasswordLength, length.toFloat()))
94103

@@ -107,18 +116,70 @@ class PasswordManager {
107116

108117

109118
fun isLetters(passwordToTest: String) : Boolean{
110-
return passwordToTest.matches( Regex(".*["+this.letters+"].*") )
119+
return passwordToTest.matches(Regex(".*[" + this.letters + "].*"))
111120
}
112121

113122
fun isUpperCase(passwordToTest: String) : Boolean{
114-
return passwordToTest.matches( Regex(".*["+this.uppercaseLetters+"].*") )
123+
return passwordToTest.matches(Regex(".*[" + this.uppercaseLetters + "].*"))
115124
}
116125

117126
fun isNumbers(passwordToTest: String) : Boolean{
118-
return passwordToTest.matches( Regex(".*["+this.numbers+"].*") )
127+
return passwordToTest.matches(Regex(".*[" + this.numbers + "].*"))
119128
}
120129

121130
fun isSymbols(passwordToTest: String) : Boolean{
122-
return passwordToTest.matches( Regex(".*["+this.special+"].*") )
131+
return passwordToTest.matches(Regex(".*[" + this.special + "].*"))
132+
}
133+
134+
private val RANDOM: Random = SecureRandom()
135+
136+
private fun getNextSalt(): ByteArray? {
137+
val salt = ByteArray(16)
138+
RANDOM.nextBytes(salt)
139+
return salt
140+
}
141+
142+
fun encrypt(strToEncrypt: String) : String?
143+
{
144+
try
145+
{
146+
val ivParameterSpec = IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
147+
148+
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
149+
val spec = PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
150+
val tmp = factory.generateSecret(spec)
151+
val secretKey = SecretKeySpec(tmp.encoded, "AES")
152+
153+
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
154+
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec)
155+
return Base64.encodeToString(cipher.doFinal(strToEncrypt.toByteArray(Charsets.UTF_8)), Base64.DEFAULT)
156+
}
157+
catch (e: Exception)
158+
{
159+
println("Error while encrypting: $e")
160+
}
161+
return null
123162
}
163+
164+
fun decrypt(strToDecrypt : String) : String? {
165+
try
166+
{
167+
168+
val ivParameterSpec = IvParameterSpec(Base64.decode(iv, Base64.DEFAULT))
169+
170+
val factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1")
171+
val spec = PBEKeySpec(secretKey.toCharArray(), Base64.decode(salt, Base64.DEFAULT), 10000, 256)
172+
val tmp = factory.generateSecret(spec);
173+
val secretKey = SecretKeySpec(tmp.encoded, "AES")
174+
175+
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
176+
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
177+
return String(cipher.doFinal(Base64.decode(strToDecrypt, Base64.DEFAULT)))
178+
}
179+
catch (e : Exception) {
180+
println("Error while decrypting: $e");
181+
}
182+
return null
183+
}
184+
124185
}

0 commit comments

Comments
 (0)