1
1
package com.mikhailgrigorev.quickpass
2
+
3
+ import android.util.Base64
2
4
import java.security.SecureRandom
3
5
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
4
11
import kotlin.math.max
5
12
6
13
class PasswordManager {
@@ -11,11 +18,13 @@ class PasswordManager {
11
18
private val maxPasswordLength : Float = 20F // Max password length that my app creates
12
19
private val maxPasswordFactor : Float = 13F // Max password factor based on chars inside password
13
20
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 {
19
28
20
29
var result = " "
21
30
var i = 0
@@ -65,10 +74,10 @@ class PasswordManager {
65
74
var factor = 0
66
75
val length = passwordToTest.length
67
76
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 }
72
81
73
82
if ((passwordToTest.length == 4 ) and (isNumbers(passwordToTest))
74
83
and (! isLetters(passwordToTest))
@@ -85,10 +94,10 @@ class PasswordManager {
85
94
var factor = 0
86
95
val length = passwordToTest.length
87
96
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 }
92
101
93
102
val strong = (factor* length)/ (maxPasswordFactor* max(maxPasswordLength, length.toFloat()))
94
103
@@ -107,18 +116,70 @@ class PasswordManager {
107
116
108
117
109
118
fun isLetters (passwordToTest : String ) : Boolean {
110
- return passwordToTest.matches( Regex (" .*[" + this .letters+ " ].*" ) )
119
+ return passwordToTest.matches(Regex (" .*[" + this .letters + " ].*" ))
111
120
}
112
121
113
122
fun isUpperCase (passwordToTest : String ) : Boolean {
114
- return passwordToTest.matches( Regex (" .*[" + this .uppercaseLetters+ " ].*" ) )
123
+ return passwordToTest.matches(Regex (" .*[" + this .uppercaseLetters + " ].*" ))
115
124
}
116
125
117
126
fun isNumbers (passwordToTest : String ) : Boolean {
118
- return passwordToTest.matches( Regex (" .*[" + this .numbers+ " ].*" ) )
127
+ return passwordToTest.matches(Regex (" .*[" + this .numbers + " ].*" ))
119
128
}
120
129
121
130
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
123
162
}
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
+
124
185
}
0 commit comments