{"record":{"id":"b09489ec7842e025","repo":"beemdevelopment/Aegis","slug":"unsupported-algorithm-s-b09489","errorCode":null,"errorMessage":"unsupported algorithm: %s","messagePattern":"unsupported algorithm: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java","lineNumber":90,"sourceCode":"    }\n\n    public void setSecret(byte[] secret) {\n        _secret = secret;\n    }\n\n    public static boolean isAlgorithmValid(String algorithm) {\n        return algorithm.equals(\"SHA1\") || algorithm.equals(\"SHA256\") ||\n                algorithm.equals(\"SHA512\") || algorithm.equals(\"MD5\");\n    }\n\n    public void setAlgorithm(String algorithm) throws OtpInfoException {\n        if (algorithm.startsWith(\"Hmac\")) {\n            algorithm = algorithm.substring(4);\n        }\n        algorithm = algorithm.toUpperCase(Locale.ROOT);\n\n        if (!isAlgorithmValid(algorithm)) {\n            throw new OtpInfoException(String.format(\"unsupported algorithm: %s\", algorithm));\n        }\n        _algorithm = algorithm;\n    }\n\n    public static boolean isDigitsValid(int digits) {\n        // allow a max of 10 digits, as truncation will only extract 31 bits\n        return digits > 0 && digits <= 10;\n    }\n\n    public void setDigits(int digits) throws OtpInfoException {\n        if (!isDigitsValid(digits)) {\n            throw new OtpInfoException(String.format(\"unsupported amount of digits: %d\", digits));\n        }\n        _digits = digits;\n    }\n\n    public static OtpInfo fromJson(String type, JSONObject obj) throws OtpInfoException {\n        OtpInfo info;","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/otp/OtpInfo.java#L72-L108","documentation":"OtpInfo.setAlgorithm normalizes the algorithm name (strips an optional 'Hmac' prefix, uppercases) and validates it against the supported set (SHA1/SHA256/SHA512) via isAlgorithmValid. If the value is not supported it throws OtpInfoException('unsupported algorithm: %s').","triggerScenarios":"parseUri on an otpauth:// URI whose algorithm parameter is not SHA1/SHA256/SHA512 (after normalization); parseEntry importing a vault entry with an unknown algorithm string; calling the OtpInfo constructor or setAlgorithm directly with e.g. 'MD5', 'SHA224', or a misspelled name.","commonSituations":"Importing credentials generated by other apps that emit algorithms Aegis doesn't support (MD5, SHA3) — e.g. some FreeOTP/andOTP exports; typos in hand-written otpauth URIs; case differences are tolerated but unsupported families are not.","solutions":["Use a supported algorithm in the URI/entry: SHA1, SHA256, or SHA512 (the 'Hmac' prefix and any casing are normalized automatically).","Before calling setAlgorithm, validate with OtpInfo.isAlgorithmValid(normalizedName) and handle unsupported values at import time.","If the source credential genuinely requires an unsupported algorithm, re-issue it with SHA1/SHA256/SHA512."],"exampleFix":"// before\nString algo = uri.getQueryParameter(\"algorithm\"); // \"MD5\"\ninfo.setAlgorithm(algo); // throws\n\n// after\nString algo = uri.getQueryParameter(\"algorithm\");\nif (algo != null && algo.startsWith(\"Hmac\")) algo = algo.substring(4);\nalgo = algo == null ? null : algo.toUpperCase(Locale.ROOT);\nif (algo != null && !OtpInfo.isAlgorithmValid(algo)) {\n    algo = null; // fall back to default SHA1 or reject entry\n}\nif (algo != null) info.setAlgorithm(algo);","handlingStrategy":"validation","validationCode":"String norm = algorithm == null ? null\n    : (algorithm.startsWith(\"Hmac\") ? algorithm.substring(4) : algorithm).toUpperCase(Locale.ROOT);\nif (norm != null && !OtpInfo.isAlgorithmValid(norm)) {\n    throw new IllegalArgumentException(\"unsupported algorithm: \" + norm);\n}","typeGuard":"boolean isSupportedAlgorithm(String algo) {\n    if (algo == null) return false;\n    String n = algo.startsWith(\"Hmac\") ? algo.substring(4) : algo;\n    return OtpInfo.isAlgorithmValid(n.toUpperCase(Locale.ROOT));\n}","tryCatchPattern":"try {\n    otpInfo.setAlgorithm(algorithmParam);\n} catch (OtpInfoException e) {\n    // unsupported algorithm from imported URI/entry; fall back to SHA1 or reject entry\n    otpInfo.setAlgorithm(\"SHA1\");\n}","preventionTips":["Only emit SHA1/SHA256/SHA512 in generated otpauth:// URIs.","Sanitize the algorithm query parameter (strip 'Hmac', uppercase) before validation at import time.","Maintain a whitelist check at the UI/import layer so unsupported algorithms are rejected with a clear message."],"tags":["otp","algorithm","validation","unsupported-value"],"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"}