Working with passwords securely
The PowerAuthPassword
class implements safe storage for users’ passwords. The class is using an underlying native object to store the user’s password securely in memory. The goal is to keep the user’s password in memory for as short a time as possible. To achieve this, the native object implements the following precautions:
- If it’s constructed with the
destroyOnUse
parameter set totrue
, then the native password is automatically destroyed after it’s used for the cryptographic operation.
-
If you leave the instance of the
PowerAuthPassword
class as it is, then the native password is removed from memory after 5 minutes of inactivity. The Flutter object is still functional, so if you use any API function, then the native password is re-initialized, but the previous passphrase is lost. -
If you call any
PowerAuthPassword
method exceptrelease()
, then the auto-cleanup timer is reset, so the native password will live for another 5 minutes.
Be aware that this class is effective only if you’re using a numeric PIN for the passphrase, although its API accepts full Unicode code points at the input. This is because it’s quite simple to re-implement the PIN keyboard with your custom UI components. On opposite to that, for the full alphanumeric input, you need to use the system keyboard, which already leaves traces of the user’s password in memory.
If you’re interested in more details about why the passwords should be protected in memory, then you can follow the Working with passwords securely chapter from the PowerAuth mobile SDK.
Instantiating password
final password = PowerAuthPassword();
Such a password is not bound to any PowerAuth instance, so it will not be destroyed together with the PowerAuth
instance.
Using password
// Creatiing password from already obtained String
// Note that this is not recommended. Do this only when you retrieve the whole string form a text input.
final password = PowerAuthPassword.fromString("1234");
// Change password from "0123" to "3210".
try {
final oldPassword = PowerAuthPassword();
await oldPassword.addCharacter('0');
await oldPassword.addCharacter('1');
await oldPassword.addCharacter('2');
await oldPassword.addCharacter('3');
final newPassword = PowerAuthPassword();
await newPassword.addCharacter(51);
await newPassword.addCharacter(50);
await newPassword.addCharacter(49);
await newPassword.addCharacter(48);
await powerAuth.changePassword(oldPassword, newPassword);
} catch (e) {
print('Change failed: ${e.code}');
}
Adding or removing characters
final password = PowerAuthPassword();
var length = await password.length();
print('length = $length'); // length = 0
length = await password.addCharacter('A');
length = await password.addCharacter('B');
print('length = $length'); // length = 2
length = await password.insertCharacter(48, 2);
length = await password.insertCharacter(49, 2);
print('length = $length'); // length = 4
length = await password.removeLastCharacter();
length = await password.removeCharacterAt(0);
print('length = $length'); // length = 2
await password.clear();
final empty = await password.isEmpty();
print('empty = $empty'); // empty = true
Compare two passwords
final p1 = PowerAuthPassword();
final p2 = PowerAuthPassword();
final p3 = PowerAuthPassword();
await p1.addCharacter('0');
await p1.addCharacter('A');
await p2.addCharacter(48);
await p2.addCharacter(65);
final p1p2equal = await p1.isEqualTo(p2);
final p2p3equal = await p2.isEqualTo(p3);
print('p1 == p2 is $p1p2equal'); // p1 == p2 is true
print('p2 == p3 is $p2p3equal'); // p2 == p3 is false