gchq/CyberChef · error · OperationError
Unsupported RSA public key format. Only PKCS#8 is supported.
Error message
Unsupported RSA public key format. Only PKCS#8 is supported.
What it means
PEMToJWK deliberately rejects PKCS#1 RSA public keys. The header string is compared to the literal '-----BEGIN RSA PUBLIC KEY-----' (the PKCS#1 marker); only PKCS#8 SubjectPublicKeyInfo ('-----BEGIN PUBLIC KEY-----') is accepted because jsrsasign's KEYUTIL.getJWKFromKey expects PKCS#8. A PKCS#1 header short-circuits before any parsing.
Source
Thrown at src/core/operations/PEMToJWK.mjs:59
*/
run(input, args) {
let output = "";
let match;
const regex = /-----BEGIN ([A-Z][A-Z ]+[A-Z])-----/g;
while ((match = regex.exec(input)) !== null) {
// find corresponding end tag
const indexBase64 = match.index + match[0].length;
const header = input.substring(match.index, indexBase64);
const footer = `-----END ${match[1]}-----`;
const indexFooter = input.indexOf(footer, indexBase64);
if (indexFooter === -1) {
throw new OperationError(`PEM footer '${footer}' not found`);
}
const pem = input.substring(match.index, indexFooter + footer.length);
if (match[1].indexOf("KEY") !== -1) {
if (header === "-----BEGIN RSA PUBLIC KEY-----") {
throw new OperationError("Unsupported RSA public key format. Only PKCS#8 is supported.");
}
const key = r.KEYUTIL.getKey(pem);
if (key.type === "DSA") {
throw new OperationError("DSA keys are not supported for JWK");
}
const jwk = r.KEYUTIL.getJWKFromKey(key);
if (output.length > 0) {
output += "\n";
}
output += JSON.stringify(jwk);
} else if (match[1] === "CERTIFICATE") {
const cert = new r.X509();
cert.readCertPEM(pem);
const key = cert.getPublicKey();
const jwk = r.KEYUTIL.getJWKFromKey(key);
if (output.length > 0) {
output += "\n";View on GitHub (pinned to 4290ea7539)
Solutions
- Convert the key to PKCS#8: openssl rsa -RSAPublicKey_in -in pub.pem -pubout -out pub_pkcs8.pem (the -pubout default writes PKCS#8 'PUBLIC KEY').
- Re-export the public key from its source as SubjectPublicKeyInfo / PKCS#8.
- Confirm the resulting header reads '-----BEGIN PUBLIC KEY-----' with no 'RSA' prefix.
Example fix
// before (PKCS#1, rejected) -----BEGIN RSA PUBLIC KEY----- ... // after (PKCS#8, accepted) -----BEGIN PUBLIC KEY----- ...
Defensive patterns
Strategy: validation
Validate before calling
function isPkcs8PublicKey(pem) {
return /-----BEGIN PUBLIC KEY-----/.test(pem)
&& !/-----BEGIN RSA PUBLIC KEY-----/.test(pem);
} Type guard
const isPkcs8RsaPublicKey = (pem) =>
typeof pem === 'string' &&
pem.includes('-----BEGIN PUBLIC KEY-----') &&
!pem.includes('-----BEGIN RSA PUBLIC KEY-----'); Prevention
- Export RSA public keys as PKCS#8 (SubjectPublicKeyInfo).
- Check the BEGIN header: 'PUBLIC KEY' = PKCS#8 (ok), 'RSA PUBLIC KEY' = PKCS#1 (rejected).
- Use 'openssl rsa -pubout' (defaults to PKCS#8), not '-RSAPublicKey_out'.
When it happens
Trigger: User feeds a PKCS#1 RSA public key whose header is '-----BEGIN RSA PUBLIC KEY-----'. Common source: OpenSSL legacy 'openssl rsa -RSAPublicKey_out' which emits PKCS#1, or Java RSA exports.
Common situations: Keys exported with older OpenSSL defaults that produce PKCS#1; interop with systems emitting 'RSA PUBLIC KEY'; copy-paste from a tool that wraps RSA public keys in PKCS#1.
Related errors
- PEM footer '${footer}' not found
- DSA keys are not supported for JWK
- Unsupported PEM type '${match[1]}'
- PEM footer '${footer}' not found
- The value of `a` must be coprime to 26.
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/5a58d33d406b8f91.
Report an issue: GitHub.