generate RSA 1024 key pair using openssl

15,896

Solution 1

but why these two files are in different size(608 bytes and 162 bytes)? the key pair of RSA 1024 should be the same size, right?

There are two formats for the private key (see, for example, PKCS #1 or RFC 3447).

OpenSSL uses the second representation, which can be described as the "long form" with n, e, d dp, dq, etc.

$ openssl pkey -in test-key.txt -inform PEM -text
-----BEGIN PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAMQFuyeb8y+Losq3
0xBjg3EjbTdb+CddlZZ+JQWxjrhkJslLN7UsxL83Qz0ZNYRxGW5Pd1RDUfmqWAYm
5xZThRFoz7seEQ0yIfVnoI/OlDuzx+bb8ci3tSGQKQDPHv5aO8jdoeBtP0oz8Zog
oNBuVeRATnHkCoocrd0vwur+xWoZAgMBAAECgYBkiLvwGJ+k5uzbI2Rwp1kmkZDW
L6kaJ3ks8g1y2hnkoBj0bEtp9EgD+gfWMjOsdYUhekgtQ0mrzp3Oqe0jGjrISEoC
iKriv2mXA2mnlPUpulQ6VRMRDCiuofoRC9kG8hvzQx+abmRr/expGvXGJ2kkItTI
t6PEUnEnpctSE819sQJBAPVPXK3R56JMMRrykwct8RsKKx7iiV+X5R1zzNZIelPz
eLmt7h1y1Xk/fP22MVeQDfxXvQkjdG5HOKuXD3a4eKMCQQDMkIZERj/ll6EqVxPa
CeZuOiYNcmVXIEq3T3TRbjYxN2zBIdDBE9Fq19ZW/YBe81M8AVegxWu6mzW40r9b
kxITAkB3W/YsXUXnoksCYaVIiQIXtgrlLDTLXo0Ml5vDZ+CdmInVTtvdWFKmfE3E
5TF8+YrUjZxdJfMw9VaNpyLPEVMhAkADQW2Rmpibu80J0nbzamLrcCt43VA1kcL+
pdoTFzDvmZU2gaZD3F/h1muH2OL5H+A8PT06xsmPH7c8KMZ4259XAkAyG8NmkLIB
s4cfkDt6qeLMkBSI1TLe62/aXZAdIhkWKqH7jahOCzb4AiHaPxGf/kcIMtvLRw5J
NBOLSFGTJBoc
-----END PRIVATE KEY-----
Private-Key: (1024 bit)
modulus:
    00:c4:05:bb:27:9b:f3:2f:8b:a2:ca:b7:d3:10:63:
    83:71:23:6d:37:5b:f8:27:5d:95:96:7e:25:05:b1:
    8e:b8:64:26:c9:4b:37:b5:2c:c4:bf:37:43:3d:19:
    35:84:71:19:6e:4f:77:54:43:51:f9:aa:58:06:26:
    e7:16:53:85:11:68:cf:bb:1e:11:0d:32:21:f5:67:
    a0:8f:ce:94:3b:b3:c7:e6:db:f1:c8:b7:b5:21:90:
    29:00:cf:1e:fe:5a:3b:c8:dd:a1:e0:6d:3f:4a:33:
    f1:9a:20:a0:d0:6e:55:e4:40:4e:71:e4:0a:8a:1c:
    ad:dd:2f:c2:ea:fe:c5:6a:19
publicExponent: 65537 (0x10001)
privateExponent:
    64:88:bb:f0:18:9f:a4:e6:ec:db:23:64:70:a7:59:
    26:91:90:d6:2f:a9:1a:27:79:2c:f2:0d:72:da:19:
    e4:a0:18:f4:6c:4b:69:f4:48:03:fa:07:d6:32:33:
    ac:75:85:21:7a:48:2d:43:49:ab:ce:9d:ce:a9:ed:
    23:1a:3a:c8:48:4a:02:88:aa:e2:bf:69:97:03:69:
    a7:94:f5:29:ba:54:3a:55:13:11:0c:28:ae:a1:fa:
    11:0b:d9:06:f2:1b:f3:43:1f:9a:6e:64:6b:fd:ec:
    69:1a:f5:c6:27:69:24:22:d4:c8:b7:a3:c4:52:71:
    27:a5:cb:52:13:cd:7d:b1
prime1:
    00:f5:4f:5c:ad:d1:e7:a2:4c:31:1a:f2:93:07:2d:
    f1:1b:0a:2b:1e:e2:89:5f:97:e5:1d:73:cc:d6:48:
    7a:53:f3:78:b9:ad:ee:1d:72:d5:79:3f:7c:fd:b6:
    31:57:90:0d:fc:57:bd:09:23:74:6e:47:38:ab:97:
    0f:76:b8:78:a3
prime2:
    00:cc:90:86:44:46:3f:e5:97:a1:2a:57:13:da:09:
    e6:6e:3a:26:0d:72:65:57:20:4a:b7:4f:74:d1:6e:
    36:31:37:6c:c1:21:d0:c1:13:d1:6a:d7:d6:56:fd:
    80:5e:f3:53:3c:01:57:a0:c5:6b:ba:9b:35:b8:d2:
    bf:5b:93:12:13
exponent1:
    77:5b:f6:2c:5d:45:e7:a2:4b:02:61:a5:48:89:02:
    17:b6:0a:e5:2c:34:cb:5e:8d:0c:97:9b:c3:67:e0:
    9d:98:89:d5:4e:db:dd:58:52:a6:7c:4d:c4:e5:31:
    7c:f9:8a:d4:8d:9c:5d:25:f3:30:f5:56:8d:a7:22:
    cf:11:53:21
exponent2:
    03:41:6d:91:9a:98:9b:bb:cd:09:d2:76:f3:6a:62:
    eb:70:2b:78:dd:50:35:91:c2:fe:a5:da:13:17:30:
    ef:99:95:36:81:a6:43:dc:5f:e1:d6:6b:87:d8:e2:
    f9:1f:e0:3c:3d:3d:3a:c6:c9:8f:1f:b7:3c:28:c6:
    78:db:9f:57
coefficient:
    32:1b:c3:66:90:b2:01:b3:87:1f:90:3b:7a:a9:e2:
    cc:90:14:88:d5:32:de:eb:6f:da:5d:90:1d:22:19:
    16:2a:a1:fb:8d:a8:4e:0b:36:f8:02:21:da:3f:11:
    9f:fe:47:08:32:db:cb:47:0e:49:34:13:8b:48:51:
    93:24:1a:1c

it's pem format?

Yes:

$ openssl genrsa -out privatekey.txt 1024
$ cat privatekey.txt 
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDEBbsnm/Mvi6LKt9MQY4NxI203W/gnXZWWfiUFsY64ZCbJSze1
LMS/N0M9GTWEcRluT3dUQ1H5qlgGJucWU4URaM+7HhENMiH1Z6CPzpQ7s8fm2/HI
t7UhkCkAzx7+WjvI3aHgbT9KM/GaIKDQblXkQE5x5AqKHK3dL8Lq/sVqGQIDAQAB
AoGAZIi78BifpObs2yNkcKdZJpGQ1i+pGid5LPINctoZ5KAY9GxLafRIA/oH1jIz
rHWFIXpILUNJq86dzqntIxo6yEhKAoiq4r9plwNpp5T1KbpUOlUTEQworqH6EQvZ
BvIb80Mfmm5ka/3saRr1xidpJCLUyLejxFJxJ6XLUhPNfbECQQD1T1yt0eeiTDEa
8pMHLfEbCise4olfl+Udc8zWSHpT83i5re4dctV5P3z9tjFXkA38V70JI3RuRzir
lw92uHijAkEAzJCGREY/5ZehKlcT2gnmbjomDXJlVyBKt0900W42MTdswSHQwRPR
atfWVv2AXvNTPAFXoMVrups1uNK/W5MSEwJAd1v2LF1F56JLAmGlSIkCF7YK5Sw0
y16NDJebw2fgnZiJ1U7b3VhSpnxNxOUxfPmK1I2cXSXzMPVWjacizxFTIQJAA0Ft
kZqYm7vNCdJ282pi63AreN1QNZHC/qXaExcw75mVNoGmQ9xf4dZrh9ji+R/gPD09
OsbJjx+3PCjGeNufVwJAMhvDZpCyAbOHH5A7eqnizJAUiNUy3utv2l2QHSIZFiqh
+42oTgs2+AIh2j8Rn/5HCDLby0cOSTQTi0hRkyQaHA==
-----END RSA PRIVATE KEY-----

The -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- indicates the key is in PEM format.

If it lacks the -----BEGIN XXX----- and -----END XXX----- and is binary, then its likely DER format.


RSA* rsa = RSA_new();
BN_hex2bn(&rsa->n, WHAT_HERE);
BN_hex2bn(&rsa->e, AND_WHAT_HERE);
RSA_public_encrypt(....);

Try using PEM_read_PrivateKey, PEM_read_PupblicKey and friends since the keys are in PEM format. There's lots of friends, and they are listed at pem(3) in the OpenSSL docs.

OpenSSL uses the functions frequently. For example, cd into <openssl dir>/apps and look at the uses:

openssl-1.0.1f/apps$ grep -R PEM_read *
apps.c:     x=PEM_read_bio_X509_AUX(cert,NULL,
apps.c:     pkey=PEM_read_bio_PrivateKey(key,NULL,
apps.c:     rsa = PEM_read_bio_RSAPublicKey(key, NULL, 
apps.c:     pkey=PEM_read_bio_PUBKEY(key,NULL,
ca.c:   if ((req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL)) == NULL)
cms.c:          cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
cms.c:          rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
crl2p7.c:           crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
crl.c:      x=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL);
dh.c:       dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
dhparam.c:              dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
dhparam.c:              dh=PEM_read_bio_DHparams(in,NULL,NULL,NULL);
dsaparam.c:     dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL);
ec.c:           eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, 
ec.c:           eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
ecparam.c:      group = PEM_read_bio_ECPKParameters(in,NULL,NULL,NULL);
gendsa.c:   if ((dsa=PEM_read_bio_DSAparams(in,NULL,NULL,NULL)) == NULL)
genpkey.c:  pkey = PEM_read_bio_Parameters(pbio, NULL);
nseq.c:     while((x509 = PEM_read_bio_X509(in, NULL, NULL, NULL))) 
nseq.c: if (!(seq = PEM_read_bio_NETSCAPE_CERT_SEQUENCE(in, NULL, NULL, NULL))) {
pkcs12.c:   while((cert = PEM_read_bio_X509(in, NULL, NULL, NULL))) {
pkcs7.c:        p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL);
pkcs8.c:            p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
pkcs8.c:            p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
pkeyparam.c:    pkey = PEM_read_bio_Parameters(in, NULL);
req.c:          req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);
req.c:      param = PEM_read_bio_Parameters(pbio, NULL);
req.c:          x = PEM_read_bio_X509(pbio, NULL, NULL, NULL);
s_client.c:     sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
sess_id.c:      x=PEM_read_bio_SSL_SESSION(in,NULL,NULL,NULL);
smime.c:            p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
s_server.c: ret=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
s_server.c:     if (PEM_read_X509(in,&x,NULL) == NULL)
x509.c:     req=PEM_read_bio_X509_REQ(in,NULL,NULL,NULL);

The apps directory is where the source code for utilities like genrsa, x509, req, encrypt, decrypt, etc are located.

Solution 2

There are a few reasons why the private key is larger than the public key. One is that whilst the private key need only contain the modulus and private exponent (these are the only parameters required to decrypt), it also contains the public exponent (so that given the private key, the public key can always be recreated), as well as the original prime values P and Q and a number of other derived parameters (DP, DQ, InverseQ).

It is possible to create a private key containing only the required parameters (modulus and private exponent), however even in this case the private key will be larger due to the sizes of the public and private exponents - the public exponent is generally small, and usually one of a set of predefined values - e.g. 65537, however the corresponding private exponent is a much larger value.

With regards the use of PEM files with OpenSSL, there are a number of functions for loading RSA keys from PEM format files. See: https://www.openssl.org/docs/crypto/pem.html

Share:
15,896
aj3423
Author by

aj3423

build software then crack it

Updated on August 21, 2022

Comments

  • aj3423
    aj3423 over 1 year

    I'd like to generate RSA 1024 key pairs. What I got from google is

     openssl genrsa -out privatekey.txt 1024 
     openssl rsa -in privatekey.txt -pubout -out publickey.txt
    

    but why these two files are in different size(608 bytes and 162 bytes)? the key pair of RSA 1024 should be the same size, right?

    and these files begin with

    0x30 0x81...

    and

    0x30 0x82...

    it's pem format? How could they be used with openssl?

    RSA* rsa = RSA_new();
    BN_hex2bn(&rsa->n, WHAT_HERE);
    BN_hex2bn(&rsa->e, AND_WHAT_HERE);
    RSA_public_encrypt(....);
    

    Thanks.

  • jww
    jww about 10 years
    "... private key with only the required parameters (modulus and private exponent)" - you actually need e too. If e is well known (3, 17, 65537), then you can try the well known suspects. If its not well known, then you will need to retain it.
  • Iridium
    Iridium about 10 years
    @noloader - you only need to retain e if you wish to be able to re-derive the public key, the actual decryption process relies only on the modulus and private exponent.
  • aj3423
    aj3423 about 10 years
    Professional. Now I got why there're PEM_xxx functions. Thanks.