[Mostly off-topic] Build RSA private key from (p,q,e) triple

Viktor Dukhovni openssl-users at dukhovni.org
Fri Oct 8 23:34:48 UTC 2021


Every once in a while IIRC there are posts asking about how to create an
RSA private key from the two prime factors (p and q) and exponent.

Though there are surely simple examples in Python or Perl, I happened to
write on in Haskell.  Here it is for posterity (Main.hs and .cabal spec).
Input is from stdin, with each of p, q and e in either decimal or
0x-prefixed hex on separate lines.  10 lines of boilerplate and 3 lines
of code:

-----------
Main.hs:

    module Main (main) where
    import qualified Data.ByteString as B
    import Crypto.Number.Basic (numBytes)
    import Crypto.PubKey.RSA (generateWith)
    import Data.ASN1.BinaryEncoding (DER(DER))
    import Data.ASN1.Encoding (encodeASN1')
    import Data.ASN1.Types (toASN1)
    import Data.X509 (PrivKey(PrivKeyRSA))

    main :: IO ()
    main = do
        (p, q, e) <- (,,) <$> readLn <*> readLn <*> readLn
        mapM_ (B.putStr . toDER) $ generateWith (p,q) (numBytes (p*q)) e
      where toDER = encodeASN1' DER . flip toASN1 [] . PrivKeyRSA . snd
-----------
pqe.cabal:

    cabal-version:      2.4
    name:               pqe
    version:            0.1.0.0

    executable pqe
        main-is:          Main.hs
        build-depends:    base >= 4.14 && < 5
                        , asn1-encoding ^>= 0.9
                        , asn1-types ^>= 0.3
                        , bytestring >= 0.10 && < 0.12
                        , cryptonite ^>= 0.29
                        , x509 ^>= 1.7
-----------

The output is legacy RSA DER, but can be converted to PKCS8 PEM by
piping it to "openssl pkey -inform DER" (optionally adding a passphrase, ...):

If the program fails to read the (p, q, e) values it will exit with an
error.  If these fail to yield a valid key it will produce no output.

Silly little example with (p, q, e) = (29, 23, 3):

    $ printf '%s\n%s\n%s\n' 29 23 3 | cabal run -v0 | openssl pkey -inform DER -text
    -----BEGIN PRIVATE KEY-----
    MDMCAQAwDQYJKoZIhvcNAQEBBQAEHzAdAgEAAgICmwIBAwICAZsCAR0CARcCARMC
    AQ8CARg=
    -----END PRIVATE KEY-----
    RSA Private-Key: (10 bit, 2 primes)
    modulus: 667 (0x29b)
    publicExponent: 3 (0x3)
    privateExponent: 411 (0x19b)
    prime1: 29 (0x1d)
    prime2: 23 (0x17)
    exponent1: 19 (0x13)
    exponent2: 15 (0xf)
    coefficient: 24 (0x18)

More realistic example with a throw-away 2048-bit RSA key:

    $ cabal run -v0 <<EOF | openssl pkey -inform DER
    > 0xfb9e9c8a90615c9edd4870b2eb434a76abcf8ffe22d0764fdf9c921523b561b25edd2ebc547836ab2e40ba7229e2f023dde7f2209c0d8ba548d442a7e9ee415f97714a1f6cdd53aa6e67b2d020287c4b2fe730355e04fb25f93b078bf41a7af8e6700c4cf2e2407720e19f90464d8e9cb4d70d960c23309b3228b5510e550833
    > 0xe779cd8cc5a7d3ae41cfe4869598832aeec3e26b0919743486f9e5d0cf1e00826a6ffe865d347e35b0c55cfcef32515b6850d552be53b5af335c3e0a8062a5d4e063b33071365f3faac29e44990f83f2994bb93cf45a0c09a4fef13e441128ebe9c36ef2dc32dddffc99ed7d1ad7bc0232c1692ff3ee466c6bcb612074d54187
    > 0x10001
    > EOF
    -----BEGIN PRIVATE KEY-----
    MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDjg9dBZiSs+s4w
    JZgYVNknm6TW4vh8lONdEOe6lquTYDciA53K00dededDmjwvQYMHbsoA6TyC/5O4
    r8T21GaXwdQHHOsMou9JcyU+5Sun350I2lh7sDeJ0Ipz/nn3RwitXBHeWMLz1MLD
    Arutm0Wc1ZFC0ri2sxXTXsoYYc4mqMCBp0C8sPkQCAkheCsOBkWHaYK6vlsOXK/V
    O1LMaxqawYZamfPQ7Nznh3rVjVY2v/zlEtHqtNbzjMu6cJrLKgzYzhfxWMO/aNA/
    QhjZoUjSNFTP5VwhpyP7EFQlrMQFLb4vumboj5G66jiHWk/SeDn5LxhLyFbnijSe
    ADkUW0XlAgMBAAECggEBALnNBLCrCw6dMF/Pg9tzB3i6Oi8nYsjTCq8JTEVsIKiV
    rdDAZU+rpaA152yk+7uX47rhNmTyFPHiaLAuE0uEgFg0+cPpUOeb9JDmUSeBHlrV
    WjhNoG86pNCOl1NNIivYPfTduNX9ZRCd04RQqhaINJx1KVEKJ8FElXFt+ttYnHOi
    WDVGtpXYNjM+6s/R6UpkSTL0SpVjY7RjQMXZ8P3uUrAru/4UQba0ZcZIbHXSQO5J
    MCWa05pIOGuTs0C/2nUuO+lN5fqz6Cv8G+YlQjp54MUcjK3XisP/vx9GC4uvt3XT
    ik8y/+plvvBk1nwO8ehJ01bUzgokWNkePI58lfczqu0CgYEA+56cipBhXJ7dSHCy
    60NKdqvPj/4i0HZP35ySFSO1YbJe3S68VHg2qy5AunIp4vAj3efyIJwNi6VI1EKn
    6e5BX5dxSh9s3VOqbmey0CAofEsv5zA1XgT7Jfk7B4v0Gnr45nAMTPLiQHcg4Z+Q
    Rk2OnLTXDZYMIzCbMii1UQ5VCDMCgYEA53nNjMWn065Bz+SGlZiDKu7D4msJGXQ0
    hvnl0M8eAIJqb/6GXTR+NbDFXPzvMlFbaFDVUr5Tta8zXD4KgGKl1OBjszBxNl8/
    qsKeRJkPg/KZS7k89FoMCaT+8T5EESjr6cNu8twy3d/8me19Gte8AjLBaS/z7kZs
    a8thIHTVQYcCgYEAw1apdLENxNfYNmq3nAkLgAF2C/VhlbCj5ZcpmZu1LnlJSDEG
    KBWDa3Vm7te+SN3hGl79C+/aXDUeyxpMPUGoIsvxOXgYDeLsBvYeTZEJnSTJtZMp
    eyomx54rA3rVMNGS9WK7SemtWBqjvkUfvlRriKCj63o3RgJwGYqc6KZVwR0CgYEA
    uNfNSrKz+BfZOhg1WNR3Oht8lRwAIjFnmLmJyZr7TFDYiiJoTZmTh3Bnyn+4yyeo
    pL6X+wE9e4Iys2BfpnIgFsQxGXB/l3msL8JF/GV1vFpIC+4aPM6DelgltaORW1qg
    OQX1XT516DPrVUgOdRb9bYv2YvcGBap6/gFkyDRD75UCgYAkruxwtnikj5hKlaSJ
    /OIXvjj3VmbPpJtSFbvadTCTzBxWCWjaBQHf0nKsbNRa/9V60y44L0EVnC40Udj6
    r6LxLw66+GHJQPfhW5bnFIpUksIDC8fF9gUyc+C0AI3OJR+jrmlXNAllqoNIEsYd
    mkdZ2BxLEY0/fmBftSO3d/dC+A==
    -----END PRIVATE KEY-----

-- 
    Viktor.


More information about the openssl-users mailing list