Verwenden Sie den OpenSSL-RSA-Schlüssel mit .Net

Lesezeit: 7 Minuten

Verwenden Sie den OpenSSL RSA Schlussel mit Net
abhithakur88

Ich verwende openssl 0.9.6g und habe ein öffentliches/privates Schlüsselpaar mit RSA_generate_key() erstellt. Wenn ich den Schlüssel mit speichere PEM_write_bio_RSAPublicKeyes gibt mir Schlüssel wie:

-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

Ich habe ein anderes Modul in .NET, das aufgrund seines Formats eine Ausnahme auslöst, wenn es in diesem Schlüssel übergeben wird. Es hat ein Format wie:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

So konvertieren Sie meine Schlüssel in dieses Format. Ich verwende C++.

In .NET verwende ich openssl.net, der Code lautet wie folgt:

string publicKey = @"-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAKGtqUVBBqcGCRYa7Sb6JVQirOX3hggWP2k7CzEtbF/soOONK510Kefm
omXBrGn2t79ES+hAcCvGSiiVZGuEb3UPiznzbiY150SME5nRC+zU0vvdX64ni0Mu
DeUlGcxM1eWSpozO71at6mxLloEMUg0oSWHfAlS5a4LVaURrJqXfAgMBAAE=
-----END RSA PUBLIC KEY-----";

Encoding enc = Encoding.ASCII;
string text = "hello world";
byte[] msg = enc.GetBytes(text);
CryptoKey key = CryptoKey.FromPublicKey(publicKey, "");
RSA rsa = key.GetRSA();
byte[] res = rsa.PublicEncrypt(msg, RSA.Padding.PKCS1);

Die Ausnahme kommt in Reihe:

CryptoKey key = CryptoKey.FromPublicKey(publicKey, "");

Wenn ich den Schlüssel verwende:

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbhcU+fhYmYLESZQAj1hKBXsNY
si0kYHNkxpP7ftxZiTFowWUVXHzQgkcYiCNnp3pt1eG6Vt0WDzyFYXqUUqugvX41
gkaIrKQw/sRiWEx49krcz7Vxr3dufL6Mg3eK7NyWDGsqwFrx/qVNqdhsHg12PGNx
IMY4UBtxin2A8pd4OwIDAQAB
-----END PUBLIC KEY-----

Es funktioniert gut.

Ich habe mich nach diesem Problem umgesehen. Ich denke, wonach ich suche, ist “wie man einen öffentlichen RSA-Schlüssel vom pkcs # 1- in das x509-Format konvertiert.

  • Bitte erstellen Sie ein MCVE.

    – TobiMcNamobi

    27. Mai 2015 um 7:31 Uhr

  • “Ich verwende openssl 0.9.6g…” – Oh wow. Ihnen ist klar, dass das schon lange aufgegeben wurde und jetzt mit ungepatchten Sicherheitsfehlern anämisch ist, oder?

    – jww

    27. Mai 2015 um 18:42 Uhr

  • @jww Nun, es ist eigentlich ein altes Produkt. In der neuen Version unseres Produkts haben wir die neueste Version von openssl, aber die alte Version (unter Wartung) verwendet immer noch dieselbe.

    – abhithakur88

    28. Mai 2015 um 5:21 Uhr

Verwenden Sie den OpenSSL RSA Schlussel mit Net
jww

Ich verwende openssl 0.9.6g und habe ein öffentliches/privates Schlüsselpaar mit RSA_generate_key() erstellt. Es gibt mir Schlüssel wie:

-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

Ich denke, wonach ich suche, ist “wie man einen öffentlichen RSA-Schlüssel vom pkcs # 1- in das x509-Format konvertiert.

Ja, .Net kann einige ASN.1/DER-codierte Schlüssel und einige PEM-codierte Schlüssel verbrauchen. Der Unterschied besteht in der PKCS-Codierung im Vergleich zur traditionellen Codierung (OpenSSL nennt sie „traditionell“). Die traditionelle Kodierung ist die SubjectPublicKeyInfo und es enthält die OID und den öffentlichen Schlüssel.

Sie suchen also entweder nach einer ASN.1/DER-Codierung oder einer PEM-Codierung, die schreibt SubjectPublicKeyInfound nicht nur der öffentliche Schlüssel.


Ich habe ein anderes Modul in .NET, das aufgrund seines Formats eine Ausnahme auslöst, wenn es in diesem Schlüssel übergeben wird. Es hat ein Format wie:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

Verwenden Sie in diesem Fall PEM_write_bio_PUBKEY eher, als PEM_write_bio_RSAPublicKey.

