Description
A certificate signing request file hides the flag. Treat it as Base64 PEM data and decode the contents to recover the string.
Download the CSR. PEM is just Base64-wrapped DER, so the body decodes back to ASN.1 bytes.
Strip only the PEM tag lines, decode the body, then run the result through strings to ignore length-prefix bytes that surround the flag.
Cross-check with openssl req -text -noout so you know which Subject field hosts the flag.
wget https://artifacts.picoctf.net/c/422/readmycert.csrsudo apt install -y binutilssed -n '/^-----/d;p' readmycert.csr | base64 --decode | stringsopenssl req -text -noout -in readmycert.csrSolution
Want to try it yourself first?
The guided walkthrough reveals hints one step at a time.
Step 1Strip the PEM tags and decode the body
ObservationThe file is a .csr and the description mentions Base64 PEM data. The flag is in the PEM body between the BEGIN and END markers, so strip those lines before decoding.Use sed to drop only the BEGIN/END marker lines, base64-decode the rest, and pipe through strings so the flag survives the binary ASN.1 framing.bashsed -n '/^-----/d;p' readmycert.csr | base64 --decode | strings | grep picoCTFExpected output
picoCTF{read_mycert...b0}What didn't work first
Tried: Decode the entire CSR file including the BEGIN/END marker lines through base64 --decode
The marker lines are not Base64: they carry hyphens and spaces that the alphabet does not contain, so feeding them to a decoder gives an invalid-input error or garbled output. Only the body between the markers is Base64-encoded DER, so strip the markers with sed or grep -v first.
Tried: Pipe the raw base64 --decode output directly to grep picoCTF without going through strings first
In DER the flag bytes sit behind an ASN.1 tag-length header, so the run immediately before the text is not printable. grep may find the match while printing surrounding binary garbage, or miss it entirely when null-byte framing confuses line-based matching. strings isolates the printable run cleanly first.
Learn more
A Certificate Signing Request (CSR) is a structured message sent to a Certificate Authority asking it to issue a TLS certificate. It contains the applicant's public key and identity fields (Common Name, Organization, Country, etc.) encoded in ASN.1 DER, a binary tag-length-value format. The CSR is then wrapped in PEM: Base64-encoded DER between
-----BEGIN CERTIFICATE REQUEST-----and-----END CERTIFICATE REQUEST-----markers.The flag lives in one of the Subject fields (typically Common Name). When the parser stores that string in DER it prefixes the bytes with an ASN.1 tag and length, e.g.
0c 24 picoCTF{...}. Those framing bytes can crowd the flag in raw output, which is whystringsis the right downstream filter: it skips short non-printable runs and surfaces the contiguous flag.Why
sed -n '/^-----/d;p'instead ofgrep -v '-----'? The PEM marker lines start with five dashes at column 0.sed's anchored regex is precise;grep -v '-----'would also drop any data line that happens to contain that substring. PEM bodies almost never do, but the anchored form is the habit worth keeping.Step 2Sanity check with openssl
ObservationPiping through strings pulls out the flag text with no field labels attached. openssl req -text -noout names the Subject field carrying it, and confirms the decode was right.openssl req -text -noout parses the ASN.1 properly and prints each field with its label, so you can confirm which Subject component holds the flag.bashopenssl req -text -noout -in readmycert.csrWhat didn't work first
Tried: Run openssl x509 -text -noout -in readmycert.csr to inspect the file
openssl x509 expects a signed certificate, not a signing request, so pointing it at a CSR gives an unable-to-load error or a parse failure. The subcommand for a CSR is openssl req, which understands the PKCS#10 structure wrapping the Subject and public key.
Tried: Omit the -noout flag and run openssl req -text -in readmycert.csr
Without -noout, openssl prints the PEM block again after the text dump, which is harmless clutter and invites re-decoding it in the belief that it holds something new. It does not; it is the same CSR reprinted. -noout suppresses that trailer and leaves the readable field breakdown.
Learn more
Running the parsed view alongside the raw decode is the workflow worth internalising.
openssl req -text -nooutgives you the structured field names (CN, O, OU, emailAddress) so you know whether the flag was stored in the Common Name, an Organizational Unit, or an extension. That structural knowledge is what generalises to real PKI work, where you might be looking for a Subject Alternative Name in a certificate or a particular OID in a custom extension.Understanding PEM, DER, and ASN.1 pays off well beyond CTFs: TLS, code signing, SSH keys, JWTs, and S/MIME all sit on this stack. The
opensslCLI inspects and converts between every variant.Step 3Alternate path: cfssl or browser export
ObservationSome environments have no openssl installed. cfssl certinfo is a drop-in alternative, parsing the same PKCS#10 structure and emitting the Subject fields as JSON.If openssl is not installed, cfssl certinfo -csr readmycert.csr also dumps the parsed fields. Browsers can export PEM-formatted certificates from any HTTPS site for practice.Learn more
cfssl (CloudFlare's SSL toolkit) ships a
certinfosubcommand that reads CSRs and certificates and emits JSON.cfssl certinfo -csr readmycert.csrgives you the same Subject breakdown openssl shows, in a format easy to grep or pipe intojq. The browser angle: in Firefox or Chrome the certificate viewer (lock icon → details) lets you export the live cert as PEM, then this same workflow inspects it.
Interactive tools
- Base64 & Base32 DecoderDecode Base64 and Base32 strings with auto-detection. Multi-layer mode unwraps nested encodings automatically.
- Recipe ChainStack decoders into a pipeline: Base64, hex, ROT, XOR, Morse, URL, Atbash, Vigenère, and more. Magic mode auto-discovers the chain. Bookmark the URL to save it.
- Number Base ConverterConvert numbers between binary, octal, decimal, and hexadecimal instantly. Enter any value and see all four bases update in real time.
Flag
Reveal flag
picoCTF{read_mycert...b0}
No openssl tooling is required; basic Base64 decoding reveals the answer.