Using the EdDSA algorithm with PyJWT - pyjwt

I am trying to use the EdDSA algorithm for encoding but I keep getting the below error.
Any ideas as to what I am doing wrong?
EllipticCurvePrivateKey = "-----BEGIN PRIVATE KEY-----\[HIDDEN]\n-----END PRIVATE KEY-----"
encoded = jwt.encode({"some": "payload"}, EllipticCurvePrivateKey, 'EdDSA')
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/rogermukai/Dev/Templates/jwt-example/.venv/lib/python3.10/site-packages/jwt/api_jwt.py", line 67, in encode
return api_jws.encode(json_payload, key, algorithm, headers, json_encoder)
File "/Users/rogermukai/Dev/Templates/jwt-example/.venv/lib/python3.10/site-packages/jwt/api_jws.py", line 153, in encode
key = alg_obj.prepare_key(key)
File "/Users/rogermukai/Dev/Templates/jwt-example/.venv/lib/python3.10/site-packages/jwt/algorithms.py", line 601, in prepare_key
raise InvalidKeyError(
jwt.exceptions.InvalidKeyError: Expecting a EllipticCurvePrivateKey/EllipticCurvePublicKey. Wrong key provided for EdDSA algorithms
I am expecting to be able to use the EdDSA algorithm as the documentation states that it is possible but it gives no examples.

Here is how I figured it out. I ran the below steps in order from top to bottom.
In the terminal/sehlll:
$ openssl genpkey -algorithm Ed25519 -out ed25519key.pem
$ cat ed25519key.pem
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIKRLPECftB6nJ/ZMQ/OXI1sdwDYUDP7gAq5sea0opeUT
-----END PRIVATE KEY-----
$ openssl pkey -in ed25519key.pem -pubout
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEA7Adh+4SttVNkOk1C/9XJj6uqtbgFZChpLuz+bq0cSF4=
-----END PUBLIC KEY-----
In python
import jwt
key = """-----BEGIN PRIVATE KEY-----
... MC4CAQAwBQYDK2VwBCIEIKRLPECftB6nJ/ZMQ/OXI1sdwDYUDP7gAq5sea0opeUT
... -----END PRIVATE KEY-----"""
encoded = jwt.encode({"Some":"Key"}, key, algorithm='EdDSA')
print(encoded)
>>> eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9.eyJTb21lIjoiS2V5In0.HDsL-x5WdP2rqpL0rq_Ir2dj9c8IEl_qqcfpUEZjncqP8df8Nrz-FGEfnI2-eB7JOGGI2WzZHM_O8vu7ieokCg
public_key = """-----BEGIN PUBLIC KEY-----
... MCowBQYDK2VwAyEA7Adh+4SttVNkOk1C/9XJj6uqtbgFZChpLuz+bq0cSF4=
... -----END PUBLIC KEY-----"""
decoded = jwt.decode(encoded, public_key, algorithms='EdDSA', verify=True)
print(decoded)
>>> {'Some': 'Key'}

Related

OpenSSL::X509::Certificate cannot open pem file - (PEM_read_bio_X509: no start line)

When I run:
OpenSSL::X509::Certificate.new("-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDd/deZ6ncdwxUH
Qlt2IV0LAZLEouWv7ntukG2FNhouvSW7xTi3JXTio7aBnPHUVCJdN41U1cVwfbtn
...
f5SDrfUDnuALz6YBiwf8vvCl1RSV2jB9yWKxGK9FG7iT96dBM1CYQMMx6xD204YL
CE/Q5PCKGOTWxOQSpLvctN3U
-----END PRIVATE KEY-----")
This gives OpenSSL::X509::CertificateError (PEM_read_bio_X509: no start line)
Is there something I'm missing?
(n.b. This question is a more generalized rewrite of a previous question to make it more useful to the wider community)
You are loading a private key there, not an X509 certificate. To load a key, you have to use the OpenSSL::PKey class rather than OpenSSL::X509::Certificate as such:
OpenSSL::PKey.read("-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDd/deZ6ncdwxUH
Qlt2IV0LAZLEouWv7ntukG2FNhouvSW7xTi3JXTio7aBnPHUVCJdN41U1cVwfbtn
...
f5SDrfUDnuALz6YBiwf8vvCl1RSV2jB9yWKxGK9FG7iT96dBM1CYQMMx6xD204YL
CE/Q5PCKGOTWxOQSpLvctN3U
-----END PRIVATE KEY-----")
Please refer to the documentation of OpenSSL::PKey.read for details.

Laravel passport not loading keys from .env file

I have copied and add private_key and public_key in .env file for passport.
But it says local.ERROR: LogicException: Key path "file:///application/storage/oauth-private.key" does not exist or is not readable in /application/vendor/league/oauth2-server/src/CryptKey.php:53 while generating token.
I want to load the keys from .env file.
Make sure the keys are written in one line without new lines except the begin and end phrase:
PASSPORT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
<your private key in one line here>
-----END PRIVATE KEY-----"
PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
<your public key in one line here>
-----END PUBLIC KEY-----"
Otherwise the key is not validated and passport is interpreting the string as a file path.

Ruby OpenSSL nested asn1 error

I have tried the advice on several of the questions posted here, but to no avail. I have the following files: (NOTE, I generated these on the fly and they are throwaway keys)
cert file:
-----BEGIN CERTIFICATE-----
MIIE+jCCA+KgAwIBAgIJAMLMeL/HH75vMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
VQQGEwJVUzENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkx
HjAcBgNVBAoTFU5pY2hvbGFzIFRlcnJ5IGRvdGNvbTEUMBIGA1UECxMLZGV2ZWxv
cG1lbnQxFjAUBgNVBAMTDW5pY2hvbGFzdGVycnkxKTAnBgkqhkiG9w0BCQEWGm5p
Y2hvbGFzQG5pY2hvbGFzdGVycnkuY29tMB4XDTE0MTIyNTA3MTkxNFoXDTE1MTIy
NTA3MTkxNFowga4xCzAJBgNVBAYTAlVTMQ0wCwYDVQQIEwRVdGFoMRcwFQYDVQQH
Ew5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVTmljaG9sYXMgVGVycnkgZG90Y29t
MRQwEgYDVQQLEwtkZXZlbG9wbWVudDEWMBQGA1UEAxMNbmljaG9sYXN0ZXJyeTEp
MCcGCSqGSIb3DQEJARYabmljaG9sYXNAbmljaG9sYXN0ZXJyeS5jb20wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRA4sMOx8cn59h8xvE1EcwudGYgGID
WixEEz+8UczLzoIovbZI//iExrwfM7edYRU/HyIufx+dvHj5bRABt5pOwgEiolDA
XtIttxpsCX23gLg/40TQY2JXRv10JgxEQ3680ypghfAEXisOiIQGrT0W+k6WpIRo
/+z4zh/UPqUmvV3ZnzG97jsFiQ0Nu8IKlByLWzoef+2MqG0GO95do3gCcBhAF3tm
v+buNVi8DgJnYTnKKD5S1+KYRSkNNioRs3zE+/W0vCA0/kLiFjSjMq3bSuGJbHmt
N/8+lodfZYh1HB6DRZoyfTynNDRHyKpPGqTvfp8U/E91kkpxusVSQFbrAgMBAAGj
ggEXMIIBEzAdBgNVHQ4EFgQUPAm5VdPIPbdedLtCEmpivYi8xfkwgeMGA1UdIwSB
2zCB2IAUPAm5VdPIPbdedLtCEmpivYi8xfmhgbSkgbEwga4xCzAJBgNVBAYTAlVT
MQ0wCwYDVQQIEwRVdGFoMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UE
ChMVTmljaG9sYXMgVGVycnkgZG90Y29tMRQwEgYDVQQLEwtkZXZlbG9wbWVudDEW
MBQGA1UEAxMNbmljaG9sYXN0ZXJyeTEpMCcGCSqGSIb3DQEJARYabmljaG9sYXNA
bmljaG9sYXN0ZXJyeS5jb22CCQDCzHi/xx++bzAMBgNVHRMEBTADAQH/MA0GCSqG
SIb3DQEBBQUAA4IBAQBIGsrZaWDwW2UWzTT2tbMEPOFVVZFZiWNazJLXFrXO1deW
1Ggaa2+h3tE+dMincQp7KPDeEOZ4VeXjrwZ1UfmJm5qOWhwJ2HnSBHay22tKO24Y
1qDF/ygMqW3yyr10MWZJaxQeUn+cgpclesS8IiTUVF61pYpjI8DrETa8Hwd8QJkC
YaB3qXOVWdbvJX3DTkYPDEqLkC0qzqibe8fWd0JFF5lDMAeCS5EgW+lu6M++dQve
u5L6Y1Xh8SvRB8SnZdy30OKNf0RrWPgNq9donv8nWgEJEYl9A/XRhWvl6ZWpQLEK
6GbCprqUIFgnWBhp0fteIMcgXZUe/oGBQ3/Yovd+
-----END CERTIFICATE-----
private key:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA0QOLDDsfHJ+fYfMbxNRHMLnRmIBiA1osRBM/vFHMy86CKL22
SP/4hMa8HzO3nWEVPx8iLn8fnbx4+W0QAbeaTsIBIqJQwF7SLbcabAl9t4C4P+NE
0GNiV0b9dCYMREN+vNMqYIXwBF4rDoiEBq09FvpOlqSEaP/s+M4f1D6lJr1d2Z8x
ve47BYkNDbvCCpQci1s6Hn/tjKhtBjveXaN4AnAYQBd7Zr/m7jVYvA4CZ2E5yig+
UtfimEUpDTYqEbN8xPv1tLwgNP5C4hY0ozKt20rhiWx5rTf/PpaHX2WIdRweg0Wa
Mn08pzQ0R8iqTxqk736fFPxPdZJKcbrFUkBW6wIDAQABAoIBAEFpWHTFc+EjW1/u
EzywKm9nV97gHsxpxfywAXxQJUWLJVTWultyMDZtc6ZYKxiHr3yHo8zlX+GfgESf
Cyleal5HfM93+MmbYy+HZC93cO6izAbCe2C0GayyvNNCrQgYD2vMsjBu+kSDq/nq
Y1crlDjCsSGX7xBlN6ZN68wiptDOVa1aBL+H3kzHtarURVdKY1MXrscR760/o8Nh
qA/9GA1PoHQ7ApNG8oLVPS9SU4JU3PfURCQTk8otYZ4GrScpSeYp9ISi/UODlF1M
IY+B9Bfrf2Eftv8zP+eF1UbTeBmMq0boy+afZsugMqjN/FpUpxUALlRX96az+VY9
fDSuUPECgYEA9Vv8E4HBbnzPrzA6jyYNcSnkfzTcNxuYaIqTrxWSLi018u1kRa9Z
zLyKFNZRg3+RTWKAqDLKkC/oZZARlPcpx8uzV1T+zrffrnf2aK1LDHUHEmsMj7PY
2DIhghO90BPGuWPpbHjmpr51hHH6+n/LcLN0EHQ2T9wh5HZY75qup9cCgYEA2hQL
sE0+Bp2rFP2CMfl5SAhhtmjrTGg76mItMmGj/3ycZ6CxRw/5nSepau7nbCZXSK+i
Pp/EutuUNcD9ZmyP7z7In2PdWP8X8OSjd9abUn3cRPz8IjSOkbuUMKYWnweUl5Qw
IgygFDYYGjEclOuUlbIzzhp9zeOJAwY0vsxulw0CgYAeaEnzOO95++nZMkbvmq2r
yp9QzIJGKhtXSWVIG4pEQsIe2yDEKhkc8HjEYFM10sd1KbH8Jl9IQ0ev3ozvQzpg
UnRlbFkv0UXdX2ygSGm2n4JC3BVwcb97+6p/bmbltK26KBGzqcAcBhqWUXHjPZc+
3l6R83UPrJ5eq/QVrbvbfQKBgBwvNwuEEB4exnuh/++hhHEw1CAVE0P+vK+gHKNE
R0O/wR8Lf53ljKco9xZg5fvuQJ2eRWO+llhoBJGl7ZoNMdUD0j33VCYqYde6VP4p
+E0DAzLPV268SCjBi3d2H7pR6nxkpIviAdZa32aTLlR41e066MMcXWH8pDqF1M9L
8IcJAoGBAMgoNz/y5LOclcfTLsj/1eYYDDCyB0a2rDsykcYSxeUOibRSicIQnE09
VW3NHZS56gsz4LFCK0Jxq9w76u/ZnhU5FCHs0+BwzyDYnyUnZQre38hcbEcMbEoe
Scmh3qRTfoS74qJzxx/rfhqRnLQal/FR4qf8V559gmB8idZmgMwK
-----END RSA PRIVATE KEY-----
The md5s match for these and when I run the following command:
openssl pkcs12 -export -out azure2.pfx -inkey azure2.key -in azure2.crt
I get a binary encoded pkcs12 file back.
However, when i try to do an http post, i get the following error:
Uncaught exception: nested asn1 error
Any ideas?
EDIT:
I tried the following:
p12 = OpenSSL::PKCS12.new(File.read("azure2.pfx"))
p p12.certificate
p p12.ca_certs
and i get valid output.... So what gives?
So, once again, I answered my own question. I was trying to read a DER-form pkcs12. I had to convert it to PEM format.
For others who might run into this. I had this error and fixed it by removing all carriage returns from my certificate string. (eg. replace "\r\n" and "\n\r" with just "\n" or just remove all "\r"

OpenSSL - Neither PUB key nor PRIV key:: nested asn1 error

I am trying to initialize OpenSSL::PKey::RSA using a public key, and it is not working.
Following is the key pair:
-----BEGIN RSA PRIVATE KEY-----
MIIBOwIBAAJBALbkpbDFbZ54bM5ybwwdCqsUHjxWQF4B0Q1sAOBFEYdpxZJZ8dAz
ycPzIgSlPc8yqjeqwJQtvCpktrntALpX1ksCAwEAAQJAYT0XyvBs48BrOSgmWm5m
aab8nF/PQSv+FgDCRnryYue3WZOpUqITB0w6ivC68G/+Mf6IXyE4ljqw2iIAdjyv
YQIhAOE20o2bLPMtziEOdH0KGpN0gNYpe38jGyvGw7k5gZd9AiEAz+TWZRJpc9yX
5dew3xcBtIhaTPFmVLgmfU7FwIWW32cCIQCvKK9LmUO1gouN5CsvUNtokbTeW/cD
467vNjDlb1deFQIhAK55pZ1p2GrOpgTWArEYg+vZy79rkbBkZJkh9UFgXIDdAiBm
Rglcmt9cD2Vqg7xMr7cP3FJbSmJffSwYve1fazuZOw==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MEoCAQACQLbkpbDFbZ54bM5ybwwdCqsUHjxWQF4B0Q1sAOBFEYdpxZJZ8dAzycPz
IgSlPc8yqjeqwJQtvCpktrntALpX1ksCAwEAAQ==
-----END PUBLIC KEY-----
OpenSSL::PKey::RSA.new(private_key) # WORKS!
OpenSSL::PKey::RSA.new(public_key) # FAILS!
OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key:: nested asn1 error
from (irb):16:in `initialize'
from (irb):16:in `new'
from (irb):16
from /Users/dhracker/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/commands/console.rb:47:in `start'
from /Users/dhracker/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/commands/console.rb:8:in `start'
from /Users/dhracker/.rvm/gems/ruby-1.9.3-p194/gems/railties-3.2.8/lib/rails/commands.rb:41:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
another_public_key = OpenSSL::PKey::RSA.new(512).public_key
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMS6XZD2NHTCwdgT+A2/PkStyJwYX/Qu
mfCyZc5TE5IZYaKsBg4uGcI97r8lxEv6rx5b0b6cIwQ7A7e6CUVph5MCAwEAAQ==
-----END PUBLIC KEY-----
OpenSSL::PKey::RSA.new(another_public_key) # WORKS!
What is wrong with public_key that causes things to fail?
Following this link http://skim.la/2012/01/16/rsa-public-key-interoperability-between-ruby-and-android/ I had more success this way.
require 'openssl'
require 'base64'
public_key = "MIIBCgKCAQEA20O377QEiZvPsj14LKl2xO23iirJB5WDTVjeab1cIOJu1vbV+Pdwl1Bov8m896ZG4K0S/qvfJcdHLovr2WJ+o2maK1XZCNy8lA" +
"zIPzZrj/yDZAB2GSjR3in1lQRQPtWjIOdB8Cy2FGybEstIkpf8MD3XMWp5g8BtdOv43ekjBuTiGGLlPRG0+IiazjHlWjyl6DU9x9m2Jxks0H6YZud6zf4s9Q6" +
"9vPUYgOZXWs7IghxqrVGE5mWxoRudsDFhLYP706+IrSxGOf5fE0/8fjtzj/eJayCLmkUWq/xsts5tBAbwsX5xKdk8iD0OU2qOEbVuiYmehEiJnvO2vyd+t76C" +
"xwIDAQAB"
rsa_public_key = OpenSSL::PKey::RSA.new(Base64.decode64(public_key))
It looks like what you've got there should work only the public key itself isn't valid. Maybe you mangled them at some point by adding or removing an extra character by accident. You can test this key out and should see it work out
public_key = "-----BEGIN RSA PUBLIC KEY-----\nMIIBCgKCAQEAoxi2V0bSKqAqUtoQHxWkOPnErCS541r6/MOSHmKOd6VSNHoBbnas\nZRQSDUTbffB6C++DbmBCOHmvzYORD0ZWYgyMcgbYJD48Z2fe0nm+WMYN5u8DPnTP\nvf8b/rJBxGF0dsaoFAWlB81tTnKFCxAbCSgfmQt+Vd4qupGZ5gGu9uoKlaPjmYuA\nIxIjUMcu3dov7PQ+PZIvdkM0fiz8YIl8zo+iWWyI2s6/XLoZJ4bYs2YJHZDf6biU\nsZhs8xqh/F6qlcRt3Ta25KMa0TB9zE3HHmqA/EJHFubWFRCrQqpboB0+nwCbmZUl\nhaxA79FRvYtORvFAoncoFD4tq3rGXcUQQwIDAQAB\n-----END RSA PUBLIC KEY-----\n"
OpenSSL::PKey::RSA.new(public_key)
I generated my key by first running the linux command for generating an openSSH key pair
$ ssh-keygen -t rsa -b 1024
Then I converted OpenSSH style public key to an OpenSSL style key (PEM format), storing it in a file called 'pem'.
$ ssh-keygen -f testing_rsa.pub -e -m pem > pem
I was facing the same issue and I tried lot of different solutions given across internet.
But the actual problem was with the key that I was providing.
The formatting of the key should be proper. There should not be any extra character or \n , \t.
I hope this might help you. So, please check your key once again.
Same day I was stuck with the same issue, changing passphrase might help you. So verify your passphrase and change it in notification class.I hope this might help you.
I have changed in file app/jobs/notification_job.rb
certificate: Rails.root.join('Your Pem File Name Goes Here'),# required
passphrase: "PASSPHRASE GOES HERE", # optional
gateway: "gateway.push.apple.com", # optional; See note below.
# gateway: "gateway.sandbox.push.apple.com", # optional; See note below.

Load PKCS#8 binary key into Ruby

I'm trying to load a particular private key encoded in binary DER format (PKCS#8) into Ruby.
However, OpenSSL::PKey won't recognize it. I can make it work by doing some console work and transforming it into a PEM like so:
openssl pkcs8 -inform DER -in file.key -passin pass:xxxxxxxx >private_key.pem
After this, the key can correctly be read.
However, since I would like for the whole process to be done in memory instead of writing and reading files.
So my question is: Is it possible to load private keys from the binary encoded DER format into Ruby/OpenSSL?
Thank you for your time,
Fernando
Yes, you can indirectly load PKCS#8 DER-encoded private keys using Ruby OpenSSL.
OpenSSL::PKey::RSA.new will only handle PEM-formatted PKCS#8, but it is easy to read the binary DER and convert it to a PEM-formatted string and then load from the string.
For example, with these DER-encoded private keys:
$ openssl genrsa | openssl pkcs8 -topk8 -outform DER \
-nocrypt -out pkcs8.key
$ openssl genrsa | openssl pkcs8 -topk8 -outform DER \
-v2 des3 -passout pass:secret -out pkcs8_des3.key
You can do something like this:
require 'openssl'
require 'base64'
def box(tag, lines)
lines.unshift "-----BEGIN #{tag}-----"
lines.push "-----END #{tag}-----"
lines.join("\n")
end
def der_to_pem(tag, der)
box tag, Base64.strict_encode64(der).scan(/.{1,64}/)
end
pem = der_to_pem('PRIVATE KEY', File.read('pkcs8.key'))
key = OpenSSL::PKey::RSA.new(pem)
pem2 = der_to_pem('ENCRYPTED PRIVATE KEY', File.read('pkcs8_des3.key'))
key2 = OpenSSL::PKey::RSA.new(pem2, 'secret')
Read the DER bytes, Base64 them and put the PEM tags on top and bottom, and then load the key.
Certificate is capable of handling DER-encoded certificates and certificates encoded in OpenSSL's PEM format.
You could find documentation about OpenSSL implementation for Ruby here :

Resources