Merge branch 'feature/EncryptionSettings' into develop #9

This commit is contained in:
J-Jamet
2018-04-05 17:25:07 +02:00
61 changed files with 408 additions and 260 deletions

View File

@@ -1,7 +1,7 @@
KeepassDX (2.5.0.0beta8)
* Hide custom entries protected
* Best management of field references (https://keepass.info/help/base/fieldrefs.html)
* Change default settings
* Change database / default settings
* Add Autofill for search
* Rebuild custom entries
* Refactor old code

View File

@@ -19,17 +19,16 @@
*/
package com.keepassdroid.tests.database;
import java.io.InputStream;
import android.content.Context;
import android.content.res.AssetManager;
import android.test.AndroidTestCase;
import com.keepassdroid.crypto.CipherFactory;
import com.keepassdroid.crypto.engine.AesEngine;
import com.keepassdroid.database.PwDatabaseV4;
import com.keepassdroid.database.load.ImporterV4;
import java.io.InputStream;
public class Kdb4Header extends AndroidTestCase {
public void testReadHeader() throws Exception {
Context ctx = getContext();
@@ -41,7 +40,7 @@ public class Kdb4Header extends AndroidTestCase {
PwDatabaseV4 db = importer.openDatabase(is, "12345", null);
assertEquals(6000, db.getNumKeyEncRounds());
assertEquals(6000, db.getNumberKeyEncryptionRounds());
assertTrue(db.getDataCipher().equals(AesEngine.CIPHER_UUID));

View File

@@ -332,7 +332,8 @@ public abstract class ListNodesActivity extends LockingActivity
PwGroup parent = pwNode.getParent();
Database db = App.getDB();
PwDatabase database = db.getPwDatabase();
if (db.isRecycleBinAvailabledAndEnabled()) {
if (db.isRecycleBinAvailable() &&
db.isRecycleBinEnabled()) {
PwGroup recycleBin = database.getRecycleBin();
// Add trash if it doesn't exists
if (parent.equals(recycleBin)

View File

@@ -24,7 +24,6 @@ import com.keepassdroid.stream.LEDataOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
@@ -33,7 +32,7 @@ public class VariantDictionary {
private static final int VdmCritical = 0xFF00;
private static final int VdmInfo = 0x00FF;
private Map<String, VdType> dict = new HashMap<String, VdType>();
private Map<String, VdType> dict = new HashMap<>();
private class VdType {
public static final byte None = 0x00;

View File

@@ -21,6 +21,7 @@ package com.keepassdroid.crypto.engine;
import com.keepassdroid.crypto.CipherFactory;
import com.keepassdroid.database.PwEncryptionAlgorithm;
import com.keepassdroid.utils.Types;
import java.security.InvalidAlgorithmParameterException;
@@ -34,6 +35,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AesEngine extends CipherEngine {
public static final UUID CIPHER_UUID = Types.bytestoUUID(
new byte[]{(byte) 0x31, (byte) 0xC1, (byte) 0xF2, (byte) 0xE6, (byte) 0xBF, (byte) 0x71, (byte) 0x43, (byte) 0x50,
(byte) 0xBE, (byte) 0x58, (byte) 0x05, (byte) 0x21, (byte) 0x6A, (byte) 0xFC, (byte)0x5A, (byte) 0xFF
@@ -47,4 +49,9 @@ public class AesEngine extends CipherEngine {
return cipher;
}
@Override
public PwEncryptionAlgorithm getPwEncryptionAlgorithm() {
return PwEncryptionAlgorithm.AES_Rijndael;
}
}

View File

@@ -19,6 +19,7 @@
*/
package com.keepassdroid.crypto.engine;
import com.keepassdroid.database.PwEncryptionAlgorithm;
import com.keepassdroid.utils.Types;
import org.spongycastle.jce.provider.BouncyCastleProvider;
@@ -34,6 +35,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class ChaCha20Engine extends CipherEngine {
public static final UUID CIPHER_UUID = Types.bytestoUUID(
new byte[]{(byte)0xD6, (byte)0x03, (byte)0x8A, (byte)0x2B, (byte)0x8B, (byte)0x6F,
(byte)0x4C, (byte)0xB5, (byte)0xA5, (byte)0x24, (byte)0x33, (byte)0x9A, (byte)0x31,
@@ -50,4 +52,9 @@ public class ChaCha20Engine extends CipherEngine {
cipher.init(opmode, new SecretKeySpec(key, "ChaCha7539"), new IvParameterSpec(IV));
return cipher;
}
@Override
public PwEncryptionAlgorithm getPwEncryptionAlgorithm() {
return PwEncryptionAlgorithm.ChaCha20;
}
}

View File

@@ -19,6 +19,8 @@
*/
package com.keepassdroid.crypto.engine;
import com.keepassdroid.database.PwEncryptionAlgorithm;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@@ -41,4 +43,6 @@ public abstract class CipherEngine {
return getCipher(opmode, key, IV, false);
}
public abstract PwEncryptionAlgorithm getPwEncryptionAlgorithm();
}

View File

@@ -20,6 +20,7 @@
package com.keepassdroid.crypto.engine;
import com.keepassdroid.crypto.CipherFactory;
import com.keepassdroid.database.PwEncryptionAlgorithm;
import com.keepassdroid.utils.Types;
import java.security.InvalidAlgorithmParameterException;
@@ -33,6 +34,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class TwofishEngine extends CipherEngine {
public static final UUID CIPHER_UUID = Types.bytestoUUID(
new byte[]{(byte)0xAD, (byte)0x68, (byte)0xF2, (byte)0x9F, (byte)0x57, (byte)0x6F, (byte)0x4B, (byte)0xB9,
(byte)0xA3, (byte)0x6A, (byte)0xD4, (byte)0x7A, (byte)0xF9, (byte)0x65, (byte)0x34, (byte)0x6C
@@ -50,4 +52,9 @@ public class TwofishEngine extends CipherEngine {
return cipher;
}
@Override
public PwEncryptionAlgorithm getPwEncryptionAlgorithm() {
return PwEncryptionAlgorithm.Twofish;
}
}

View File

@@ -22,7 +22,6 @@ package com.keepassdroid.crypto.keyDerivation;
import com.keepassdroid.crypto.CryptoUtil;
import com.keepassdroid.crypto.finalkey.FinalKey;
import com.keepassdroid.crypto.finalkey.FinalKeyFactory;
import com.keepassdroid.database.PwDatabaseV4;
import com.keepassdroid.utils.Types;
import java.io.IOException;
@@ -30,6 +29,10 @@ import java.security.SecureRandom;
import java.util.UUID;
public class AesKdf extends KdfEngine {
public static final int DEFAULT_ROUNDS = 6000;
public static final String DEFAULT_NAME = "AES-KDF";
public static final UUID CIPHER_UUID = Types.bytestoUUID(
new byte[]{(byte) 0xC9, (byte) 0xD9, (byte) 0xF3, (byte) 0x9A, (byte) 0x62, (byte) 0x8A, (byte) 0x44, (byte) 0x60,
(byte) 0xBF, (byte) 0x74, (byte) 0x0D, (byte) 0x08, (byte)0xC1, (byte) 0x8A, (byte) 0x4F, (byte) 0xEA
@@ -42,10 +45,14 @@ public class AesKdf extends KdfEngine {
uuid = CIPHER_UUID;
}
public String getName() {
return DEFAULT_NAME;
}
@Override
public KdfParameters getDefaultParameters() {
KdfParameters p = super.getDefaultParameters();
p.setUInt32(ParamRounds, PwDatabaseV4.DEFAULT_ROUNDS);
p.setUInt32(ParamRounds, DEFAULT_ROUNDS);
return p;
}
@@ -76,4 +83,14 @@ public class AesKdf extends KdfEngine {
p.setByteArray(ParamSeed, seed);
}
@Override
public long getKeyRounds(KdfParameters p) {
return p.getUInt64(ParamRounds);
}
@Override
public void setKeyRounds(KdfParameters p, long keyRounds) {
p.setUInt64(ParamRounds, keyRounds);
}
}

View File

@@ -62,6 +62,11 @@ public class Argon2Kdf extends KdfEngine {
uuid = CIPHER_UUID;
}
@Override
public String getName() {
return "Argon2";
}
@Override
public KdfParameters getDefaultParameters() {
KdfParameters p = super.getDefaultParameters();
@@ -97,4 +102,15 @@ public class Argon2Kdf extends KdfEngine {
p.setByteArray(ParamSalt, salt);
}
@Override
public long getKeyRounds(KdfParameters p) {
return p.getUInt64(ParamIterations);
}
@Override
public void setKeyRounds(KdfParameters p, long keyRounds) {
p.setUInt64(ParamIterations, keyRounds);
}
}

View File

@@ -33,4 +33,10 @@ public abstract class KdfEngine {
public abstract void randomize(KdfParameters p);
public abstract String getName();
public abstract long getKeyRounds(KdfParameters p);
public abstract void setKeyRounds(KdfParameters p, long keyRounds);
}

View File

@@ -25,7 +25,7 @@ import java.util.UUID;
public class KdfFactory {
public static List<KdfEngine> kdfList = new ArrayList<KdfEngine>();
public static List<KdfEngine> kdfList = new ArrayList<>();
static {
kdfList.add(new AesKdf());

View File

@@ -21,6 +21,7 @@ package com.keepassdroid.database;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -272,6 +273,44 @@ public class Database {
passwordEncodingError = false;
}
public String getVersion() {
return getPwDatabase().getVersion().toString();
}
public String getName() {
return getPwDatabase().getName();
}
public boolean containsDescription() {
switch (getPwDatabase().getVersion()) {
default:
return false;
case V4:
return true;
}
}
public String getDescription() {
switch (getPwDatabase().getVersion()) {
default:
return "";
case V4:
return ((PwDatabaseV4) getPwDatabase()).getDescription();
}
}
public String getEncryptionAlgorithmName(Resources resources) {
return getPwDatabase().getEncryptionAlgorithm().getName(resources);
}
public String getKeyDerivationName() {
return getPwDatabase().getKeyDerivationName();
}
public String getNumberKeyEncryptionRounds() {
return Long.toString(getPwDatabase().getNumberKeyEncryptionRounds());
}
public void addEntryTo(PwEntry entry, PwGroup parent) {
try {
switch (getPwDatabase().getVersion()) {
@@ -435,20 +474,12 @@ public class Database {
}
}
public boolean isRecycleBinAvailabledAndEnabled() {
try {
switch (getPwDatabase().getVersion()) {
case V3:
return ((PwDatabaseV3) getPwDatabase()).isRecycleBinAvailable() &&
((PwDatabaseV3) getPwDatabase()).isRecycleBinEnabled();
case V4:
return ((PwDatabaseV4) getPwDatabase()).isRecycleBinAvailable() &&
((PwDatabaseV4) getPwDatabase()).isRecycleBinEnabled();
}
} catch (Exception e) {
Log.e(TAG, "This version of database don't know if the Recyclebin is available", e);
}
return false;
public boolean isRecycleBinAvailable() {
return getPwDatabase().isRecycleBinAvailable();
}
public boolean isRecycleBinEnabled() {
return getPwDatabase().isRecycleBinEnabled();
}
public void undoRecycle(PwEntry entry, PwGroup parent) {

View File

@@ -44,10 +44,14 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
public static final UUID UUID_ZERO = new UUID(0,0);
// Algorithm used to encrypt the database
protected PwEncryptionAlgorithm algorithm;
protected byte masterKey[] = new byte[32];
protected byte[] finalKey;
protected String name = "KeePass database";
protected String name = "KeePass DX database";
protected PwGroupDB rootGroup;
protected PwIconFactory iconFactory = new PwIconFactory();
@@ -106,7 +110,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
return finalKey;
}
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, int numRounds) throws IOException {
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, long numRounds) throws IOException {
// Write checksum Checksum
MessageDigest md;
@@ -129,7 +133,7 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
* Encrypt the master key a few times to make brute-force key-search harder
* @throws IOException
*/
protected static byte[] transformMasterKey( byte[] pKeySeed, byte[] pKey, int rounds ) throws IOException {
protected static byte[] transformMasterKey( byte[] pKeySeed, byte[] pKey, long rounds ) throws IOException {
FinalKey key = FinalKeyFactory.createFinalKey();
return key.transformMasterKey(pKeySeed, pKey, rounds);
@@ -273,13 +277,21 @@ public abstract class PwDatabase<PwGroupDB extends PwGroup<PwGroupDB, PwGroupDB,
return md.digest();
}
public abstract long getNumRounds();
public abstract long getNumberKeyEncryptionRounds();
public abstract void setNumRounds(long rounds) throws NumberFormatException;
public abstract void setNumberKeyEncryptionRounds(long rounds) throws NumberFormatException;
public abstract boolean algorithmSettingsEnabled();
public PwEncryptionAlgorithm getEncryptionAlgorithm() {
if (algorithm != null)
return algorithm;
return PwEncryptionAlgorithm.AES_Rijndael;
}
public abstract PwEncryptionAlgorithm getEncryptionAlgorithm();
public void setEncryptionAlgorithm(PwEncryptionAlgorithm algorithm) {
this.algorithm = algorithm;
}
public abstract String getKeyDerivationName();
public abstract List<PwGroupDB> getGrpRoots();

View File

@@ -46,6 +46,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
package com.keepassdroid.database;
// Java
import com.keepassdroid.crypto.keyDerivation.AesKdf;
import com.keepassdroid.database.exception.InvalidKeyFileException;
import java.io.IOException;
@@ -67,8 +68,7 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
private List<PwEntryV3> entries = new ArrayList<>();
// all groups
private List<PwGroupV3> groups = new ArrayList<>();
// Algorithm used to encrypt the database
private PwEncryptionAlgorithm algorithm;
private int numKeyEncRounds;
private void initAndAddGroup(String name, int iconId, PwGroupV3 parent) {
@@ -80,9 +80,8 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
@Override
public void initNew(String dbPath) {
algorithm = PwEncryptionAlgorithm.Rjindal;
algorithm = PwEncryptionAlgorithm.AES_Rijndael;
numKeyEncRounds = DEFAULT_ENCRYPTION_ROUNDS;
name = "KeePass Password Manager"; // TODO as resource
// Build the root tree
constructTree(null);
@@ -96,21 +95,9 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
return PwVersion.V3;
}
@Override
public PwEncryptionAlgorithm getEncryptionAlgorithm() {
return algorithm;
}
public void setEncryptionAlgorithm(PwEncryptionAlgorithm algorithm) {
this.algorithm = algorithm;
}
public int getNumKeyEncRounds() {
return numKeyEncRounds;
}
public void setNumKeyEncRounds(int numKeyEncRounds) {
this.numKeyEncRounds = numKeyEncRounds;
@Override
public String getKeyDerivationName() {
return AesKdf.DEFAULT_NAME;
}
@Override
@@ -278,23 +265,18 @@ public class PwDatabaseV3 extends PwDatabase<PwGroupV3, PwEntryV3> {
@Override
public long getNumRounds() {
public long getNumberKeyEncryptionRounds() {
return numKeyEncRounds;
}
@Override
public void setNumRounds(long rounds) throws NumberFormatException {
public void setNumberKeyEncryptionRounds(long rounds) throws NumberFormatException {
if (rounds > Integer.MAX_VALUE || rounds < Integer.MIN_VALUE) {
throw new NumberFormatException();
}
numKeyEncRounds = (int) rounds;
}
@Override
public boolean algorithmSettingsEnabled() {
return true;
}
@Override
public void addEntryTo(PwEntryV3 newEntry, PwGroupV3 parent) {
super.addEntryTo(newEntry, parent);

View File

@@ -58,7 +58,6 @@ import biz.source_code.base64Coder.Base64Coder;
public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
public static final int DEFAULT_ROUNDS = 6000;
private static final int DEFAULT_HISTORY_MAX_ITEMS = 10; // -1 unlimited
private static final long DEFAULT_HISTORY_MAX_SIZE = 6 * 1024 * 1024; // -1 unlimited
private static final String RECYCLEBIN_NAME = "RecycleBin";
@@ -67,9 +66,9 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
private UUID dataCipher = AesEngine.CIPHER_UUID;
private CipherEngine dataEngine = new AesEngine();
private PwCompressionAlgorithm compressionAlgorithm = PwCompressionAlgorithm.Gzip;
private KdfEngine kdfEngine;
// TODO: Refactor me away to get directly from kdfParameters
private long numKeyEncRounds = 6000;
private long numKeyEncRounds = AesKdf.DEFAULT_ROUNDS; // By default take the AES rounds
private PwDate nameChanged = new PwDate();
private PwDate settingsChanged = new PwDate();
private String description = "";
@@ -123,6 +122,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
public void setDataEngine(CipherEngine dataEngine) {
this.dataEngine = dataEngine;
this.algorithm = dataEngine.getPwEncryptionAlgorithm();
}
public PwCompressionAlgorithm getCompressionAlgorithm() {
@@ -133,12 +133,18 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
this.compressionAlgorithm = compressionAlgorithm;
}
public long getNumKeyEncRounds() {
@Override
public long getNumberKeyEncryptionRounds() {
if (getKdfEngine() != null && getKdfParameters() != null)
numKeyEncRounds = getKdfEngine().getKeyRounds(getKdfParameters());
return numKeyEncRounds;
}
public void setNumKeyEncRounds(long numKeyEncRounds) {
this.numKeyEncRounds = numKeyEncRounds;
@Override
public void setNumberKeyEncryptionRounds(long rounds) throws NumberFormatException {
if (getKdfEngine() != null && getKdfParameters() != null)
getKdfEngine().setKeyRounds(getKdfParameters(), rounds);
numKeyEncRounds = rounds;
}
public PwDate getNameChanged() {
@@ -146,14 +152,16 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
public void setNameChanged(PwDate nameChanged) {
// TODO change name date
this.nameChanged = nameChanged;
}
public PwDate getSettingsChanged() {
return settingsChanged; // TODO change setting date
return settingsChanged;
}
public void setSettingsChanged(PwDate settingsChanged) {
// TODO change setting date
this.settingsChanged = settingsChanged;
}
@@ -162,6 +170,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
public void setDescription(String description) {
// TODO change description date
this.description = description;
}
@@ -178,6 +187,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
public void setDefaultUserName(String defaultUserName) {
// TODO change default user name date
this.defaultUserName = defaultUserName;
}
@@ -194,6 +204,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
public void setKeyLastChanged(PwDate keyLastChanged) {
// TODO date
this.keyLastChanged = keyLastChanged;
}
@@ -309,6 +320,15 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
this.customData.put(label, value);
}
public KdfEngine getKdfEngine() {
return kdfEngine;
}
@Override
public String getKeyDerivationName() {
return kdfEngine.getName();
}
@Override
public byte[] getMasterKey(String key, InputStream keyInputStream)
throws InvalidKeyFileException, IOException {
@@ -335,7 +355,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
@Override
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, int numRounds) throws IOException {
public void makeFinalKey(byte[] masterSeed, byte[] masterSeed2, long numRounds) throws IOException {
byte[] transformedMasterKey = transformMasterKey(masterSeed2, masterKey, numRounds);
@@ -363,7 +383,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
public void makeFinalKey(byte[] masterSeed, KdfParameters kdfP, long roundsFix)
throws IOException {
KdfEngine kdfEngine = KdfFactory.get(kdfP.kdfUUID);
kdfEngine = KdfFactory.get(kdfP.kdfUUID);
if (kdfEngine == null) {
throw new IOException("Unknown key derivation function");
}
@@ -490,27 +510,6 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
}
@Override
public long getNumRounds() {
return numKeyEncRounds;
}
@Override
public void setNumRounds(long rounds) throws NumberFormatException {
numKeyEncRounds = rounds;
}
@Override
public boolean algorithmSettingsEnabled() {
return false;
}
@Override
public PwEncryptionAlgorithm getEncryptionAlgorithm() {
return PwEncryptionAlgorithm.Rjindal;
}
@Override
public PwGroupIdV4 newGroupId() {
PwGroupIdV4 id;
@@ -590,6 +589,7 @@ public class PwDatabaseV4 extends PwDatabase<PwGroupV4, PwEntryV4> {
}
public void setRecycleBinChanged(Date recycleBinChanged) {
// TODO recyclebin Date
this.recycleBinChanged = recycleBinChanged;
}

View File

@@ -19,26 +19,22 @@
*/
package com.keepassdroid.database;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.DigestInputStream;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import com.keepassdroid.crypto.keyDerivation.AesKdf;
import com.keepassdroid.crypto.keyDerivation.KdfParameters;
import com.keepassdroid.database.exception.InvalidDBVersionException;
import com.keepassdroid.database.security.ProtectedBinary;
import com.keepassdroid.stream.CopyInputStream;
import com.keepassdroid.stream.HmacBlockStream;
import com.keepassdroid.stream.LEDataInputStream;
import com.keepassdroid.utils.Types;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -65,7 +61,6 @@ public class PwDbHeaderV4 extends PwDbHeader {
public static final byte InnerRandomStreamID = 10;
public static final byte KdfParameters = 11;
public static final byte PublicCustomData = 12;
}
public class PwDbInnerHeaderV4Fields {
@@ -178,7 +173,7 @@ public class PwDbHeaderV4 extends PwDbHeader {
break;
case PwDbHeaderV4Fields.TransformSeed:
assert(version < PwDbHeaderV4.FILE_VERSION_32_4);
assert(version < PwDbHeaderV4.FILE_VERSION_32_4); // TODO file > FILEVERSION
AesKdf kdfS = new AesKdf();
if (!db.getKdfParameters().kdfUUID.equals(kdfS.uuid)) {
db.setKdfParameters(kdfS.getDefaultParameters());
@@ -195,7 +190,7 @@ public class PwDbHeaderV4 extends PwDbHeader {
}
long rounds = LEDataInputStream.readLong(fieldData, 0);
db.getKdfParameters().setUInt64(AesKdf.ParamRounds, rounds);
db.setNumKeyEncRounds(rounds);
db.setNumberKeyEncryptionRounds(rounds);
break;
case PwDbHeaderV4Fields.EncryptionIV:
@@ -264,7 +259,7 @@ public class PwDbHeaderV4 extends PwDbHeader {
throw new IOException("Rounds higher than " + Integer.MAX_VALUE + " are not currently supported.");
}
db.setNumKeyEncRounds(rnd);
db.setNumberKeyEncryptionRounds(rnd);
}

View File

@@ -19,8 +19,25 @@
*/
package com.keepassdroid.database;
import android.content.res.Resources;
import com.kunzisoft.keepass.R;
public enum PwEncryptionAlgorithm {
Rjindal,
Twofish;
AES_Rijndael,
Twofish,
ChaCha20;
public String getName(Resources resources) {
switch (this) {
default:
case AES_Rijndael:
return resources.getString(R.string.rijndael);
case Twofish:
return resources.getString(R.string.twofish);
case ChaCha20:
return resources.getString(R.string.chacha20);
}
}
}

View File

@@ -1,5 +1,17 @@
package com.keepassdroid.database;
public enum PwVersion {
V3, V4
V3, V4;
@Override
public String toString() {
switch (this) {
case V3:
return "KeePass 1";
case V4:
return "KeePass 2";
default:
return "unknown";
}
}
}

View File

@@ -160,7 +160,7 @@ public class ImporterV3 extends Importer {
// Select algorithm
if( (hdr.flags & PwDbHeaderV3.FLAG_RIJNDAEL) != 0 ) {
newManager.setEncryptionAlgorithm(PwEncryptionAlgorithm.Rjindal);
newManager.setEncryptionAlgorithm(PwEncryptionAlgorithm.AES_Rijndael);
} else if( (hdr.flags & PwDbHeaderV3.FLAG_TWOFISH) != 0 ) {
newManager.setEncryptionAlgorithm(PwEncryptionAlgorithm.Twofish);
} else {
@@ -170,18 +170,18 @@ public class ImporterV3 extends Importer {
// Copy for testing
newManager.copyHeader(hdr);
newManager.setNumKeyEncRounds(hdr.numKeyEncRounds);
newManager.setNumberKeyEncryptionRounds(hdr.numKeyEncRounds);
newManager.setName("KeePass Password Manager"); // TODO as resource;
// Generate transformedMasterKey from masterKey
newManager.makeFinalKey(hdr.masterSeed, hdr.transformSeed, newManager.getNumKeyEncRounds());
newManager.makeFinalKey(hdr.masterSeed, hdr.transformSeed, newManager.getNumberKeyEncryptionRounds());
status.updateMessage(R.string.decrypting_db);
// Initialize Rijndael algorithm
Cipher cipher;
try {
if ( newManager.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) {
if ( newManager.getEncryptionAlgorithm() == PwEncryptionAlgorithm.AES_Rijndael) {
cipher = CipherFactory.getInstance("AES/CBC/PKCS5Padding");
} else if ( newManager.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Twofish ) {
cipher = CipherFactory.getInstance("Twofish/CBC/PKCS7PADDING");

View File

@@ -98,7 +98,7 @@ public class PwDbHeaderOutputV4 extends PwDbHeaderOutput {
if (header.version < PwDbHeaderV4.FILE_VERSION_32_4) {
writeHeaderField(PwDbHeaderV4Fields.TransformSeed, header.getTransformSeed());
writeHeaderField(PwDbHeaderV4Fields.TransformRounds, LEDataOutputStream.writeLongBuf(db.getNumKeyEncRounds()));
writeHeaderField(PwDbHeaderV4Fields.TransformRounds, LEDataOutputStream.writeLongBuf(db.getNumberKeyEncryptionRounds()));
} else {
writeHeaderField(PwDbHeaderV4Fields.KdfParameters, KdfParameters.serialize(db.getKdfParameters()));
}

View File

@@ -60,7 +60,7 @@ public class PwDbV3Output extends PwDbOutput {
public byte[] getFinalKey(PwDbHeader header) throws PwDbOutputException {
try {
PwDbHeaderV3 h3 = (PwDbHeaderV3) header;
mPM.makeFinalKey(h3.masterSeed, h3.transformSeed, mPM.getNumKeyEncRounds());
mPM.makeFinalKey(h3.masterSeed, h3.transformSeed, mPM.getNumberKeyEncryptionRounds());
return mPM.getFinalKey();
} catch (IOException e) {
throw new PwDbOutputException("Key creation failed: " + e.getMessage());
@@ -77,7 +77,7 @@ public class PwDbV3Output extends PwDbOutput {
Cipher cipher;
try {
if (mPM.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal) {
if (mPM.getEncryptionAlgorithm() == PwEncryptionAlgorithm.AES_Rijndael) {
cipher = CipherFactory.getInstance("AES/CBC/PKCS5Padding");
} else if (mPM.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Twofish){
cipher = CipherFactory.getInstance("Twofish/CBC/PKCS7PADDING");
@@ -127,7 +127,7 @@ public class PwDbV3Output extends PwDbOutput {
header.signature2 = PwDbHeaderV3.DBSIG_2;
header.flags = PwDbHeaderV3.FLAG_SHA2;
if ( mPM.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) {
if ( mPM.getEncryptionAlgorithm() == PwEncryptionAlgorithm.AES_Rijndael) {
header.flags |= PwDbHeaderV3.FLAG_RIJNDAEL;
} else if ( mPM.getEncryptionAlgorithm() == PwEncryptionAlgorithm.Twofish ) {
header.flags |= PwDbHeaderV3.FLAG_TWOFISH;
@@ -138,7 +138,7 @@ public class PwDbV3Output extends PwDbOutput {
header.version = PwDbHeaderV3.DBVER_DW;
header.numGroups = mPM.numberOfGroups();
header.numEntries = mPM.numberOfEntries();
header.numKeyEncRounds = mPM.getNumKeyEncRounds();
header.numKeyEncRounds = (int) mPM.getNumberKeyEncryptionRounds();
setIVs(header);

View File

@@ -210,7 +210,7 @@ public class PwDbV4Output extends PwDbOutput {
}
if (header.version >= PwDbHeaderV4.FILE_VERSION_32_4) {
PwDbInnerHeaderOutputV4 ihOut = new PwDbInnerHeaderOutputV4((PwDatabaseV4)mPM, header, osXml);
PwDbInnerHeaderOutputV4 ihOut = new PwDbInnerHeaderOutputV4(mPM, header, osXml);
ihOut.output();
}
@@ -285,10 +285,10 @@ public class PwDbV4Output extends PwDbOutput {
writeMeta();
PwGroupV4 root = (PwGroupV4) mPM.getRootGroup();
PwGroupV4 root = mPM.getRootGroup();
xml.startTag(null, ElemRoot);
startGroup(root);
Stack<PwGroupV4> groupStack = new Stack<PwGroupV4>();
Stack<PwGroupV4> groupStack = new Stack<>();
groupStack.push(root);
if (!root.preOrderTraverseTree(new GroupWriter(groupStack), new EntryWriter()))

View File

@@ -48,6 +48,7 @@ public class MainPreferenceFragment extends PreferenceFragmentCompat implements
public void onDisplayPreferenceDialog(Preference preference) {
// Try if the preference is one of our custom Preferences
if (preference instanceof RoundsPreference) {
assert getFragmentManager() != null;
DialogFragment dialogFragment = RoundsFixPreferenceDialogFragmentCompat.newInstance(preference.getKey());
dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(getFragmentManager(), null);

View File

@@ -34,6 +34,7 @@ import android.support.v4.app.FragmentManager;
import android.support.v4.hardware.fingerprint.FingerprintManagerCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceCategory;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.util.Log;
import android.view.autofill.AutofillManager;
@@ -41,7 +42,6 @@ import android.widget.Toast;
import com.keepassdroid.app.App;
import com.keepassdroid.database.Database;
import com.keepassdroid.database.PwEncryptionAlgorithm;
import com.keepassdroid.dialogs.StorageAccessFrameworkDialog;
import com.keepassdroid.dialogs.UnavailableFeatureDialogFragment;
import com.keepassdroid.fingerprint.FingerPrintHelper;
@@ -208,6 +208,7 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
SwitchPreference autoFillEnablePreference =
(SwitchPreference) findPreference(getString(R.string.settings_autofill_enable_key));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
assert getActivity() != null;
AutofillManager autofillManager = getActivity().getSystemService(AutofillManager.class);
if (autofillManager != null && autofillManager.hasEnabledAutofillServices())
autoFillEnablePreference.setChecked(autofillManager.hasEnabledAutofillServices());
@@ -252,18 +253,13 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
}
});
} else {
autoFillEnablePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
((SwitchPreference) preference).setChecked(false);
FragmentManager fragmentManager = getFragmentManager();
assert fragmentManager != null;
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.O)
.show(fragmentManager, "unavailableFeatureDialog");
}
return false;
}
autoFillEnablePreference.setOnPreferenceClickListener(preference -> {
((SwitchPreference) preference).setChecked(false);
FragmentManager fragmentManager = getFragmentManager();
assert fragmentManager != null;
UnavailableFeatureDialogFragment.getInstance(Build.VERSION_CODES.O)
.show(fragmentManager, "unavailableFeatureDialog");
return false;
});
}
break;
@@ -273,31 +269,47 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
Database db = App.getDB();
if (db.getLoaded()) {
if (db.getPwDatabase().algorithmSettingsEnabled()) {
Preference roundPref = findPreference(getString(R.string.rounds_key));
roundPref.setEnabled(true);
roundPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
setRounds(App.getDB(), preference);
return true;
}
});
setRounds(db, roundPref);
PreferenceCategory dbGeneralPrefCategory = (PreferenceCategory) findPreference(getString(R.string.database_general_key));
// TODO Algo
Preference algorithmPref = findPreference(getString(R.string.algorithm_key));
// algorithmPref.setEnabled(true);
setAlgorithm(db, algorithmPref);
// Db name
Preference dbNamePref = findPreference(getString(R.string.database_name_key));
dbNamePref.setSummary(db.getName());
// Db description
Preference dbDescriptionPref = findPreference(getString(R.string.database_description_key));
if ( db.containsDescription() ) {
dbDescriptionPref.setSummary(db.getDescription());
} else {
dbGeneralPrefCategory.removePreference(dbDescriptionPref);
}
if (db.isRecycleBinAvailabledAndEnabled()) {
SwitchPreference recycleBinPref = (SwitchPreference) findPreference(getString(R.string.recycle_bin_key));
// Recycle bin
SwitchPreference recycleBinPref = (SwitchPreference) findPreference(getString(R.string.recycle_bin_key));
if (db.isRecycleBinAvailable()) {
// TODO Recycle
//recycleBinPref.setEnabled(true);
recycleBinPref.setChecked(db.isRecycleBinAvailabledAndEnabled());
recycleBinPref.setChecked(db.isRecycleBinEnabled());
recycleBinPref.setEnabled(false);
} else {
dbGeneralPrefCategory.removePreference(recycleBinPref);
}
// Version
Preference dbVersionPref = findPreference(getString(R.string.database_version_key));
dbVersionPref.setSummary(db.getVersion());
// Encryption Algorithm
Preference algorithmPref = findPreference(getString(R.string.encryption_algorithm_key));
algorithmPref.setSummary(db.getEncryptionAlgorithmName(getResources()));
// Key derivation function
Preference kdfPref = findPreference(getString(R.string.key_derivation_function_key));
kdfPref.setSummary(db.getKeyDerivationName());
// Round encryption
Preference roundPref = findPreference(getString(R.string.transform_rounds_key));
roundPref.setSummary(db.getNumberKeyEncryptionRounds());
} else {
Log.e(getClass().getName(), "Database isn't ready");
}
@@ -313,6 +325,7 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
public void onDisplayPreferenceDialog(Preference preference) {
// Try if the preference is one of our custom Preferences
if (preference instanceof RoundsPreference) {
assert getFragmentManager() != null;
DialogFragment dialogFragment = RoundsPreferenceDialogFragmentCompat.newInstance(preference.getKey());
dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(getFragmentManager(), null);
@@ -323,21 +336,6 @@ public class NestedSettingsFragment extends PreferenceFragmentCompat
}
}
private void setRounds(Database db, Preference rounds) {
rounds.setSummary(Long.toString(db.getPwDatabase().getNumRounds()));
}
private void setAlgorithm(Database db, Preference algorithm) {
int resId;
if ( db.getPwDatabase().getEncryptionAlgorithm() == PwEncryptionAlgorithm.Rjindal ) {
resId = R.string.rijndael;
} else {
resId = R.string.twofish;
}
algorithm.setSummary(resId);
}
public static String retrieveTitle(Resources resources, int key) {
switch (key) {
case NESTED_SCREEN_APP_KEY:

View File

@@ -24,6 +24,21 @@ public class RoundsFixPreferenceDialogFragmentCompat extends PreferenceDialogFra
return fragment;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
TextView textDescriptionView = view.findViewById(R.id.rounds_explanation);
mRoundsView = view.findViewById(R.id.rounds);
DialogPreference preference = getPreference();
if (preference instanceof RoundsPreference) {
textDescriptionView.setText(((RoundsPreference) preference).getExplanations());
long numRounds = ((RoundsPreference) preference).getRounds();
mRoundsView.setText(String.valueOf(numRounds));
}
}
@Override
public void onDialogClosed(boolean positiveResult) {
if ( positiveResult ) {
@@ -47,19 +62,4 @@ public class RoundsFixPreferenceDialogFragmentCompat extends PreferenceDialogFra
}
}
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
TextView textDescriptionView = (TextView) view.findViewById(R.id.rounds_explanation);
mRoundsView = (TextView) view.findViewById(R.id.rounds);
DialogPreference preference = getPreference();
if (preference instanceof RoundsPreference) {
textDescriptionView.setText(((RoundsPreference) preference).getExplanations());
long numRounds = ((RoundsPreference) preference).getRounds();
mRoundsView.setText(String.valueOf(numRounds));
}
}
}

View File

@@ -34,12 +34,15 @@ public class RoundsPreference extends DialogPreference {
public RoundsPreference(Context context) {
this(context, null);
}
public RoundsPreference(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.dialogPreferenceStyle);
}
public RoundsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, defStyleAttr);
}
public RoundsPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
TypedArray a = context.getTheme().obtainStyledAttributes(
@@ -47,7 +50,7 @@ public class RoundsPreference extends DialogPreference {
R.styleable.RoundsDialog,
0, 0);
try {
explanations = a.getString(R.styleable.RoundsDialog_description);
setExplanations(a.getString(R.styleable.RoundsDialog_explanations));
} finally {
a.recycle();
}

View File

@@ -3,18 +3,16 @@ package com.keepassdroid.settings;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.preference.DialogPreference;
import android.support.v7.preference.PreferenceDialogFragmentCompat;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.keepassdroid.database.Database;
import com.keepassdroid.tasks.ProgressTask;
import com.keepassdroid.app.App;
import com.keepassdroid.database.PwDatabase;
import com.keepassdroid.database.edit.OnFinish;
import com.keepassdroid.database.edit.SaveDB;
import com.keepassdroid.tasks.ProgressTask;
import com.kunzisoft.keepass.R;
public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat {
@@ -33,9 +31,23 @@ public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragme
return fragment;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mRoundsView = view.findViewById(R.id.rounds);
// Get the number or rounds from the related Preference
mPM = App.getDB().getPwDatabase();
long numRounds = mPM.getNumberKeyEncryptionRounds();
mRoundsView.setText(String.valueOf(numRounds));
}
@Override
public void onDialogClosed(boolean positiveResult) {
if ( positiveResult ) {
assert getContext() != null;
long rounds;
try {
@@ -50,59 +62,46 @@ public class RoundsPreferenceDialogFragmentCompat extends PreferenceDialogFragme
rounds = 1;
}
long oldRounds = mPM.getNumRounds();
long oldRounds = mPM.getNumberKeyEncryptionRounds();
try {
mPM.setNumRounds(rounds);
mPM.setNumberKeyEncryptionRounds(rounds);
} catch (NumberFormatException e) {
Toast.makeText(getContext(), R.string.error_rounds_too_large, Toast.LENGTH_LONG).show();
mPM.setNumRounds(Integer.MAX_VALUE);
mPM.setNumberKeyEncryptionRounds(Integer.MAX_VALUE);
}
Handler handler = new Handler();
SaveDB save = new SaveDB(getContext(), App.getDB(), new AfterSave(getContext(), handler, oldRounds));
SaveDB save = new SaveDB(getContext(), App.getDB(), new AfterSave(getContext(), handler, rounds, oldRounds));
ProgressTask pt = new ProgressTask(getContext(), save, R.string.saving_database);
pt.run();
}
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mRoundsView = view.findViewById(R.id.rounds);
// Get the time from the related Preference
Database db = App.getDB();
mPM = db.getPwDatabase();
long numRounds = mPM.getNumRounds();
DialogPreference preference = getPreference();
if (preference instanceof RoundsPreference) {
numRounds = ((RoundsPreference) preference).getRounds();
}
mRoundsView.setText(String.valueOf(numRounds));
}
private class AfterSave extends OnFinish {
private long mNewRounds;
private long mOldRounds;
private Context mCtx;
public AfterSave(Context ctx, Handler handler, long oldRounds) {
public AfterSave(Context ctx, Handler handler, long newRounds, long oldRounds) {
super(handler);
mCtx = ctx;
mNewRounds = newRounds;
mOldRounds = oldRounds;
}
@Override
public void run() {
long roundsToShow = mNewRounds;
if (!mSuccess) {
displayMessage(mCtx);
mPM.setNumRounds(mOldRounds);
mPM.setNumberKeyEncryptionRounds(mOldRounds);
}
getPreference().setSummary(String.valueOf(roundsToShow));
super.run();
}
}

View File

@@ -27,7 +27,7 @@
<string name="accept">Accepta</string>
<string name="add_entry">Afegeix entrada</string>
<string name="add_group">Afegeix grup</string>
<string name="algorithm">Algoritme</string>
<string name="encryption_algorithm">Algoritme</string>
<string name="app_timeout">Temps d\'espera de l\'aplicació</string>
<string name="app_timeout_summary">Temps abans de bloquejar la base de dades quan l\'applicació està inactiva.</string>
<string name="application">Aplicació</string>

View File

@@ -27,7 +27,7 @@
<string name="accept">Přijat</string>
<string name="add_entry">Přidat záznam</string>
<string name="add_group">Přidat skupinu</string>
<string name="algorithm">Algoritmus</string>
<string name="encryption_algorithm">Algoritmus</string>
<string name="app_timeout">Časový limit aplikace</string>
<string name="app_timeout_summary">Čas před zamknutím databáze, když je aplikace neaktivní.</string>
<string name="application">Aplikace</string>

View File

@@ -26,7 +26,7 @@
<string name="accept">Accepter</string>
<string name="add_entry">Tilføj post</string>
<string name="add_group">Tilføj gruppe</string>
<string name="algorithm">Algoritme</string>
<string name="encryption_algorithm">Algoritme</string>
<string name="app_timeout">Applikations timeout</string>
<string name="app_timeout_summary">Tid før databasen låses, når applikationen er inaktiv.</string>
<string name="application">Applikation</string>

View File

@@ -30,7 +30,7 @@
<string name="add_entry">Eintrag hinzufügen</string>
<string name="add_group">Gruppe hinzufügen</string>
<string name="add_string">Text hinzufügen</string>
<string name="algorithm">Algorithmus</string>
<string name="encryption_algorithm">Algorithmus</string>
<string name="app_timeout">Anwendungssperre</string>
<string name="app_timeout_summary">Bei inaktiver Anwendung wird die Datenbank nach Ablauf der eingestellten Zeit automatisch gesperrt.</string>
<string name="application">Anwendung</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">Αποδοχή</string>
<string name="add_entry">Προσθήκη εγγραφής</string>
<string name="add_group">Προσθήκη ομάδας</string>
<string name="algorithm">Αλγόριθμος</string>
<string name="encryption_algorithm">Αλγόριθμος</string>
<string name="app_timeout">Χρονικό όριο εφαρμογής</string>
<string name="app_timeout_summary">Ο χρόνος προτού κλειδωθεί η βάση δεδομένων όταν η εφαρμογή είναι ανενεργή.</string>
<string name="application">Εφαρμογή</string>

View File

@@ -26,7 +26,7 @@ Spanish translation by José I. Paños. Updated by David García-Abad (23-09-201
<string name="accept">Aceptar</string>
<string name="add_entry">Añadir entrada</string>
<string name="add_group">Añadir grupo</string>
<string name="algorithm">Algoritmo</string>
<string name="encryption_algorithm">Algoritmo</string>
<string name="app_timeout">Tiempo de espera de aplicación</string>
<string name="app_timeout_summary">Tiempo hasta bloquear la base de datos cuando la aplicación está inacttiva.</string>
<string name="application">Aplicación</string>

View File

@@ -26,7 +26,7 @@
<string name="accept">Onartu</string>
<string name="add_entry">Sarrera gehitu</string>
<string name="add_group">Taldea gehitu</string>
<string name="algorithm">Algoritmoa</string>
<string name="encryption_algorithm">Algoritmoa</string>
<string name="app_timeout">Aplikazioa itzaltzeko denbora</string>
<string name="app_timeout_summary">Denbora datubasea blokeatu baino lehenago aplikazioa erabili gabe dagoenean</string>
<string name="application">Aplikazioa</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">Hyväksy</string>
<string name="add_entry">Lisää uusi salasanatietue</string>
<string name="add_group">Lisää ryhmä</string>
<string name="algorithm">Algoritmi</string>
<string name="encryption_algorithm">Algoritmi</string>
<string name="app_timeout">Ohjelman aikakatkaisu</string>
<string name="app_timeout_summary">Aika, jonka jälkeen KeePass lukitaan jos se on ollut toimeton.</string>
<string name="application">Ohjelma</string>

View File

@@ -27,7 +27,7 @@
<string name="add_entry">Ajouter une entrée</string>
<string name="add_group">Ajouter un groupe</string>
<string name="add_string">Ajouter une chaîne</string>
<string name="algorithm">Algorithme</string>
<string name="encryption_algorithm">Algorithme</string>
<string name="app_timeout">Application timeout</string>
<string name="app_timeout_summary">Temps avant le verrouillage de la base de données lorsque l\'application est inactive.</string>
<string name="application">Application</string>
@@ -151,7 +151,7 @@
<string name="remove_from_filelist">Effacer</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">Racine</string>
<string name="rounds">Niveau du chiffrement</string>
<string name="rounds">Tours de transformation</string>
<string name="rounds_explaination">Un niveau de chiffrement supérieur assure une protection supplémentaire contre les attaques de force brute, mais peut considérablement ralentir l\'ouverture et l\'enregistrement.</string>
<string name="rounds_hint">niveaux</string>
<string name="rounds_fix_title">Résolution de la base de données</string>
@@ -248,6 +248,9 @@
<string name="allow_copy_password_summary">Autoriser la copie du mot de passe dans le presse-papiers.</string>
<string name="warning_disabling_storage_access_framework">ATTENTION : désactiver cette fonctionnalité peut engendrer une impossibilité d\'ouvrir ou sauvegarder les bases de données</string>
<string name="open_link_database">Lien du fichier Kdbx à ouvrir</string>
<string name="database_name_title">Nom de la base de données</string>
<string name="database_description_title">Description de la base de données</string>
<string name="database_version_title">Version de la base de données</string>
<string-array name="timeout_options">
<item>5 secondes</item>

View File

@@ -21,7 +21,7 @@
<string name="accept">Elfogadás</string>
<string name="add_entry">Bejegyzés hozzáadása</string>
<string name="add_group">Csoport hozzáadása</string>
<string name="algorithm">Algoritmus</string>
<string name="encryption_algorithm">Algoritmus</string>
<string name="app_timeout">Alkalmazás időkorlátja</string>
<string name="app_timeout_summary">Beállíthatja, mennyi idő után kerüljön lezárásra az adatbázis</string>
<string name="application">Alkalmazás</string>

View File

@@ -27,7 +27,7 @@
<string name="accept">Accetto</string>
<string name="add_entry">Aggiungi voce</string>
<string name="add_group">Aggiungi gruppo</string>
<string name="algorithm">Algoritmo</string>
<string name="encryption_algorithm">Algoritmo</string>
<string name="app_timeout">Scadenza applicazione</string>
<string name="app_timeout_summary">Tempo prima che venga bloccato il database quando l\'applicazione è inattiva.</string>
<string name="application">Applicazione</string>

View File

@@ -25,7 +25,7 @@
<string name="accept">קבל</string>
<string name="add_entry">הוסף ערך</string>
<string name="add_group">הוסף קבוצה</string>
<string name="algorithm">אלגוריתם</string>
<string name="encryption_algorithm">אלגוריתם</string>
<string name="app_timeout">פסק זמן ליישום</string>
<string name="app_timeout_summary">זמן לפני נעילת מסד הנתונים כאשר היישום לא פעיל.</string>
<string name="application">יישום</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">決定</string>
<string name="add_entry">エントリーを追加</string>
<string name="add_group">グループを追加</string>
<string name="algorithm">アルゴリズム</string>
<string name="encryption_algorithm">アルゴリズム</string>
<string name="app_timeout">アプリケーション タイムアウト</string>
<string name="app_timeout_summary">KeePassがこの時間非アクティブだった場合、データベースをロックします。</string>
<string name="application">アプリケーション</string>

View File

@@ -10,7 +10,7 @@
<string name="add_entry">Pridėti įrašą</string>
<string name="add_group">Pridėti grupę</string>
<string name="add_string">Pridėti eilutę</string>
<string name="algorithm">Algortimas</string>
<string name="encryption_algorithm">Algortimas</string>
<string name="app_timeout_summary">Laikas, per kurį yra užrakinama duomenų bazė po neveiklumo programėlėje.</string>
<string name="application">Programėlė</string>
<string name="menu_app_settings">Programėlės nustatymai</string>

View File

@@ -6,7 +6,7 @@
<string name="accept">Pieņemt</string>
<string name="add_entry">Jauns ieraksts</string>
<string name="add_group">Jauna grupa</string>
<string name="algorithm">Algoritms</string>
<string name="encryption_algorithm">Algoritms</string>
<string name="app_timeout">Pielikuma taimauts</string>
<string name="app_timeout_summary">Bloķēšanas taimauts, kad programma nav aktīva.</string>
<string name="application">Programma</string>

View File

@@ -26,7 +26,7 @@
<string name="accept">Aanvaarden</string>
<string name="add_entry">Record toevoegen</string>
<string name="add_group">Groep toevoegen</string>
<string name="algorithm">Algoritme</string>
<string name="encryption_algorithm">Algoritme</string>
<string name="app_timeout">Applicatietimeout</string>
<string name="app_timeout_summary">Tijd tot het vergrendelen van de database bij inactiviteit.</string>
<string name="application">Applicatie</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">Godta</string>
<string name="add_entry">Legg til post</string>
<string name="add_group">Legg til gruppe</string>
<string name="algorithm">Algoritme</string>
<string name="encryption_algorithm">Algoritme</string>
<string name="app_timeout">Programtidsavbrot</string>
<string name="app_timeout_summary">Tid før databasen blir låst når programmet ikkje er i bruk.</string>
<string name="application">Program</string>

View File

@@ -23,7 +23,7 @@ along with KeePass DX. If not, see <http://www.gnu.org/licenses/>.
<string name="accept">Akceptuj</string>
<string name="add_entry">Dodaj wpis</string>
<string name="add_group">Dodaj grupę</string>
<string name="algorithm">Algorytm</string>
<string name="encryption_algorithm">Algorytm</string>
<string name="app_timeout">Czas wygaśnięcia aplikacji</string>
<string name="app_timeout_summary">Czas do zablokowania bazy danych przy bezczynności aplikacji.</string>
<string name="application">Aplikacja</string>

View File

@@ -27,7 +27,7 @@
<string name="accept">Aceitar</string>
<string name="add_entry">Adicionar entrada</string>
<string name="add_group">Adicionar grupo</string>
<string name="algorithm">Algoritmo</string>
<string name="encryption_algorithm">Algoritmo</string>
<string name="app_timeout">Tempo limite para o aplicativo</string>
<string name="app_timeout_summary">Tempo até que o banco de dados seja travado quando o aplicativo estiver inativo.</string>
<string name="application">Aplicação</string>

View File

@@ -27,7 +27,7 @@
<string name="add_entry">Adicionar entrada</string>
<string name="add_group">Adicionar grupo</string>
<string name="add_string">Adicionar linha</string>
<string name="algorithm">Algoritmo</string>
<string name="encryption_algorithm">Algoritmo</string>
<string name="app_timeout">Tempo de espera da aplicação</string>
<string name="app_timeout_summary">Tempo antes do bloqueio da base de dados quando a aplicação está inativa.</string>
<string name="application">Aplicação</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">Принять</string>
<string name="add_entry">Новая запись</string>
<string name="add_group">Новая группа</string>
<string name="algorithm">Алгоритм</string>
<string name="encryption_algorithm">Алгоритм</string>
<string name="app_timeout">Блокировка базы</string>
<string name="app_timeout_summary">Задержка блокировки при бездействии</string>
<string name="application">Программа</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">Prijať</string>
<string name="add_entry">Pridať Záznam</string>
<string name="add_group">Pridať Skupinu</string>
<string name="algorithm">Algoritmus</string>
<string name="encryption_algorithm">Algoritmus</string>
<string name="app_timeout">Časový limit aplikácie.</string>
<string name="app_timeout_summary">Čas pred uzamknutím databázy, ak je aplikácia neaktívna.</string>
<string name="application">Applikácia</string>

View File

@@ -26,7 +26,7 @@
<string name="accept">OK</string>
<string name="add_entry">Ny post</string>
<string name="add_group">Ny grupp</string>
<string name="algorithm">Algoritm</string>
<string name="encryption_algorithm">Algoritm</string>
<string name="app_timeout">Tidsgräns för applikation</string>
<string name="app_timeout_summary">Tid innan låsning när applikationen är inaktiv.</string>
<string name="application">Applikation</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">Прийняти</string>
<string name="add_entry">Додати запис</string>
<string name="add_group">Додати групу</string>
<string name="algorithm">Алгоритм</string>
<string name="encryption_algorithm">Алгоритм</string>
<string name="app_timeout">Тайм-аут програми</string>
<string name="app_timeout_summary">Час перед закриттям бази даних, коли програма є неактивною.</string>
<string name="application">Програма</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">接受</string>
<string name="add_entry">添加条目</string>
<string name="add_group">添加群组</string>
<string name="algorithm">算法</string>
<string name="encryption_algorithm">算法</string>
<string name="app_timeout">应用程序超时</string>
<string name="app_timeout_summary">应用程序处于非活动时锁定数据库。</string>
<string name="application">应用程序</string>

View File

@@ -24,7 +24,7 @@
<string name="accept">接受</string>
<string name="add_entry">添加條目</string>
<string name="add_group">添加群組</string>
<string name="algorithm">演算法</string>
<string name="encryption_algorithm">演算法</string>
<string name="app_timeout">應用程式超時</string>
<string name="app_timeout_summary">應用程式處於非活動時鎖定資料庫。</string>
<string name="application">應用程式</string>

View File

@@ -30,6 +30,6 @@
<attr name="whiteFab" format="reference" />
<declare-styleable name="RoundsDialog">
<attr name="description" format="string" />
<attr name="explanations" format="string" />
</declare-styleable>
</resources>

View File

@@ -34,13 +34,15 @@
<string name="max_password_length" translatable="false">64</string>
<!-- Preference settings -->
<string name="algorithm_key" translatable="false">algorithm</string>
<string name="encryption_algorithm_key" translatable="false">algorithm</string>
<string name="key_derivation_function_key" translatable="false">key_derivation_function_key</string>
<string name="app_key" translatable="false">app</string>
<string name="app_timeout_key" translatable="false">app_timeout_key</string>
<string name="clipboard_timeout_key" translatable="false">clip_timeout_key</string>
<string name="db_key" translatable="false">db</string>
<string name="rounds_key" translatable="false">rounds</string>
<string name="transform_rounds_key" translatable="false">transform_rounds_key</string>
<string name="roundsFix_key" translatable="false">roundsFix</string>
<integer name="roundsFix_default" translatable="false">100000</integer>
<string name="keyfile_key" translatable="false">keyfile</string>
<string name="maskpass_key" translatable="false">maskpass</string>
<string name="omitbackup_key" translatable="false">omitbackup</string>
@@ -54,7 +56,6 @@
<string name="sort_recycle_bin_bottom_key" translatable="false">sort_recycle_bin_bottom_key</string>
<string name="timeout_key" translatable="false">timeout_key</string>
<string name="saf_key" translatable="false">storage_access_framework_key</string>
<integer name="roundsFix_default" translatable="false">100000</integer>
<string name="setting_style_key" translatable="false">setting_style_key</string>
<string name="clipboard_notifications_key" translatable="false">clipboard_notifications_key</string>
<string name="lock_database_screen_off_key" translatable="false">lock_database_screen_off_key</string>
@@ -67,6 +68,10 @@
<string name="monospace_font_fields_enable_key" translatable="false">monospace_font_extra_fields_enable_key</string>
<string name="auto_open_file_uri_key" translatable="false">auto_open_file_uri_key</string>
<string name="allow_copy_password_key" translatable="false">allow_copy_password_key</string>
<string name="database_general_key" translatable="false">database_general_key</string>
<string name="database_name_key" translatable="false">database_name_key</string>
<string name="database_description_key" translatable="false">database_description_key</string>
<string name="database_version_key" translatable="false">database_version_key</string>
<bool name="maskpass_default" translatable="false">true</bool>
<bool name="keyfile_default" translatable="false">true</bool>

View File

@@ -27,7 +27,9 @@
<string name="add_entry">Add entry</string>
<string name="add_group">Add group</string>
<string name="add_string">Add string</string>
<string name="algorithm">Algorithm</string>
<string name="encryption">Encryption</string>
<string name="encryption_algorithm">Encryption Algorithm</string>
<string name="key_derivation_function">Key Derivation Function</string>
<string name="app_timeout">Application timeout</string>
<string name="app_timeout_summary">Time before locking database when the application is inactive.</string>
<string name="application">Application</string>
@@ -151,7 +153,7 @@
<string name="remove_from_filelist">Remove</string>
<string name="rijndael">Rijndael (AES)</string>
<string name="root">Root</string>
<string name="rounds">Encryption Rounds</string>
<string name="rounds">Transform Rounds</string>
<string name="rounds_explaination">Higher encryption rounds provide additional protection against brute force attacks, but can really slow down loading and saving.</string>
<string name="rounds_fix_title">Fix of database</string>
<string name="rounds_fix">Key encryption rounds before corruption</string>
@@ -174,6 +176,7 @@
<string name="search">Search</string>
<string name="search_results">Search results</string>
<string name="twofish">Twofish</string>
<string name="chacha20">ChaCha20</string>
<string name="underline">Underline</string>
<string name="unsupported_db_version">Unsupported database version.</string>
<string name="uppercase">Upper-case</string>
@@ -249,6 +252,9 @@
<string name="allow_copy_password_summary">Allow the copy of the password to the clipboard.</string>
<string name="warning_disabling_storage_access_framework">WARNING : disabling this feature may result in an inability to open or save the databases</string>
<string name="open_link_database">Link of the Kdbx file to open</string>
<string name="database_name_title">Database name</string>
<string name="database_description_title">Database description</string>
<string name="database_version_title">Database version</string>
<string-array name="timeout_options">
<item>5 seconds</item>

View File

@@ -20,28 +20,49 @@
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/general">
<PreferenceCategory
android:key="@string/database_general_key"
android:title="@string/general">
<Preference
android:key="@string/algorithm_key"
android:persistent="false"
android:title="@string/algorithm"
android:enabled="false"/>
<com.keepassdroid.settings.RoundsPreference
android:key="@string/rounds_key"
android:key="@string/database_name_key"
android:persistent="false"
android:title="@string/rounds"
android:positiveButtonText="@string/entry_save"
android:negativeButtonText="@string/entry_cancel"
android:enabled="false"/>
android:title="@string/database_name_title"/>
<Preference
android:key="@string/database_description_key"
android:persistent="false"
android:title="@string/database_description_title"/>
<Preference
android:key="@string/database_version_key"
android:persistent="false"
android:title="@string/database_version_title"/>
<SwitchPreference
android:key="@string/recycle_bin_key"
android:persistent="false"
android:title="@string/recycle_bin_title"
android:summary="@string/recycle_bin_summary"
android:enabled="false"
android:checked="false"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/encryption">
<Preference
android:key="@string/encryption_algorithm_key"
android:persistent="false"
android:title="@string/encryption_algorithm"/>
<Preference
android:key="@string/key_derivation_function_key"
android:persistent="false"
android:title="@string/key_derivation_function"/>
<com.keepassdroid.settings.RoundsPreference
android:key="@string/transform_rounds_key"
android:persistent="false"
android:title="@string/rounds"
android:positiveButtonText="@string/entry_save"
android:negativeButtonText="@string/entry_cancel"/>
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -45,7 +45,7 @@
android:key="@string/roundsFix_key"
android:title="@string/rounds_fix_title"
android:summary="@string/rounds_fix"
custom:description="@string/rounds_fix_explanation"
custom:explanations="@string/rounds_fix_explanation"
android:defaultValue="@integer/roundsFix_default"
android:icon="@drawable/ic_filter_tilt_shift_pref_24dp" />
</PreferenceCategory>

View File

@@ -1,6 +1,6 @@
* Hide custom entries protected
* Best management of field references (https://keepass.info/help/base/fieldrefs.html)
* Change default settings
* Change database / default settings
* Add Autofill for search
* Rebuild custom entries
* Refactor old code

View File

@@ -1,6 +1,6 @@
* Cache pour les entrées protégées customisées
* Meilleure gestion des références de champs (https://keepass.info/help/base/fieldrefs.html)
* Changement des paramètres par defaut
* Changement des paramètres de base de données / par defaut
* Ajout du remplissage automatique pour la recherche
* Reconstruction des entrées customisées
* Refactorisation du vieux code