I have the content of a public key which I'm getting passed as an input to my system:
public_key = 'MDkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDIgAC/Bu9nyAtG1DQe7t7jszLb+dZ1GbXoR8G0rIXoak67NM='
I need to feed this into OpenSSL so it can take part in some ECDH decryption.
I can't seem to find a way to make OpenSSL accept the above input.
I've tried the following:
OpenSSL::PKey::RSA.new public_keyOpenSSL::PKey::RSA.new "-----BEGIN PUBLIC KEY-----\n#{public_key}\n-----END PUBLIC KEY-----\n"
Both of these return:
OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key: nested asn1 error
I can do:
OpenSSL::PKey.read "-----BEGIN PUBLIC KEY-----\n#{public_key}\n-----END PUBLIC KEY-----\n"
This doesn't return an error, however I can't then see a way to set the group as secp128r2 without throwing an error.
Doing c = OpenSSL::PKey::EC.new("secp128r2") and trying to set the key after with c.public_key = OpenSSL::PKey.read("-----BEGIN PUBLIC KEY-----\n#{public_key}\n-----END PUBLIC KEY-----\n").public_key throws the error:
OpenSSL::PKey::ECError: EC_KEY_set_public_key: incompatible objects
There’s a couple of things wrong here. First, this is an elliptic curve key, so trying to create an RSA key isn’t going to work. You need to create an EC key.
The EC key initializer accepts a number of ways to pass in the key. Unfortunately none of them match exactly what you have here. You can pass in the PEM form or the DER form though. The PEM form is just what you have with the
BEGIN PUBLIC KEYandEND PUBLIC KEYlines added, so this will work (similiar to what you’ve tried, only using the correct key type):The DER form is what you have but base 64 decoded, so this will also work and might be more convenient:
When you’ve done that you can call
key.group.curve_nameand you will see the second problem. This is a prime256v1 key, not a secp128r2 key. It doesn’t represent a point on the secp128r2 curve and so is causing theincompatible objectserror you are getting. Make sure you’re using matching key types.