Sign jwt with RSA OpenSSH keys, in python with pyJWT - ssh

I have generated an ssh key with:
ssh-keygen -t rsa -b 4096
Resulting in this:
-----BEGIN OPENSSH PRIVATE KEY-----
...
-----END OPENSSH PRIVATE KEY-----
Now trying to generate a jwt with this key:
import jwt
key = open("~/.ssh/id_rsa", "r").read()
token = jwt.encode(
claim={'iss': 'me'},
key=key,
algorithm='RS256'
)
I got the error:
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')])
Is it not possible to use openSSH key to sign the data?

PyJWT requires the Cryprography library for RSA, see here. Cryptography in turn supports the OpenSSH format, see here and here, e.g.:
import jwt
from cryptography.hazmat.primitives import serialization
private_key_OpenSSH = b'''-----BEGIN OPENSSH PRIVATE KEY-----
b3Blbn....suThWLDRnmD
-----END OPENSSH PRIVATE KEY-----'''
private_key = serialization.load_ssh_private_key(private_key_OpenSSH, password=None)
encoded = jwt.encode({"some": "payload"}, private_key, algorithm="RS256")
...
If the key is secured with a password, additionally the bcrypt module must be installed.

Related

How to convert OpenSSH ED25519 private key to the OpenSSH format that MySQL Workbench uses?

My OpenSSH ED25519 private key file has the following structure:
-----BEGIN OPENSSH PRIVATE KEY-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END OPENSSH PRIVATE KEY-----
MySQL workbench will not make a connection when the file is in this format the format required is described in this answer:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: XXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END RSA PRIVATE KEY-----
How can I make this conversion (peferably with a bash command)?
I do not wish to create the key pair again and place the public key in 10's of different places.
Unfortunately it cannot be done because ED25519 and RSA are completely different types of keys. You cannot convert between them.
The only solution is to create a new key pair. To create on that works with MySQL use:
ssh-keygen -m PEM -t rsa -b 8192

Decrypt encrypted RSA Private Key on the Browser side

I have an encrypted private RSA key:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,B92E0E3A7B... // <--- IV here.
...
-----END RSA PRIVATE KEY-----
I need to decrypt it via a passphrase, basically I need the equivalent of
openssl rsa -in <encrypted_private.key> -out <decrypted_private.key>
on the browser side with an Angular based client, using webcrypto and pkijs.
So for anyone who will in the future maybe face the same issue like I did:
PKI.js is providing an examples folder in their repo:
OpenSSLPrivateKeyEncryption
In there you will find a method called decrypt.
With the code I were able to decrypt my AES-CBC Private key.

Finding PKCS version while having the SSL certificate and the public and private keys

I'm new to PKI and need to know something. I'm not even sure if my question makes sense so excuse me in advance. If we have the SSL certificate and the public and private keys, can we find which version of PKCS is used ? Like PKCS#1 RSASSA-PKCS1-V1_5 or another ?
Thank you!
Usually you should have some text/base64 encoded PEM files. In those files you can see the type by the ----BEGIN line in the private key file.
-----BEGIN RSA PRIVATE KEY----- means you have an RSA private key in PKCS#1 format.
-----BEGIN PRIVATE KEY----- means you have an RSA private key in PKCS#8 format.
For all the formats see https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem

How can I determine the format of an ssh private key file?

I am developing an application that uses ssh keys (JSch), and it won't accept some ssh keys. I want to make guidelines to users so they know which keys they can use and which one they can't. Hence the question: how can I determine the format of an ssh private key file, going beyond the RSA/etc and the number of bits?
For instance, at the end of this question is a 3072 bit RSA key that was generated using ssh-keygen with no parameters on android/termux. it works in ssh but both JSch and JuiceSSH refuse to even open it. openssl rsa -text -noout -in file says:
unable to load Private Key
1991864336:error:0909006C:PEM routines:get_name:no start line:../crypto/pem/pem_lib.c:745:Expecting: ANY PRIVATE KEY
I can fix this by running ssh-keygen -p -m PEM -f file, and this might be a workaround for some users, but it would help to know in advance which formats work and which don't.
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

one PEM file with private key and certificate into JKS

I have a JKS keystore in client application and I have been given one PEM file containing both private key and certificate to use for SOAP signature. PEM file looks like this:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
First question is how to import correctly this PEM to JKS?
Second question: given private key isn't password protected, it's possible to add a password to it before importing it to JKS keystore?
Thanks!
If you prefer a GUI solution I would take Portecle. This simple key store management tool allows to create a JKS and then import cert and private key.
I am not sure if you can import cert and key from the same combined PEM file as you have it but may be the command "Import Key pair" of Portecle works with such a file.
If not you can simply split the PEM file directly after the -----END RSA PRIVATE KEY----- line into two PEM files and import them separately.
After importing, when you save the JKS Portecle will ask you for a password.