{"record":{"id":"4b02c2e34093c57d","repo":"beemdevelopment/Aegis","slug":"unable-to-find-nonce-in-parameters","errorCode":null,"errorMessage":"Unable to find nonce in parameters","messagePattern":"Unable to find nonce in parameters","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java","lineNumber":346,"sourceCode":"            }\n        }\n    }\n\n    private static byte[] parseNonce(byte[] parameters) throws IOException {\n        ASN1Primitive prim = ASN1Sequence.fromByteArray(parameters);\n        if (prim instanceof ASN1OctetString) {\n            return ((ASN1OctetString) prim).getOctets();\n        }\n\n        if (prim instanceof ASN1Sequence) {\n            for (ASN1Encodable enc : (ASN1Sequence) prim) {\n                if (enc instanceof ASN1OctetString) {\n                    return ((ASN1OctetString) enc).getOctets();\n                }\n            }\n        }\n\n        throw new IOException(\"Unable to find nonce in parameters\");\n    }\n\n    private static byte[] toBytes(JSONArray array) throws JSONException {\n        byte[] bytes = new byte[array.length()];\n        for (int i = 0; i < array.length(); i++) {\n            bytes[i] = (byte)array.getInt(i);\n        }\n        return bytes;\n    }\n    private static class SerializedHashMapParser {\n        private static final int MAGIC = 0xaced;\n        private static final int VERSION = 5;\n        private static final long SERIAL_VERSION_UID = 362498820763181265L;\n\n        private static final byte TC_NULL = 0x70;\n        private static final byte TC_CLASSDESC = 0x72;\n        private static final byte TC_OBJECT = 0x73;\n        private static final byte TC_STRING = 0x74;","sourceCodeStart":328,"sourceCodeEnd":364,"githubUrl":"https://github.com/beemdevelopment/Aegis/blob/d6f4e5925a97e4e91593f1542085eae03432a759/app/src/main/java/com/beemdevelopment/aegis/importers/FreeOtpImporter.java#L328-L364","documentation":"FreeOtpImporter throws this IOException from parseNonce when it walks the ASN.1 AlgorithmParameters of a FreeOTP backup key and cannot locate the initialization-vector/nonce octet string. It means the parameters structure was parsed but no ASN1OctetString (nonce) component was found where the FreeOTP format guarantees one. The key blob is malformed, uses an unsupported parameter layout, or is not the expected AES parameter encoding.","triggerScenarios":"Parsing a FreeOTP exported key whose AlgorithmParameters do not contain an octet-string nonce (e.g. the ASN.1 sequence has different field count/order, or the blob was decoded with the wrong OID so the expected component is an INTEGER or missing entirely).","commonSituations":"Hand-edited or truncated FreeOTP key blobs, tokens generated by a different app than FreeOTP, key material re-encoded by another tool with non-standard GCM/IV parameters, or an outdated FreeOTP format the importer does not recognize.","solutions":["Verify the input file is a genuine, unmodified FreeOTP export (re-export from FreeOTP).","Confirm the key blob is complete — truncated base64/hex will parse but drop the nonce field.","Check the blob uses the AES/GCM AlgorithmParameters layout FreeOTP produces; re-encode if a different cipher parameter structure was used.","Update Aegis, then FreeOTP, to current versions in case the serialization format changed."],"exampleFix":"// before: passing wrong parameter blob\nbyte[] nonce = parseNonce(params);\n// after: validate parameters contain the expected ASN.1 structure first\nif (params == null || !(ASN1Sequence.getInstance(params).toArray()[expectedIdx] instanceof ASN1OctetString)) {\n    throw new IOException(\"Key parameters are not valid FreeOTP AES parameters\");\n}\nbyte[] nonce = parseNonce(params);","handlingStrategy":"try-catch","validationCode":"byte[] params = getAlgorithmParameters(keyBlob);\nboolean hasNonce = false;\ntry {\n    ASN1Sequence seq = ASN1Sequence.getInstance(params);\n    hasNonce = seq.size() > 1 && seq.getObjectAt(1) instanceof ASN1OctetString;\n} catch (Exception ignored) {}\nif (!hasNonce) throw new IllegalArgumentException(\"Key blob has no nonce in parameters\");","typeGuard":"static boolean hasNonce(ASN1Encodable[] seq) {\n    return seq.length > 1 && seq[1] instanceof ASN1OctetString;\n}","tryCatchPattern":"try {\n    byte[] nonce = parseNonce(params);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"Unable to find nonce in parameters\")) {\n        // reject the key blob: wrong or unsupported parameter structure\n        throw new ImportException(\"FreeOTP key parameters missing nonce\", e);\n    }\n    throw e;\n}","preventionTips":["Always round-trip test exported key blobs with the same ASN.1 library before import.","Never hand-edit base64 key material; truncation drops trailing parameter fields.","Pin supported cipher parameter layouts and validate the OID before parsing.","Log the decoded ASN.1 structure on failure to aid diagnosis."],"tags":["java","android","importer","asn1","freeotp"],"backgroundTag":"invalid-argument-format","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"}