{"record":{"id":"cfd5dea5fa887498","repo":"beemdevelopment/Aegis","slug":"unexpected-master-key-kdf-s","errorCode":null,"errorMessage":"Unexpected master key KDF: %s","messagePattern":"Unexpected master key KDF: (.+?)","errorType":"exception","errorClass":"DatabaseImporterException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java","lineNumber":134,"sourceCode":"    public static class EncryptedState extends State {\n        private static final int MASTER_KEY_SIZE = 32 * 8;\n\n        private final String _mkAlgo;\n        private final String _mkCipher;\n        private final byte[] _mkCipherText;\n        private final byte[] _mkParameters;\n        private final byte[] _mkToken;\n        private final byte[] _mkSalt;\n        private final int _mkIterations;\n        private final Map<String, String> _entries;\n\n        private EncryptedState(JSONObject mkObj, Map<String, String> entries)\n                throws DatabaseImporterException, JSONException {\n            super(true);\n\n            _mkAlgo = mkObj.getString(\"mAlgorithm\");\n            if (!_mkAlgo.equals(\"PBKDF2withHmacSHA1\") && !_mkAlgo.equals(\"PBKDF2withHmacSHA512\")) {\n                throw new DatabaseImporterException(String.format(\"Unexpected master key KDF: %s\", _mkAlgo));\n            }\n            JSONObject keyObj = mkObj.getJSONObject(\"mEncryptedKey\");\n            _mkCipher = keyObj.getString(\"mCipher\");\n            if (!_mkCipher.equals(\"AES/GCM/NoPadding\")) {\n                throw new DatabaseImporterException(String.format(\"Unexpected master key cipher: %s\", _mkCipher));\n            }\n            _mkCipherText = toBytes(keyObj.getJSONArray(\"mCipherText\"));\n            _mkParameters = toBytes(keyObj.getJSONArray(\"mParameters\"));\n            _mkToken = keyObj.getString(\"mToken\").getBytes(StandardCharsets.UTF_8);\n            _mkSalt = toBytes(mkObj.getJSONArray(\"mSalt\"));\n            _mkIterations = mkObj.getInt(\"mIterations\");\n            _entries = entries;\n        }\n\n        public State decrypt(char[] password) throws DatabaseImporterException {\n            PBKDFTask.Params params = new PBKDFTask.Params(_mkAlgo, MASTER_KEY_SIZE, password, _mkSalt, _mkIterations);\n            SecretKey passKey = PBKDFTask.deriveKey(params);\n            return decrypt(passKey);","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java#L116-L152","documentation":"The FreeOTP importer reads the master key object's \"mAlgorithm\" field from the FreeOTP backup JSON and only supports PBKDF2withHmacSHA1 and PBKDF2withHmacSHA512. Any other KDF string means Aegis cannot derive the master key, so it throws DatabaseImporterException.","triggerScenarios":"Importing a FreeOTP backup (freeotp-backup.json) whose master key entry uses an unrecognized mAlgorithm value — produced by a different/patched FreeOTP version or a hand-edited file.","commonSituations":"FreeOTP fork or newer release switching KDF; JSON edited by hand; attempting to import a non-FreeOTP JSON that happens to have a master key section.","solutions":["Update Aegis to the latest version for newer FreeOTP KDF support","Check the JSON's mAlgorithm value; re-export from stock FreeOTP if it's nonstandard","If feasible, convert the backup by re-deriving tokens in the original app and re-exporting","Use the FreeOTP app's key migration path (or key exchange feature) instead of direct import"],"exampleFix":"// before\nif (!_mkAlgo.equals(\"PBKDF2withHmacSHA1\") && !_mkAlgo.equals(\"PBKDF2withHmacSHA512\")) {\n    throw new DatabaseImporterException(String.format(\"Unexpected master key KDF: %s\", _mkAlgo));\n}\n// after\nSet<String> SUPPORTED_KDFS = Set.of(\"PBKDF2withHmacSHA1\", \"PBKDF2withHmacSHA512\");\nif (!SUPPORTED_KDFS.contains(_mkAlgo)) {\n    throw new DatabaseImporterException(String.format(\n        \"Unexpected master key KDF: %s (supported: PBKDF2withHmacSHA1, PBKDF2withHmacSHA512)\", _mkAlgo));\n}","handlingStrategy":"validation","validationCode":"JSONObject mk = backupJson.getJSONObject(\"mMasterKey\");\nString algo = mk.getString(\"mAlgorithm\");\nif (!algo.equals(\"PBKDF2withHmacSHA1\") && !algo.equals(\"PBKDF2withHmacSHA512\")) {\n    throw new IllegalArgumentException(\"Unsupported FreeOTP KDF: \" + algo);\n}","typeGuard":null,"tryCatchPattern":"try {\n    importer.read(stream);\n} catch (DatabaseImporterException e) {\n    if (e.getMessage().startsWith(\"Unexpected master key KDF\")) {\n        showUserError(\"FreeOTP backup uses an unsupported KDF — update Aegis or re-export\");\n    }\n}","preventionTips":["Use stock FreeOTP, not forks, for exports","Update Aegis before importing","Don't hand-edit the backup JSON"],"tags":["import","freeotp","pbkdf2","kdf"],"backgroundTag":"unsupported-enum-value","analyzedSha":"d6f4e5925a97e4e91593f1542085eae03432a759","analyzedAt":"2026-09-08T00:46:31.111Z","contentChangedAt":"2026-09-08T00:46:31.111Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}