PEM_write_bio_PUBKEY schreibt die SubjectPublicKeyInfo; während PEM_write_bio_RSAPublicKey schreibt nur den öffentlichen Schlüssel.

Sie benötigen eine EVP_PKEYalso verwenden EVP_PKEY_set1_RSA um es umzuwandeln.


Das ist ein PKCS Geben Sie OpenSSL ein. Es ist nur der öffentliche Schlüssel. Du würdest verwenden PEM_write_RSAPublicKey um es zu schreiben:

-----BEGIN RSA PUBLIC KEY-----

Und das ist ein Traditionell Geben Sie OpenSSL ein. Es ist das SubjectPublicKeyInfound es enthält eine OID für den Algorithmus (rsaEncryption) und den öffentlichen Schlüssel. Du würdest verwenden PEM_write_bio_PUBKEY um es zu schreiben:

-----BEGIN PUBLIC KEY-----

Anstatt den Schlüssel mit zu speichern PEM_write_RSAPublicKeysollten Sie die ausschreiben SubjectPublicKeyInfo Struktur im ASN.1/DER-Format mit i2d_RSA_PUBKEY_bio; oder schreiben Sie es im PEM-Format mit aus PEM_write_bio_PUBKEY.

Das folgende Programm erstellt ein RSA-Schlüsselpaar und schreibt dann den öffentlichen Schlüssel in allen Formaten aus. Achten Sie darauf, auch den privaten Schlüssel zu speichern.

(Und ich bin froh, dass Sie das C++-Tag haben. unique_ptr macht diese Übung so viel einfacher).

#include <memory>
using std::unique_ptr;

#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/x509.h>

#include <cassert>
#define ASSERT assert

using BN_ptr = std::unique_ptr<BIGNUM, decltype(&::BN_free)>;
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
using EVP_KEY_ptr = std::unique_ptr<EVP_PKEY, decltype(&::EVP_PKEY_free)>;
using BIO_FILE_ptr = std::unique_ptr<BIO, decltype(&::BIO_free)>;

int main(int argc, char* argv[])
{
    int rc;

    RSA_ptr rsa(RSA_new(), ::RSA_free);
    BN_ptr bn(BN_new(), ::BN_free);

    BIO_FILE_ptr pem1(BIO_new_file("rsa-public-1.pem", "w"), ::BIO_free);
    BIO_FILE_ptr pem2(BIO_new_file("rsa-public-2.pem", "w"), ::BIO_free);
    BIO_FILE_ptr der1(BIO_new_file("rsa-public-1.der", "w"), ::BIO_free);
    BIO_FILE_ptr der2(BIO_new_file("rsa-public-2.der", "w"), ::BIO_free);

    rc = BN_set_word(bn.get(), RSA_F4);
    ASSERT(rc == 1);

    // Generate key
    rc = RSA_generate_key_ex(rsa.get(), 2048, bn.get(), NULL);
    ASSERT(rc == 1);

    // Convert RSA key to PKEY
    EVP_KEY_ptr pkey(EVP_PKEY_new(), ::EVP_PKEY_free);
    rc = EVP_PKEY_set1_RSA(pkey.get(), rsa.get());
    ASSERT(rc == 1);

    //////////

    // Write just the public key in ASN.1/DER
    // Load with d2i_RSAPublicKey_bio
    rc = i2d_RSAPublicKey_bio(der1.get(), rsa.get());
    ASSERT(rc == 1);

    // Write just the public key in PEM
    // Load with PEM_read_bio_RSAPublicKey
    rc = PEM_write_bio_RSAPublicKey(pem1.get(), rsa.get());
    ASSERT(rc == 1);

    // Write SubjectPublicKeyInfo with OID and public key in ASN.1/DER
    // Load with d2i_RSA_PUBKEY_bio
    rc = i2d_RSA_PUBKEY_bio(der2.get(), rsa.get());
    ASSERT(rc == 1);

    // Write SubjectPublicKeyInfo with OID and public key in PEM
    // Load with PEM_read_bio_PUBKEY
    rc = PEM_write_bio_PUBKEY(pem2.get(), pkey.get());
    ASSERT(rc == 1);

    return 0;
}

Die set1 in EVP_PKEY_set1_RSA erhöht die Referenzanzahl, sodass Sie bei einem Double Free keinen Segfault erhalten.

Nach Ausführung des Programms erhalten Sie die erwartete PEM und ASN.1/DER:

