# How to get openssl rsa private key out of private\_key.json

**URL:** <https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658>\
**Category:** Issuance Tech\
**Created:** [November 30, 2015, 7:23pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658 "2015-11-30T19:23:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrtux](https://avatars.discourse-cdn.com/v4/letter/m/9de0a6/32.png) [@mrtux](https://community.letsencrypt.org/u/mrtux)\
**Post date:** [November 30, 2015, 7:23pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/1 "2015-11-30T19:23:19Z")

</div>

How to get a `openssl genrsa` compatible key out of the `private_key.json` which the official letsencrypt client creates (i.e., for using in e.g. [https://github.com/diafygi/acme-tiny/](https://github.com/diafygi/acme-tiny/))?

---

<div class="post-metadata">

**Author:** ![tlussnig](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/tlussnig/32/2053_2.png) [@tlussnig](https://community.letsencrypt.org/u/tlussnig)\
**Post date:** [November 30, 2015, 9:12pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/2 "2015-11-30T21:12:15Z")

</div>

For Example with Java:  
`final Decoder dec = java.util.Base64.getUrlDecoder(); final Pattern pattern = Pattern.compile("\\{\"e\": \"(.*)\", \"d\": \"(.*)\", \"n\": \"(.*)\", \"q\": \"(.*)\", \"p\": \"(.*)\", \"kty\": \"(.*)\", \"qi\": \"(.*)\", \"dp\": \"(.*)\", \"dq\": \"(.*)\"}"); final String alias = "letsencryptUserAlias"; final String keyFile = argc[0]; final String storeFile = argc[1]; final File f = new File(keyFile); final byte[] b = new byte[(int)f.length()]; try(InputStream s = new FileInputStream(f)) { s.read(b, 0, b.length); } final String json = new String(b); final Matcher m6 = pattern.matcher(json); if(!m6.matches()) throw new IllegalArgumentException(); final BigInteger e = new BigInteger(1, dec.decode(m6.group(1))); final BigInteger d = new BigInteger(1, dec.decode(m6.group(2))); final BigInteger n = new BigInteger(1, dec.decode(m6.group(3))); final BigInteger q = new BigInteger(1, dec.decode(m6.group(4))); final BigInteger p = new BigInteger(1, dec.decode(m6.group(5))); final BigInteger qi = new BigInteger(1, dec.decode(m6.group(7))); final BigInteger dp = new BigInteger(1, dec.decode(m6.group(8))); final BigInteger dq = new BigInteger(1, dec.decode(m6.group(9))); final KeyFactory kf = KeyFactory.getInstance("RSA"); final RSAPrivateCrtKey s_key = (RSAPrivateCrtKey)kf.generatePrivate(new RSAPrivateCrtKeySpec(n, e, d, p, q, dp, dq, qi));`

---

<div class="post-metadata">

**Author:** ![mrtux](https://avatars.discourse-cdn.com/v4/letter/m/9de0a6/32.png) [@mrtux](https://community.letsencrypt.org/u/mrtux)\
**Post date:** [December 1, 2015, 9:29pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/3 "2015-12-01T21:29:40Z")

</div>

@tlussnig Thanks!

Here my full adapted source:

```
public static void main(String[] args) throws FileNotFoundException, IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException {
    final Decoder dec = java.util.Base64.getUrlDecoder();
    final Pattern pattern = Pattern.compile("\\{\"e\": \"(.*)\", \"d\": \"(.*)\", \"n\": \"(.*)\", \"q\": \"(.*)\", \"p\": \"(.*)\", \"kty\": \"(.*)\", \"qi\": \"(.*)\", \"dp\": \"(.*)\", \"dq\": \"(.*)\"}");
    final String keyFile = args[0];
    final File f = new File(keyFile);
    final byte[] b = new byte[(int)f.length()];
    try(InputStream s = new FileInputStream(f)) { s.read(b, 0, b.length); }
    final String json = new String(b);
    final Matcher m6 = pattern.matcher(json);
    if(!m6.matches()) throw new IllegalArgumentException();
    final BigInteger e = new BigInteger(1, dec.decode(m6.group(1)));
    final BigInteger d = new BigInteger(1, dec.decode(m6.group(2)));
    final BigInteger n = new BigInteger(1, dec.decode(m6.group(3)));
    final BigInteger q = new BigInteger(1, dec.decode(m6.group(4)));
    final BigInteger p = new BigInteger(1, dec.decode(m6.group(5)));
    final BigInteger qi = new BigInteger(1, dec.decode(m6.group(7)));
    final BigInteger dp = new BigInteger(1, dec.decode(m6.group(8)));
    final BigInteger dq = new BigInteger(1, dec.decode(m6.group(9)));
    final KeyFactory kf = KeyFactory.getInstance("RSA");
    final RSAPrivateCrtKey s_key = (RSAPrivateCrtKey)kf.generatePrivate(new RSAPrivateCrtKeySpec(n, e, d, p, q, dp, dq, qi));

    FileWriter o = new FileWriter(new File(args[1]));
    final String encoded = Base64.getEncoder().encodeToString(s_key.getEncoded());
    o.write(encoded);
    o.close();
}
```

---

<div class="post-metadata">

**Author:** ![chris5](https://avatars.discourse-cdn.com/v4/letter/c/f19dbf/32.png) [@chris5](https://community.letsencrypt.org/u/chris5)\
**Post date:** [January 23, 2018, 3:52am UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/4 "2018-01-23T03:52:28Z")

</div>

Hate to completely out myself as a java noob, but how on earth does one actually use this code? javac won’t compile it. It doesn’t run directly via the ‘java’ command (saved in a file and passed as an argument). Can those of us that aren’t java devs please get some hints?

Clues are much appreciated.

Thanks,  
-C

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [January 23, 2018, 4:17am UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/5 "2018-01-23T04:17:52Z")

</div>

I’m not sure about the Java code, but if you have Go installed, you can try this program to do a similar thing.

```auto
$ go get -u gopkg.in/square/go-jose.v2/...
$ go run certbot-to-pem.go [path to private_key.json]
-----BEGIN RSA PRIVATE KEY-----
<snip>

```

Here is the program (`certbot-to-pem.go`):

```auto
package main

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io/ioutil"
	"os"
	"reflect"

	"gopkg.in/square/go-jose.v2"
)

func main() {
	if len(os.Args) != 2 {
		fmt.Println("Usage: certbot-to-pem path-to-certbot-private_key.json")
		os.Exit(1)
	}

	pkBuf, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		panic(err)
	}

	var k jose.JSONWebKey
	if err := k.UnmarshalJSON(pkBuf); err != nil {
		panic(err)
	}

	switch p := k.Key.(type) {
	case *rsa.PrivateKey:
		fmt.Println(string(pem.EncodeToMemory(&pem.Block{
			Type: "RSA PRIVATE KEY",
			Bytes: x509.MarshalPKCS1PrivateKey(p),
		})))
	default:
		panic("Don't know how to deal with " + reflect.TypeOf(p).String())
	}
}

```

---

<div class="post-metadata">

**Author:** ![chris5](https://avatars.discourse-cdn.com/v4/letter/c/f19dbf/32.png) [@chris5](https://community.letsencrypt.org/u/chris5)\
**Post date:** [January 24, 2018, 6:45pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/6 "2018-01-24T18:45:39Z")

</div>

Awesome - thank you for the go code. I was able to extract a valid RSA key out of the private\_key.json file. Saved this off to a private\_key.pem file and openssl reports “RSA key ok” when I run a ‘-check’ against it.

Now I’m trying to sort out why the key extracted is being reported by openssl as not matching the certificate I was issued by letsencrypt. Am I just not caffeinated enough and completely missing how this private key is used in letsencrypt?

End result I need is both the private key and certificate available so that I can use them in a slapd instance.

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [January 24, 2018, 8:28pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/7 "2018-01-24T20:28:50Z")

</div>

That’s your Let’s Encrypt account key. It isn’t used for certificates.

Your certificate private key is present as a symlink in `/etc/letsencrypt/live/{domain}/privkey.pem` .

---

<div class="post-metadata">

**Author:** ![chris5](https://avatars.discourse-cdn.com/v4/letter/c/f19dbf/32.png) [@chris5](https://community.letsencrypt.org/u/chris5)\
**Post date:** [January 24, 2018, 8:42pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/8 "2018-01-24T20:42:18Z")

</div>

Gotcha - thanks. That’s where I know they get stored on my other nodes. This system in particular though never set that dir structure up when the letsencrypt provisioning ran:

=====

# get a new cert

# letsencrypt certonly --standalone --csr “$WORKDIR/httpd-csr.der” --email “$EMAIL” --agree-tos

It’s a FreeIPA server and someone had contributed a routine to handle generation and installation of letsencrypt certs for the various IPA services:  
[https://github.com/freeipa/freeipa-letsencrypt.git](https://github.com/freeipa/freeipa-letsencrypt.git)

That’s why I was searching around to see if I could figure out some other place that the letsencrypt utility had perhaps put the private key and had for some reason thought it was being stored in the private\_key.json file, but I now follow the difference. I’ll re-run things via the CLI and get the proper dir structure working.

Thanks again for the help and enlightenment. Been staring at this for too long so obviously was getting confused.

-Chris

---

<div class="post-metadata">

**Author:** ![mnordhoff](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/mnordhoff/32/22583_2.png) [@mnordhoff](https://community.letsencrypt.org/u/mnordhoff)\
**Post date:** [January 24, 2018, 9:19pm UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/9 "2018-01-24T21:19:07Z")

</div>

When Certbot is run with the “`--csr`” option, it doesn’t set things up in the typical `/etc/letsencrypt/live/` location.

That’s why the `renew-le.sh` program is copying the certificate from a “`0000_cert.pem`” file somewhere.

The CSR was generated by `certutil`. I’m not familiar with certutil, but I assume it either read a private key from somewhere, or generated one and saved it somewhere.

You should consult the configuration or documentation for FreeIPA or certutil to try to determine where the key is.

Edit: I guess it’s in `/etc/httpd/alias/` – possibly not in a `.pem` file – but I’m really not sure.

---

<div class="post-metadata">

**Author:** ![felixf](https://avatars.discourse-cdn.com/v4/letter/f/fbc32d/32.png) [@felixf](https://community.letsencrypt.org/u/felixf)\
**Post date:** [February 14, 2018, 9:16am UTC](https://community.letsencrypt.org/t/how-to-get-openssl-rsa-private-key-out-of-private-key-json/4658/10 "2018-02-14T09:16:22Z")

</div>

In the acme-tiny documentation, there’s also a way to do the conversion with Python: [https://github.com/diafygi/acme-tiny/#use-existing-lets-encrypt-key](https://github.com/diafygi/acme-tiny/#use-existing-lets-encrypt-key)
