{"record":{"id":"ea8de363ee170dab","repo":"kgretzky/evilginx2","slug":"private-key-is-corrupted","errorCode":null,"errorMessage":"private key is corrupted","messagePattern":"private key is corrupted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"core/certdb.go","lineNumber":107,"sourceCode":"\t\t// private key corrupted or not found, recreate and delete all public certificates\n\t\tos.RemoveAll(filepath.Join(o.cache_dir, \"*\"))\n\n\t\tkey, err = rsa.GenerateKey(rand.Reader, 2048)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"private key generation failed\")\n\t\t}\n\t\tpkey = pem.EncodeToMemory(&pem.Block{\n\t\t\tType:  \"RSA PRIVATE KEY\",\n\t\t\tBytes: x509.MarshalPKCS1PrivateKey(key),\n\t\t})\n\t\terr = ioutil.WriteFile(filepath.Join(o.cache_dir, \"ca.key\"), pkey, 0600)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tblock, _ := pem.Decode(pkey)\n\t\tif block == nil {\n\t\t\treturn fmt.Errorf(\"private key is corrupted\")\n\t\t}\n\n\t\tkey, err = x509.ParsePKCS1PrivateKey(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tca_cert, err := ioutil.ReadFile(filepath.Join(o.cache_dir, \"ca.crt\"))\n\tif err != nil {\n\t\tnotBefore := time.Now()\n\t\taYear := time.Duration(10*365*24) * time.Hour\n\t\tnotAfter := notBefore.Add(aYear)\n\t\tserialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)\n\t\tserialNumber, err := rand.Int(rand.Reader, serialNumberLimit)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/kgretzky/evilginx2/blob/4c0988a1d9db4d172a185e979a38bfd0efdb5830/core/certdb.go#L89-L125","documentation":"generateCertificates throws this when the cached PEM file exists but pem.Decode cannot extract a valid 'RSA PRIVATE KEY' block, meaning the stored key file is malformed or not PEM at all. Unlike a parse failure of a valid block (which returns the raw error), this is the case of no PEM data whatsoever.","triggerScenarios":"NewCertDb reads ca.key from cache_dir, the PEM block is nil — e.g. the file is empty, contains base64 without PEM armor, was truncated by an interrupted write, is a different key type (EC PRIVATE KEY), or was overwritten by another process.","commonSituations":"Disk-full or crash during key write; user manually editing/replacing ca.key; cache restored from backup with wrong format; mixing cache dirs between versions of the tool.","solutions":["Delete the corrupt ca.key in cache_dir and restart so the key is regenerated (public certs are also recreated)","Restore a known-good ca.key file from backup","Regenerate the whole cache_dir if site certificates are also suspect","Ensure whatever manages the cache (sync/backup tools) preserves the file verbatim"],"exampleFix":"// before\ncp old-mixed-cache/ca.key ~/.evilginx/cache/  // wrong format file\n// after\nrm ~/.evilginx/cache/ca.key && rm -rf ~/.evilginx/cache/sites/*  // let the tool regenerate","handlingStrategy":"validation","validationCode":"data, err := os.ReadFile(filepath.Join(cacheDir, \"ca.key\"))\nif err != nil || len(bytes.TrimSpace(data)) == 0 {\n    os.Remove(filepath.Join(cacheDir, \"ca.key\")) // let it regenerate\n} else if blk, _ := pem.Decode(data); blk == nil || blk.Type != \"RSA PRIVATE KEY\" {\n    os.Remove(filepath.Join(cacheDir, \"ca.key\"))\n}","typeGuard":"func isPemRSAPrivateKey(data []byte) bool {\n    blk, _ := pem.Decode(data)\n    if blk == nil || blk.Type != \"RSA PRIVATE KEY\" { return false }\n    _, err := x509.ParsePKCS1PrivateKey(blk.Bytes)\n    return err == nil\n}","tryCatchPattern":"db, err := NewCertDb(cacheDir, \"\")\nif err != nil {\n    if err.Error() == \"private key is corrupted\" {\n        os.Remove(filepath.Join(cacheDir, \"ca.key\"))\n        db, err = NewCertDb(cacheDir, \"\") // regenerate\n    }\n    if err != nil { log.Fatal(err) }\n}","preventionTips":["Never hand-edit ca.key; treat the cache as tool-managed","Check disk space before key writes to avoid truncated files","Don't share or migrate cache dirs between different tool versions","Back up the cache before maintenance so a good key can be restored"],"tags":["crypto","tls","certificate","corruption"],"backgroundTag":"private-key-corrupted","analyzedSha":"4c0988a1d9db4d172a185e979a38bfd0efdb5830","analyzedAt":"2026-09-05T19:23:07.238Z","contentChangedAt":"2026-09-05T19:23:07.238Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}