haskell-crypto / cryptonite

lowlevel set of cryptographic primitives for haskell
Other
226 stars 139 forks source link

What constitutes the very value of the PublicKey? #317

Closed GildedHonour closed 4 years ago

GildedHonour commented 4 years ago

Say, I create public and private keys this way:


import Crypto.PubKey.RSA.PKCS15
import Crypto.PubKey.RSA.Types

let rsaKey1 = PrivateKey
    { private_pub = PublicKey
        { public_n = 0xa8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb
        , public_e = 0x010001
        , public_size = 128
        }
    , private_d = someLongHexInteger
    , private_p = someLongHexInteger
    , private_q = someLongHexInteger
    , private_dP = someLongHexInteger
    , private_dQ = someLongHexInteger
    , private_qinv = someLongHexInteger
    }

How can I get the very value of the public key?

For instance, in ~/.ssh/id_rsa.pub I have an RSA public key. It's a string as everyone know.

Given this part:

    { private_pub = PublicKey
        { public_n = 0xa8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb
        , public_e = 0x010001
        , public_size = 128
        }

If I were to generate my RSA key pair via this library and store it in ~/.ssh at my computer, which part would I store in my ~/.ssh/id_rsa.pub?

Would it be public_n? Namely

0xa8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb

As is? Or would I have somehow encode, decode or transform it first? It's a hex digit here.

Also, what would I store in ~/.ssh/id_rsa -- as a private key?

tekul commented 4 years ago

The RSA public key is defined by the integers n and e (which are hex-encoded in the example above). Unfortunately you can't just store these strings in an ssh key file. Key and certificate files as used by openssh, openssl etc are usually stored in some form of ASN.1 encoding with the binary data Base64 encoded. Unfortunately this whole area is a bit of a mess with lots of different formats in use.

There is already an issue open about reading/writing RSA keys and you might also find this stackexchange answer useful.

GildedHonour commented 4 years ago

Ok.

Then another question. I have this code in Erlang/Elixir:

 :crypto.private_decrypt(:rsa, bin_data, rsa_priv_key, [{:rsa_padding, :rsa_pkcs1_oaep_padding}])

While I know how to encrypt a message using RSA, I can't figure out what the equlivant of those {:rsa_padding, :rsa_pkcs1_oaep_padding} will be in cryptonite and how to use them. Do you have an idea?

ocheron commented 4 years ago

I think this is module Crypto.PubKey.RSA.OAEP, with default parameters and SHA-1 as hash algorithm.

GildedHonour commented 4 years ago

thx