### Background

Staticman’s documentation gives a link to the public key for the public Staticman instance.

I’ve set up my own Staticman instance for testing
Staticman’s native GitLab support. It’s a coincidence that the public
Staticman instance has been hitting it’s API limit, as reported in
Staticman issue 227. To help others, I’ve published the URL of
my own Staticman instance, which is associated with the
GitHub/GitLab user **staticmanlab**. As Node.js’s RSA
library has been used in Staticman, I have the *responsibility* to *publish the
public RSA key for my Staticman instance*.

Before releasing my public key, I have to verify that public key stored in the
local repository is the *right* one. To avoid breaking things, I conducted the
testing in the local repository for
my public Staticman instance for Framagit.

### TODO

- Generate the RSA public key from my private one.
- Test my Staticman instance’s encryption endpoint by locally decrypting a test
message
`"test"`

. - Publish the key generated in step 1.

In a web browser, opening the following link gives an encrypted text.

```
GET https://staticman-frama.herokuapp.com/v3/encrypt/test
i6bxZBOCZYm4uPbBhyAL4Z42jYbWkeRWZk6Jefe4m01vFD8b4TtwDHOqs88EBMmpTd33EpgGlHsTA2D7FIox5a0+/2vAzZ1bQ2xQHknUY1mB7OI8TAbXYtr6ubJqhuH5c7QIAsn/qyt3ivYAZZUOzbvHxVCQsSnENeQYT19ZjtjvQs7lUXmSoDYuw3//J4VtnG1hWVlWa/gpkKAby9BmCEQEs4rca4CXlV+nnKdZID6Fe6xcca6Zp6WyYtxw5JfIeIGbQXNAZdSNsX4UJDXgPzNNe/ytndNucxKh+GEMqQxmlEkqq8QyL49HFRN3FjrjT6EcjU5v5McsWQWJuxaUBA==
```

N.B. Although the encryption algorithm itself is *deterministic*, its
implementation includes *OAEP*, in which a *random* sequence of zero bits is
appended to the message. Consequently, OpenSSL’s RSA encryption tool gives
*different* results for the *same* input. *The above output is just my
observation, and it can never be reproduced.*

### Problem

After having generated a public key from the private RSA key created by
OpenSSL, I was *unable* to decrypt the message encrypted online by my Staticman
instance for Framagit.

```
$ openssl rsa -in staticman_key -pubout -out staticman_key.pub
$ cat > text.enc # save Staticman's encrypted text into "text.enc"
$ cat text.enc | openssl rsautl -decrypt -inkey staticman_key
RSA operation error
140599129772480:error:0406506C:rsa routines:rsa_ossl_private_decrypt:data greate
r than mod len:../crypto/rsa/rsa_ossl.c:401:
```

### Discussion

The above error is due to an encoding mismatch. Statimcan encrypts a string
into a *base64 string*, whereas

```
$ openssl rsautl -encrypt -pubin staticman_key.pub -in msg -out msg.enc
```

produces a *binary file* from the input text file `msg`

. Therefore, to use
OpenSSL’s RSA decrytion utility, the encrypted message `text.enc`

has to be
*decoded into binary data from base64* first.

Then, I encountered *another* error.

```
$ cat text.enc | base64 -d | openssl rsautl -decrypt -inkey staticman_key
RSA operation error
139653142688192:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs
decoding error:../crypto/rsa/rsa_pk1.c:241:
139653142688192:error:04065072:rsa routines:rsa_ossl_private_decrypt:padding che
ck failed:../crypto/rsa/rsa_ossl.c:487:
```

Defacing `text.enc`

would *not* reproduce the above RSA padding check error. To
get the *same* error message, I generated *another* private RSA key with OpenSSL
and fed it to `-inkey`

. It seemed that I had used the wrong private RSA key
`staticman_key`

for testing. Nonetheless, `heroku config:get RSA_PRIVATE_KEY`

returned the *same* key. To be 100% sure of that, I had saved the it into a
temporary file, I ran `diff -u`

and got *nothing*.

### Solution

It’s clear that the parsing of the private RSA key caused the error.
Staticman’s source code in Node.js provides *no* clue for that. Finally, by
searching “ssh key decryption”, I found the *missing flag* `-oaep`

in
Bjørn Johansen’s file encryption guide.

Hence, the command to decrpyt Staticman’s encrypted string is

```
$ cat text.enc | base64 -d | openssl rsautl -decrypt -oaep -inkey staticman_key
test% # '%' indicates the absence of newline '\n' at the end in Zsh
```

### Conclusion

The public RSA key generated `staticman_key.pub`

from `openssl rsa -pubout`

*matches* the private key `staticman_key`

. The former is now ready to be
committed into the Git repository.

You may view the public keys for

- GitLab.com: https://github.com/VincentTam/staticman/blob/deploy/staticman_key.pub
- Framagit: https://framagit.org/staticman-gitlab-pages/staticman/blob/framagit/staticman_key.pub