Is there a way to use CURL to generate certificate?

First of all, sorry for my awful English, it’s not my native language as you might guess. Also, I’m pretty sure I’m in the wrong category, sorry for that.

Anyway - I’ve understood there is a way to obtain SSL certificate using CURL and “challenges” ( - that’s how they did it, right)? Is there a nice and easy to understand documentation, PayPal style or something?

I hate SDKs. Even when I interact with PayPal/Facebook I use CURL, never SDK.


curl is what you would (or could - it’s not the only HTTP client library out there) use to communicate with Let’s Encrypt’s HTTP API. I’m not aware of a way to generate certificates or CSRs with curl, that’s what you’d use openssl for (or similar software).

1 Like

Thanks pfg. Yes, I will use openssl for the local part. Let’s Encrypt HTTP API is exactly what I was looking for. Is there a documentation for this API?

You can have a look at and the clients that are written in shell:

Handling the API is not particularly friendly to shell, because you need to parse HTTP headers at times and speak JSON. I would choose some higher-level language that has modules for that.

I’m using PHP. I know there are some PHP libraries, but as I said, I love using CURL. I’m looking for a solution that won’t require SHELL access - something that I can do using only PHP (like using CURL…)

Small addition: Let’s Encrypt currently implements the acme-01 draft, which differs quite a bit from the latest draft in that link.

1 Like

There are 6 PHP clients on the link @TCM provided - ACME Client Implementations - Let's Encrypt

Thanks, but as I said, I’m not looking for a ready to use library. I might use JS, it’ll help the server. But it doesn’t matter. Is there a way to do so with CURL + OPENSSL?

yes, you can use curl, openssl and almost whatever language you like ( PHP, JS … )

How? Is there a documentation for the HTTP API?

Yes, ACME is the HTTP protocol used by Let’s Encrypt. Link provided in my previous post.

As long as you can do HTTP requests with proper TLS, handle JSON and do public key crypto and hashing, you can use anything you want. :slight_smile: The documentation is in the spec.

Keep in mind that what you’re asking basically amounts to writing another client. It’s not a simple API.

1 Like

I’m not sure what you are after.

There is full documentation ( provided in the links above)

There is source code to bash, php, JS code (and other languages) which uses openssl and curl ( linked above ) which you can use / modify if you want to. Alternatively you can ignore those and write your own client from scratch.

It’s a lot of text for non-english guy. Is there more simplified explanation? Something like this: :blush:

All I’m looking for is a simple documentation :sob:

I’m not aware of a simplified version, no. Reading source code of existing implementations might help.

1 Like

OK. I’ve managed to register, ask for a certificate and request a challenge, but I can’t understand what’s next. In the existing clients, the filename is the token, and the content is the token, dot, and some user related base64 (the same string for all domains, so it’s something related to the user and not to the challenge itself). In the DNS challenge - the text if base64 of something, not the token. What are those strings? How do I generate them?

After challenge completed, I send a post with the type, token and TLS for the URL given in the challenge, and immediately after - a get with nothing in the body to check the status, if receive 202 that wait Retry-After seconds and retry. No authentication? How lets encrypt will know I’m the one who asks for the status?


This is where it isn't as simple as just using curl :wink:

See draft-ietf-acme-acme-03

A key authorization is a string that expresses a domain holder's authorization for a specified key to satisfy a specified challenge, by concatenating the token for the challenge with a key fingerprint, separated by a "." character:
key-authz = token || '.' || base64url(JWK_Thumbprint(accountKey))

Because it's signed with your private account key.

Oops I was using the wrong documentation. Luckily the other steps are the same. Just to make sure, in the http challenge I need to place the raw key, token.base64(sha256(jwk)), and in the dsn challenge in need to put the key encoded in base64 (base64(token.base64(sha256(jwk))))?

And about the second question, they do not ask for singing or anything else in the get request:

To check on the status of an authorization, the client sends a GET request to the authorization URI

@VladGincher, also be careful that you are using the JWS version of base64, which is different from the most widespread version of base64.