{"record":{"id":"e3c73ab5d43d0132","repo":"beemdevelopment/Aegis","slug":"unexpected-cipher-s","errorCode":null,"errorMessage":"Unexpected cipher: %s","messagePattern":"Unexpected cipher: (.+?)","errorType":"exception","errorClass":"DatabaseImporterException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java","lineNumber":245,"sourceCode":"\n                    VaultEntry vaultEntry = convertEntry(encObj, tokenObj);\n                    result.addEntry(vaultEntry);\n                } catch (DatabaseImporterEntryException e) {\n                    result.addError(e);\n                } catch (JSONException ignored) {\n                }\n            }\n\n            return result;\n        }\n\n        private VaultEntry convertEntry(JSONObject encObj, JSONObject tokenObj)\n                throws DatabaseImporterEntryException {\n            try {\n                JSONObject keyObj = new JSONObject(encObj.getString(\"key\"));\n                String cipherName = keyObj.getString(\"mCipher\");\n                if (!cipherName.equals(\"AES/GCM/NoPadding\")) {\n                    throw new DatabaseImporterException(String.format(\"Unexpected cipher: %s\", cipherName));\n                }\n                byte[] cipherText = toBytes(keyObj.getJSONArray(\"mCipherText\"));\n                byte[] parameters = toBytes(keyObj.getJSONArray(\"mParameters\"));\n                byte[] token = keyObj.getString(\"mToken\").getBytes(StandardCharsets.UTF_8);\n\n                byte[] nonce = parseNonce(parameters);\n                IvParameterSpec spec = new IvParameterSpec(nonce);\n                Cipher cipher = Cipher.getInstance(cipherName);\n                cipher.init(Cipher.DECRYPT_MODE, _masterKey, spec);\n                cipher.updateAAD(token);\n                byte[] secretBytes = cipher.doFinal(cipherText);\n\n                JSONArray secretArray = new JSONArray();\n                for (byte b : secretBytes) {\n                    secretArray.put(b);\n                }\n                tokenObj.put(\"secret\", secretArray);\n","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java#L227-L263","documentation":"Each FreeOTP token entry embeds its own encrypted key JSON with an \"mCipher\" field. The importer only supports AES/GCM/NoPadding for per-entry keys; any other value aborts conversion of that entry with DatabaseImporterException (wrapped into a DatabaseImporterEntryException by convertEntry's caller vaultEntry).","triggerScenarios":"Importing a FreeOTP backup where a token's key object has mCipher different from \"AES/GCM/NoPadding\" — modified FreeOTP build, schema drift, or hand-edited backup JSON.","commonSituations":"FreeOTP fork using CBC or another mode; partial manual edits to a backup; importing backups generated by tooling that reimplemented FreeOTP encryption differently.","solutions":["Update Aegis; if unsupported, re-export from stock FreeOTP","Inspect the entry's key JSON mCipher value to diagnose","Re-save the token in stock FreeOTP so it is encrypted with GCM and re-export","Delete/re-add the affected entry in FreeOTP if only some entries fail"],"exampleFix":"// before\nif (!cipherName.equals(\"AES/GCM/NoPadding\")) {\n    throw new DatabaseImporterException(String.format(\"Unexpected cipher: %s\", cipherName));\n}\n// after\nif (!cipherName.equals(\"AES/GCM/NoPadding\")) {\n    throw new DatabaseImporterException(String.format(\n        \"Unexpected cipher: %s for token key (only AES/GCM/NoPadding supported)\", cipherName));\n}","handlingStrategy":"try-catch","validationCode":"JSONObject keyObj = new JSONObject(encObj.getString(\"key\"));\nif (!keyObj.getString(\"mCipher\").equals(\"AES/GCM/NoPadding\")) {\n    // skip or warn about this entry\n}","typeGuard":null,"tryCatchPattern":"try {\n    entry = importer.convertEntry(encObj, tokenObj);\n} catch (DatabaseImporterEntryException e) {\n    log.warn(\"Entry skipped: \" + e.getMessage());\n}","preventionTips":["Scan all token entries' key JSON for mCipher before bulk import","Re-save failing tokens in stock FreeOTP","Keep backups unedited"],"tags":["import","freeotp","aes-gcm","crypto"],"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"}