{"record":{"id":"b068651677f434b5","repo":"grpc/grpc-java","slug":"neither-rsa-nor-ec-worked","errorCode":null,"errorMessage":"Neither RSA nor EC worked","messagePattern":"Neither RSA nor EC worked","errorType":"exception","errorClass":"InvalidKeySpecException","httpStatus":null,"severity":"error","filePath":"util/src/main/java/io/grpc/util/CertificateUtils.java","lineNumber":90,"sourceCode":"        break;\n      }\n    }\n    StringBuilder keyContent = new StringBuilder();\n    while ((line = reader.readLine()) != null) {\n      if (\"-----END PRIVATE KEY-----\".equals(line)) {\n        break;\n      }\n      keyContent.append(line);\n    }\n    byte[] decodedKeyBytes = BaseEncoding.base64().decode(keyContent.toString());\n    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKeyBytes);\n    try {\n      return KeyFactory.getInstance(\"RSA\").generatePrivate(keySpec);\n    } catch (InvalidKeySpecException ignore) {\n      try {\n        return KeyFactory.getInstance(\"EC\").generatePrivate(keySpec);\n      } catch (InvalidKeySpecException e) {\n        throw new InvalidKeySpecException(\"Neither RSA nor EC worked\", e);\n      }\n    }\n  }\n}\n\n","sourceCodeStart":72,"sourceCodeEnd":96,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/util/src/main/java/io/grpc/util/CertificateUtils.java#L72-L96","documentation":"CertificateUtils.getPrivateKey tries to build a PKCS#8 private key first with the RSA KeyFactory and then with the EC KeyFactory. If both generatePrivate calls reject the key spec, it rethrows as an InvalidKeySpecException with this message, chaining the EC failure. It means the encoded key is neither a valid RSA nor EC private key for the loaded providers.","triggerScenarios":"Calling CertificateUtils.getPrivateKey with a byte array/PKCS8EncodedKeySpec that neither the RSA nor the EC KeyFactory can parse — e.g. a DSA/Ed25519 key, a corrupted or truncated DER encoding, a key encoded in a format other than PKCS#8 (PKCS#1 'BEGIN RSA PRIVATE KEY', SEC1 'BEGIN EC PRIVATE KEY', or a raw public key), or a PEM file whose Base64 body was passed raw.","commonSituations":"Loading keys generated with modern algorithms (Ed25519) unsupported by the two hardcoded factories; pasting the inner Base64 of a PKCS#1 header into PKCS8EncodedKeySpec; keys double-Base64-encoded or with headers/whitespace included; converting certificates/keys between formats with tools like OpenSSL incorrectly.","solutions":["Convert the key to PKCS#8: openssl pkcs8 -topk8 -nocrypt -in key.pem -out key_pkcs8.pem and load that","If the key is RSA and in PKCS#1 format, convert first (openssl rsa -traditional vs -pkcs8) before parsing","Check the key algorithm — DSA/Ed25519 keys are not handled by this utility; generate an RSA or EC key or use a different loader","Strip PEM headers and decode the Base64 body exactly once; verify the DER parses (e.g. openssl asn1parse)","Regenerate the key pair if the encoding is corrupted"],"exampleFix":"// before\nbyte[] der = base64Decode(pemBodyOfRsaPkcs1Key); // 'BEGIN RSA PRIVATE KEY'\nPrivateKey key = CertificateUtils.getPrivateKey(der); // InvalidKeySpecException\n// after\n// $ openssl pkcs8 -topk8 -nocrypt -in key.pem -out key_pkcs8.pem\nbyte[] der = base64Decode(pemBodyOf(\"key_pkcs8.pem\"));\nPrivateKey key = CertificateUtils.getPrivateKey(der);","handlingStrategy":"try-catch","validationCode":"static boolean isPkcs8RsaOrEc(byte[] der) {\n  // PKCS#8 PrivateKeyInfo starts with SEQUENCE; quick sanity via ASN.1 parse\n  try {\n    new PKCS8EncodedKeySpec(der);\n    return der.length > 8 && der[0] == 0x30; // SEQUENCE tag\n  } catch (IllegalArgumentException e) {\n    return false;\n  }\n}","typeGuard":"static boolean looksLikePemPkcs8(String pem) {\n  return pem.contains(\"BEGIN PRIVATE KEY\"); // vs 'BEGIN RSA PRIVATE KEY' (PKCS#1) or 'BEGIN EC PRIVATE KEY' (SEC1)\n}","tryCatchPattern":"try {\n  privateKey = CertificateUtils.getPrivateKey(keyBytes);\n} catch (InvalidKeySpecException e) {\n  throw new IllegalArgumentException(\n      \"Key must be PKCS#8-encoded RSA or EC; got neither. Convert with: openssl pkcs8 -topk8 -nocrypt\", e);\n}","preventionTips":["Store keys in PKCS#8 format ('BEGIN PRIVATE KEY' header)","Convert PKCS#1/SEC1 keys with openssl pkcs8 -topk8 -nocrypt before loading","Strip PEM headers and Base64-decode exactly once; verify with openssl asn1parse","Avoid DSA/Ed25519 keys with this utility; use RSA or EC key pairs"],"tags":["security","crypto","key-format","grpc"],"backgroundTag":"invalid-key-spec","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}