{"record":{"id":"293f96caad189b51","repo":"beemdevelopment/Aegis","slug":"unexpectedly-high-number-of-iterations-d","errorCode":null,"errorMessage":"Unexpectedly high number of iterations: %d","messagePattern":"Unexpectedly high number of iterations: (.+?)","errorType":"exception","errorClass":"DatabaseImporterException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java","lineNumber":127,"sourceCode":"                    | InvalidAlgorithmParameterException\n                    | InvalidKeyException\n                    | NoSuchPaddingException\n                    | IllegalBlockSizeException e) {\n                throw new RuntimeException(e);\n            }\n        }\n\n        private PBKDFTask.Params getKeyDerivationParams(char[] password) throws DatabaseImporterException {\n            byte[] iterBytes = Arrays.copyOfRange(_data, 0, INT_SIZE);\n            int iterations = ByteBuffer.wrap(iterBytes).getInt();\n            if (iterations < 1) {\n                throw new DatabaseImporterException(String.format(\"Invalid number of iterations for PBKDF: %d\", iterations));\n            }\n            // If number of iterations is this high, it's probably not an andOTP file, so\n            // abort early in order to prevent having to wait for an extremely long key derivation\n            // process, only to find out that the user picked the wrong file\n            if (iterations > 10_000_000L) {\n                throw new DatabaseImporterException(String.format(\"Unexpectedly high number of iterations: %d\", iterations));\n            }\n\n            byte[] salt = Arrays.copyOfRange(_data, INT_SIZE, INT_SIZE + SALT_SIZE);\n            return new PBKDFTask.Params(\"PBKDF2WithHmacSHA1\", KEY_SIZE, password, salt, iterations);\n        }\n\n        protected DecryptedState decryptOldFormat(char[] password) throws DatabaseImporterException {\n            // WARNING: DON'T DO THIS IN YOUR OWN CODE\n            // this exists solely to support the old andOTP backup format\n            // it is not a secure way to derive a key from a password\n            MessageDigest hash;\n            try {\n                hash = MessageDigest.getInstance(\"SHA-256\");\n            } catch (NoSuchAlgorithmException e) {\n                throw new RuntimeException(e);\n            }\n            byte[] keyBytes = hash.digest(CryptoUtils.toBytes(password));\n            SecretKey key = new SecretKeySpec(keyBytes, \"AES\");","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/importers/AndOtpImporter.java#L109-L145","documentation":"The andOTP importer caps the PBKDF2 iteration count at 10,000,000. A larger value almost certainly means the file is not an andOTP backup, so the importer aborts early to avoid a multi-minute key derivation that would only fail at decryption time.","triggerScenarios":"Importing a file whose first 4 bytes parse to an iteration count above 10,000,000 — typically a non-andOTP file or one from a different app whose header places other data where andOTP stores iterations.","commonSituations":"Wrong file selected during import; andOTP backup created with an absurd iteration count via manual config edit; corrupted/truncated file where high-order bytes shift the value.","solutions":["Confirm the file is an andOTP encrypted export and re-select it","Re-export the backup from andOTP","Check the first 4 bytes in a hex editor for a realistic iteration count (typically 10,000–1,000,000)","Import via the correct importer for the file's actual source app"],"exampleFix":"// before\nif (iterations > 10_000_000L) {\n    throw new DatabaseImporterException(String.format(\"Unexpectedly high number of iterations: %d\", iterations));\n}\n// after\nlong MAX_ITERATIONS = 10_000_000L;\nif (iterations > MAX_ITERATIONS) {\n    throw new DatabaseImporterException(String.format(\n        \"Not an andOTP backup (iterations=%d > %d); pick the correct file/app\",\n        iterations, MAX_ITERATIONS));\n}","handlingStrategy":"validation","validationCode":"int iterations = ByteBuffer.wrap(Arrays.copyOfRange(fileBytes, 0, 4)).getInt();\nif (iterations <= 0 || iterations > 10_000_000) {\n    throw new IllegalArgumentException(\"Un plausible andOTP iteration count: \" + iterations);\n}","typeGuard":null,"tryCatchPattern":"try {\n    importer.read(stream, password);\n} catch (DatabaseImporterException e) {\n    if (e.getMessage().startsWith(\"Unexpectedly high\")) {\n        promptUserToPickCorrectFile();\n    }\n}","preventionTips":["Verify file provenance — andOTP backups only","Hex-inspect the leading int32 for a realistic iteration value before importing","Use the correct importer per source app"],"tags":["import","pbkdf2","validation","android"],"backgroundTag":"value-out-of-range","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"}