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.
- Generate the RSA public key from my private one.
- Test my Staticman instance’s encryption endpoint by locally decrypting a test
- Publish the key generated in step 1.
In a web browser, opening the following link gives an encrypted text.
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.
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:
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:04065072:rsa routines:rsa_ossl_private_decrypt:padding che
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.
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
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
The public RSA key generated
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