$ cat rsa-public-1.pem 
-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEA0cgFv6wEcqoOhPtHdVmX4YFlCwodnSqooeCxFF1XadTS4sZkVJTC
kszHmRqXiXL2NmqnuDQsq6nLd+sNoU5yJJ+W1hwo7UToCyJ/81tS4n6mXvF8oilP
8YudD5QnBdW9LhqttBIN4Gk+Cxun+HG1rSJLGP9yiPPFd7DPiFz0Gd+juyWznWnP
gapDIWEKqANKma3j6b9eopBDWB0XAgU0HQ71MSNbcsPvDd23Ftx0re/7jG53V7Bn
eBy7fQsPmxcn4c74Lz4CvhOr7VdQpeBzNeG2CtkefKWyTk7Vu4FZnAgNd/202XAr
c6GmEQqD2M2zXH/nVZg5oLznECDVQ1x/pwIDAQAB
-----END RSA PUBLIC KEY-----

$ cat rsa-public-2.pem 
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0cgFv6wEcqoOhPtHdVmX
4YFlCwodnSqooeCxFF1XadTS4sZkVJTCkszHmRqXiXL2NmqnuDQsq6nLd+sNoU5y
JJ+W1hwo7UToCyJ/81tS4n6mXvF8oilP8YudD5QnBdW9LhqttBIN4Gk+Cxun+HG1
rSJLGP9yiPPFd7DPiFz0Gd+juyWznWnPgapDIWEKqANKma3j6b9eopBDWB0XAgU0
HQ71MSNbcsPvDd23Ftx0re/7jG53V7BneBy7fQsPmxcn4c74Lz4CvhOr7VdQpeBz
NeG2CtkefKWyTk7Vu4FZnAgNd/202XArc6GmEQqD2M2zXH/nVZg5oLznECDVQ1x/
pwIDAQAB
-----END PUBLIC KEY-----

$ dumpasn1 rsa-public-1.der 
  0 266: SEQUENCE {
  4 257:   INTEGER
       :     00 D1 C8 05 BF AC 04 72 AA 0E 84 FB 47 75 59 97
       :     E1 81 65 0B 0A 1D 9D 2A A8 A1 E0 B1 14 5D 57 69
       :     D4 D2 E2 C6 64 54 94 C2 92 CC C7 99 1A 97 89 72
       :     F6 36 6A A7 B8 34 2C AB A9 CB 77 EB 0D A1 4E 72
       :     24 9F 96 D6 1C 28 ED 44 E8 0B 22 7F F3 5B 52 E2
       :     7E A6 5E F1 7C A2 29 4F F1 8B 9D 0F 94 27 05 D5
       :     BD 2E 1A AD B4 12 0D E0 69 3E 0B 1B A7 F8 71 B5
       :     AD 22 4B 18 FF 72 88 F3 C5 77 B0 CF 88 5C F4 19
       :             [ Another 129 bytes skipped ]
265   3:   INTEGER 65537
       :   }

0 warnings, 0 errors.

$ dumpasn1 rsa-public-2.der 
  0 290: SEQUENCE {
  4  13:   SEQUENCE {
  6   9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
 17   0:     NULL
       :     }
 19 271:   BIT STRING, encapsulates {
 24 266:     SEQUENCE {
 28 257:       INTEGER
       :         00 D1 C8 05 BF AC 04 72 AA 0E 84 FB 47 75 59 97
       :         E1 81 65 0B 0A 1D 9D 2A A8 A1 E0 B1 14 5D 57 69
       :         D4 D2 E2 C6 64 54 94 C2 92 CC C7 99 1A 97 89 72
       :         F6 36 6A A7 B8 34 2C AB A9 CB 77 EB 0D A1 4E 72
       :         24 9F 96 D6 1C 28 ED 44 E8 0B 22 7F F3 5B 52 E2
       :         7E A6 5E F1 7C A2 29 4F F1 8B 9D 0F 94 27 05 D5
       :         BD 2E 1A AD B4 12 0D E0 69 3E 0B 1B A7 F8 71 B5
       :         AD 22 4B 18 FF 72 88 F3 C5 77 B0 CF 88 5C F4 19
       :                 [ Another 129 bytes skipped ]
289   3:       INTEGER 65537
       :       }
       :     }
       :   }

0 warnings, 0 errors.

Verwandte Informationen finden Sie unter So generieren Sie einen privaten RSA-Schlüssel mit openssl?. Es zeigt Ihnen, wie Sie einen öffentlichen und privaten RSA-Schlüssel in einer Reihe von Formaten schreiben.

  • @abhithakur88 – ja, der Unterschied ist schmerzlich offensichtlich, wenn man es sich ansieht rsa-public-1.der und rsa-public-2.der. Die Details gehen bei der PEM-Kodierung verloren.

    – jww

    28. Mai 2015 um 20:34 Uhr

923710cookie-checkVerwenden Sie den OpenSSL-RSA-Schlüssel mit .Net

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy