Question

I created a key pair in C# and i'd like to upload the public key to a server so the server can send private data to the client. The server must use this public key, but it's in XML format. I've been reading and it seems the best way to encrypt a file in linux using a public key is with openssl.

This is how my public key looks like after being generated with RSACryptoServiceProvider in .net

<RSAKeyValue>
    <Modulus>sqprMX0n4y1gmmgpTt6pHb870k5U0MIuXixidD+S8foQf5BbFS44kth2uWDKzXOXqiONxIPHPb+84XdxrRi2O7bvLysztgrFeU8oNDMeuIwJOKVQzKoJ1vGqjBKiA9w48oQKxvO+Ck3GmObW67LFNcrt50sEco2/OMmrpiH3W8hRx55TcR1flCJduU0/6jA7Yct9ZfhOw5wBq6o5IwiT8Mi1R6LVq9sTzSNAWHC/bFcEONktz6NgUKbFKtt+mTfFGToiwPB1L4TecGyTIweH84nl8jVAngcMvvFP415Eg1kd9PJbRqrIESM5AU1YcsapWV3bsqEGVS2y+r5N4yzXPCYRCRyFWJSnNVlax+gtDFTNz3m9UT8m2E7elGe5hPhR6nN3votzBNvTeQ4Lwc5JDIvnWUg7aOdVIXnHQbBqEQke79BXxIv8tzVPczGkFqFExkmPPQQv8zJvBKkIYc+BFJtkylBiZfQX0590NS3L1y31VSeXn8Ncx2/ceJfUXsMWJ3sQ+dk51MKBJ2LLoyJq8IgloBLnXWvlYZ+tkzRVTExFR277V3Jr17DeTOMQGEg5HqRkbDDVGPTl2RvC2S2BTe7+r9xNzyAZMieVjZLZgb6icE6uSJFcu4qqJ1khQUjW7taymqW8Ao3oEiCUJKvRpZcJPMN+JtMnji+2we17ytk=</Modulus>
    <Exponent>AQAB</Exponent>
</RSAKeyValue>

The fact is that openssl only accepts PEM (as far as I've seen). How do I convert this key into something openssl can use to encrypt?

Was it helpful?

Solution

but it's in XML format

The presentation format is RFC 3275, XML-Signature Syntax and Processing.


How do I convert this key into something openssl can use to encrypt?

You will need to parse the RFC 3275 RSAKeyValue, then put it in an OpenSSL RSA structure.

Its somewhat painful.... are you sure you want to see it? (The XML parsing is left as an exercise to the reader, but it uses the values you provided above).

#include <stdio.h>
#include <string.h>

#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/evp.h>

int main(int argc, char* argv[])
{
    int ret = -1;

    char nz[] = "sqprMX0n4y1gmmgpTt6pHb870k5U0MIuXixidD+S8foQf5Bb"
             "FS44kth2uWDKzXOXqiONxIPHPb+84XdxrRi2O7bvLysztgrF"
             "eU8oNDMeuIwJOKVQzKoJ1vGqjBKiA9w48oQKxvO+Ck3GmObW"
             "67LFNcrt50sEco2/OMmrpiH3W8hRx55TcR1flCJduU0/6jA7"
             "Yct9ZfhOw5wBq6o5IwiT8Mi1R6LVq9sTzSNAWHC/bFcEONkt"
             "z6NgUKbFKtt+mTfFGToiwPB1L4TecGyTIweH84nl8jVAngcM"
             "vvFP415Eg1kd9PJbRqrIESM5AU1YcsapWV3bsqEGVS2y+r5N"
             "4yzXPCYRCRyFWJSnNVlax+gtDFTNz3m9UT8m2E7elGe5hPhR"
             "6nN3votzBNvTeQ4Lwc5JDIvnWUg7aOdVIXnHQbBqEQke79BX"
             "xIv8tzVPczGkFqFExkmPPQQv8zJvBKkIYc+BFJtkylBiZfQX"
             "0590NS3L1y31VSeXn8Ncx2/ceJfUXsMWJ3sQ+dk51MKBJ2LL"
             "oyJq8IgloBLnXWvlYZ+tkzRVTExFR277V3Jr17DeTOMQGEg5"
             "HqRkbDDVGPTl2RvC2S2BTe7+r9xNzyAZMieVjZLZgb6icE6u"
             "SJFcu4qqJ1khQUjW7taymqW8Ao3oEiCUJKvRpZcJPMN+JtMn"
             "ji+2we17ytk=";

    char ez[] = "AQAB";

    BIO* nn = NULL, *ee = NULL;
    BIO* b1 = NULL, *b2 = NULL;
    RSA* rsa = NULL;

    nn = BIO_new_mem_buf(nz, strlen(nz));
    if(!nn) { ret = 1; goto done; }

    ee = BIO_new_mem_buf(ez, strlen(ez));
    if(!ee) { ret = 2; goto done; }

    b1 = BIO_new(BIO_f_base64());
    if(!b1) { ret = 3; goto done; }

    b2 = BIO_new(BIO_f_base64());
    if(!b2) { ret = 4; goto done; }

    /* If you leave these out even though you   */
    /* are reading, then BIO_read will return 0 */
    /* and BIO_should_retry will return false   */
    BIO_set_flags(b1, BIO_FLAGS_BASE64_NO_NL);
    BIO_set_flags(b2, BIO_FLAGS_BASE64_NO_NL);

    nn = BIO_push(b1, nn);
    if(!nn) { ret = 5; goto done; }

    ee = BIO_push(b2, ee);
    if(!ee) { ret = 6; goto done; }

    rsa = RSA_new();
    if(rsa == NULL) { ret = 7; goto done; }

    unsigned char buff[4096];
    const int bsize = sizeof(buff);
    int rr = 0, rd = 0;

    /* See http://marc.info/?l=openssl-users&m=123171064303018&w=2 */
    /* for this contorted goodness */
    rd = 0;
    do {
        rr = BIO_read(nn, buff + rd, bsize - rd);
        if(rr < 0) { ret = 8; goto done; } /* failed */

        rd += rr;
    } while (rr > 0 || BIO_should_retry(nn));

    if(rd == 0) { ret = 9; goto done; }

    rsa->n = BN_bin2bn(buff, rd, NULL);
    if(rsa->n == NULL) { ret = 10; goto done; }

    rd = 0;
    do {
        rr = BIO_read(ee, buff + rd, bsize - rd);
        if(rr < 0) { ret = 11; goto done; } /* failed */

        rd += rr;
    } while (rr > 0 || BIO_should_retry(ee));

    if(rd == 0) { ret = 12; goto done; }

    rsa->e = BN_bin2bn(buff, rd, NULL);
    if(rsa->e == NULL) { ret = 13; goto done; }

    /***** Paydirt *****/

    RSA_print_fp(stdout, rsa, 0);

    ret = 0;

done:

    if(ret != 0)
        fprintf(stderr, "Failed to parse and validate RSA key\n");

    if(rsa)
       RSA_free(rsa), rsa = NULL;

    if(nn)
        BIO_free_all(nn), nn = NULL;

    if(ee)
        BIO_free_all(ee), ee = NULL;

    return ret;
}

How to encrypt in linux using an xml public key

With the RSA from above, try RSA_encrypt (and RSA_verify). See rsa(3) in the OpenSSL docs.


The fact is that openssl only accepts PEM (as far as I've seen).

OpenSSL accepts PEM and DER.


Here's the output of the program above on your parameters.

$ ./rsa-test.exe
Public-Key: (4096 bit)
Modulus:
    00:b2:aa:6b:31:7d:27:e3:2d:60:9a:68:29:4e:de:
    a9:1d:bf:3b:d2:4e:54:d0:c2:2e:5e:2c:62:74:3f:
    92:f1:fa:10:7f:90:5b:15:2e:38:92:d8:76:b9:60:
    ca:cd:73:97:aa:23:8d:c4:83:c7:3d:bf:bc:e1:77:
    71:ad:18:b6:3b:b6:ef:2f:2b:33:b6:0a:c5:79:4f:
    28:34:33:1e:b8:8c:09:38:a5:50:cc:aa:09:d6:f1:
    aa:8c:12:a2:03:dc:38:f2:84:0a:c6:f3:be:0a:4d:
    c6:98:e6:d6:eb:b2:c5:35:ca:ed:e7:4b:04:72:8d:
    bf:38:c9:ab:a6:21:f7:5b:c8:51:c7:9e:53:71:1d:
    5f:94:22:5d:b9:4d:3f:ea:30:3b:61:cb:7d:65:f8:
    4e:c3:9c:01:ab:aa:39:23:08:93:f0:c8:b5:47:a2:
    d5:ab:db:13:cd:23:40:58:70:bf:6c:57:04:38:d9:
    2d:cf:a3:60:50:a6:c5:2a:db:7e:99:37:c5:19:3a:
    22:c0:f0:75:2f:84:de:70:6c:93:23:07:87:f3:89:
    e5:f2:35:40:9e:07:0c:be:f1:4f:e3:5e:44:83:59:
    1d:f4:f2:5b:46:aa:c8:11:23:39:01:4d:58:72:c6:
    a9:59:5d:db:b2:a1:06:55:2d:b2:fa:be:4d:e3:2c:
    d7:3c:26:11:09:1c:85:58:94:a7:35:59:5a:c7:e8:
    2d:0c:54:cd:cf:79:bd:51:3f:26:d8:4e:de:94:67:
    b9:84:f8:51:ea:73:77:be:8b:73:04:db:d3:79:0e:
    0b:c1:ce:49:0c:8b:e7:59:48:3b:68:e7:55:21:79:
    c7:41:b0:6a:11:09:1e:ef:d0:57:c4:8b:fc:b7:35:
    4f:73:31:a4:16:a1:44:c6:49:8f:3d:04:2f:f3:32:
    6f:04:a9:08:61:cf:81:14:9b:64:ca:50:62:65:f4:
    17:d3:9f:74:35:2d:cb:d7:2d:f5:55:27:97:9f:c3:
    5c:c7:6f:dc:78:97:d4:5e:c3:16:27:7b:10:f9:d9:
    39:d4:c2:81:27:62:cb:a3:22:6a:f0:88:25:a0:12:
    e7:5d:6b:e5:61:9f:ad:93:34:55:4c:4c:45:47:6e:
    fb:57:72:6b:d7:b0:de:4c:e3:10:18:48:39:1e:a4:
    64:6c:30:d5:18:f4:e5:d9:1b:c2:d9:2d:81:4d:ee:
    fe:af:dc:4d:cf:20:19:32:27:95:8d:92:d9:81:be:
    a2:70:4e:ae:48:91:5c:bb:8a:aa:27:59:21:41:48:
    d6:ee:d6:b2:9a:a5:bc:02:8d:e8:12:20:94:24:ab:
    d1:a5:97:09:3c:c3:7e:26:d3:27:8e:2f:b6:c1:ed:
    7b:ca:d9
Exponent: 65537 (0x10001)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top