{"record":{"id":"afbdb5f9e692a5b5","repo":"pxb1988/dex2jar","slug":"signatureexception","errorCode":null,"errorMessage":"SignatureException: ","messagePattern":"SignatureException: ","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java","lineNumber":66,"sourceCode":"        private int mCount;\r\n        private Signature mSignature;\r\n\r\n        public SignatureOutputStream(OutputStream out, Signature sig) {\r\n            super(out);\r\n            mSignature = sig;\r\n            mCount = 0;\r\n        }\r\n\r\n        public int size() {\r\n            return mCount;\r\n        }\r\n\r\n        @Override\r\n        public void write(byte[] b) throws IOException {\r\n            try {\r\n                mSignature.update(b, 0, b.length);\r\n            } catch (SignatureException e) {\r\n                throw new IOException(\"SignatureException: \" + e);\r\n            }\r\n            out.write(b);\r\n            mCount += b.length;\r\n        }\r\n\r\n        @Override\r\n        public void write(byte[] b, int off, int len) throws IOException {\r\n            try {\r\n                mSignature.update(b, off, len);\r\n            } catch (SignatureException e) {\r\n                throw new IOException(\"SignatureException: \" + e);\r\n            }\r\n            out.write(b, off, len);\r\n            mCount += len;\r\n        }\r\n\r\n        @Override\r\n        public void write(int b) throws IOException {\r","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/pxb1988/dex2jar/blob/b5bda4fb4935ae8b3869b422454ae3b3896c7bc1/dex-tools/src/main/java/com/googlecode/d2j/signapk/AbstractJarSign.java#L48-L84","documentation":"Thrown by AbstractJarSign's signature-wrapping OutputStream.write(byte[]) when java.security.Signature.update(byte[], int, int) throws SignatureException, rewrapped as an IOException. Signature.update only fails when the signature engine is not in a valid signing state, meaning mSignature was never initialized with initSign or was already finalized.","triggerScenarios":"Writing bytes through the signed output stream while mSignature has not had Signature.initSign(privateKey) called, or continuing to write after sign() was invoked.","commonSituations":"Custom AbstractJarSign subclasses that forget initialization; reusing one Signature across multiple jars; writes flushed after signature generation began; aborted signing runs that keep streaming.","solutions":["Call Signature.initSign(privateKey) (optionally with a SecureRandom) on mSignature before any data is written.","Audit the subclass initialization path; check the cause message ('object not initialized properly').","Create a fresh Signature instance per signing operation instead of reusing across jars.","Abort and restart the signing operation if the failure occurred mid-run; do not keep writing after sign()."],"exampleFix":"// before\nSignature mSignature = Signature.getInstance(\"SHA1withRSA\");\n// missing initSign\noutputStream.write(jarBytes); // throws SignatureException\n// after\nSignature mSignature = Signature.getInstance(\"SHA1withRSA\");\nmSignature.initSign(privateKey, new SecureRandom());\noutputStream.write(jarBytes);","handlingStrategy":"validation","validationCode":"// Ensure the signer is initialized before streaming bytes\nif (!signatureInitialized) {\n    signature.initSign(privateKey, new SecureRandom());\n    signatureInitialized = true;\n}\n","typeGuard":"static boolean readyToSign(java.security.Signature s) {\n    try { s.update(new byte[0]); return true; }\n    catch (java.security.SignatureException e) { return false; }\n}\n","tryCatchPattern":"try {\n    signedOut.write(bytes);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"SignatureException:\")) {\n        throw new IllegalStateException(\"Signature not initialized; call initSign(privateKey) first\", e);\n    }\n    throw e;\n}\n","preventionTips":["Call Signature.initSign(privateKey) immediately after getInstance(), before creating the output stream.","Use a fresh Signature instance per jar; never reuse across signing operations.","Stop writing bytes the moment sign() has been called.","Keep signing single-threaded; java.security.Signature is not thread-safe."],"tags":["signing","jar","security","signature"],"backgroundTag":"invalid-state-transition","analyzedSha":"b5bda4fb4935ae8b3869b422454ae3b3896c7bc1","analyzedAt":"2026-09-08T00:44:01.258Z","contentChangedAt":"2026-09-08T00:44:01.258Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}