使用OpenSSL RSA密钥与.net [英] Use OpenSSL RSA key with .Net

查看:210
本文介绍了使用OpenSSL RSA密钥与.net的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的OpenSSL 0.9.6g,我已经使用RSA_generate_key创建公共/私有密钥对()。当我保存 PEM_write_bio_RSAPublicKey 的关键,它给了我钥匙这样的:

  ----- BEGIN RSA公钥-----
...
----- END RSA公钥-----
 

我在.NET中,当在这个关键,因为它的格式通过它抛出一个异常,另一个模块。它采用的格式如下:

  ----- BEGIN公钥-----
...
----- END公钥-----
 

如何把我的钥匙转换为这种格式。我使用C ++。

在.NET中,我使用openssl.net,在code是如下:

 字符串公钥= @----- BEGIN RSA公钥-----
MIGJAoGBAKGtqUVBBqcGCRYa7Sb6JVQirOX3hggWP2k7CzEtbF / soOONK510Kefm
omXBrGn2t79ES + hAcCvGSiiVZGuEb3UPiznzbiY150SME5nRC + zU0vvdX64ni0Mu
DeUlGcxM1eWSpozO71at6mxLloEMUg0oSWHfAlS5a4LVaURrJqXfAgMBAAE =
----- END RSA公钥-----;

编码ENC = Encoding.ASCII;
字符串文字=世界你好;
byte []的味精= enc.GetBytes(文本);
密码键键= CryptoKey.FromPublicKey(公钥,);
RSA RSA = key.GetRSA();
byte []的解析度= rsa.PublicEncrypt(味精,RSA.Padding.PKCS1);
 

例外进来行:

 密码键键= CryptoKey.FromPublicKey(公钥,);
 

如果我用钥匙:

  ----- BEGIN公钥-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbhcU + fhYmYLESZQAj1hKBXsNY
si0kYHNkxpP7ftxZiTFowWUVXHzQgkcYiCNnp3pt1eG6Vt0WDzyFYXqUUqugvX41
gkaIrKQw / sRiWEx49krcz7Vxr3dufL6Mg3eK7NyWDGsqwFrx / qVNqdhsHg12PGNx
IMY4UBtxin2A8pd4OwIDAQAB
----- END公钥-----
 

它工作正常。

我一直在寻找解决此问题的。我觉得我所期待的是如何RSA公钥转换PKCS#1至X509格式。

解决方案
  

我使用的OpenSSL 0.9.6g和我创建公共/私有密钥   使用RSA_generate_key()。它给我的按键,例如:

  ----- BEGIN RSA公钥-----
...
----- END RSA公钥-----
 

     

我想我在找的是如何将RSA公钥从PKCS#1至X509格式。

是啊,净能消耗一定的ASN.1 / DER EN codeD按键,以及一些PEM EN codeD按键。所不同的是PKCS编码与传统编码(OpenSSL的将其称为传统)。传统的编码是的的SubjectPublicKeyInfo 的,它包括OID和公钥。

所以,你正在寻找任何一个ASN.1 / DER编码或写入一个PEM编码的的SubjectPublicKeyInfo 的,而不仅仅是公钥。


  

我在.NET时通过它抛出一个异常另一个模块   这个关键,因为它的格式。它采用的格式如下:

  ----- BEGIN公钥-----
...
----- END公钥-----
 

在此情况下,使用 PEM_write_bio_PUBKEY ,而不是 PEM_write_bio_RSAPublicKey

PEM_write_bio_PUBKEY 写的的SubjectPublicKeyInfo 的;而 PEM_write_bio_RSAPublicKey 只写入了公开密钥。

您将需要一个 EVP_PKEY ,所以使用 EVP_PKEY_set1_RSA 来转换。


这是一个的 PKCS 键OpenSSL的。它只是公钥。你可以使用 PEM_write_RSAPublicKey 来写:

  ----- BEGIN RSA公钥-----
 

和这是一个 传统键OpenSSL的。它的的的SubjectPublicKeyInfo 的,它包括一个OID的算法( rsaEncryption )和公共密钥。你可以使用 PEM_write_bio_PUBKEY 来写:

  ----- BEGIN公钥-----
 


相反节能与 PEM_write_RSAPublicKey 的关键,你应该写出来的的SubjectPublicKeyInfo 的结构ASN.1 / DER格式 i2d_RSA_PUBKEY_bio ;或 PEM_write_bio_PUBKEY 写出来PEM格式。

下面的程序创建一个RSA密钥对,然后写出公钥中的所有格式。一定要保存私钥了。

(我很高兴你有C ++的标签。的unique_ptr 使这项工作就轻松多了)。

的#include<内存> 使用std ::的unique_ptr; #包括<的OpenSSL / bn.h> #包括<的OpenSSL / rsa.h> #包括<的OpenSSL / pem.h> #包括<的OpenSSL / bio.h> #包括<的OpenSSL / x509.h> #包括<&了cassert GT; #定义ASSERT断言 使用BN_ptr =的std ::的unique_ptr< BIGNUM,decltype(安培; :: BN_free)取代; 使用RSA_ptr =的std ::的unique_ptr< RSA,decltype(安培; :: RSA_free)取代; 使用EVP_KEY_ptr =的std ::的unique_ptr< EVP_PKEY,decltype(安培; :: EVP_PKEY_free)取代; 使用BIO_FILE_ptr =的std ::的unique_ptr< BIO,decltype(安培; :: BIO_free)取代; INT主(INT ARGC,字符* argv的[]) {     INT RC;     RSA_ptr RSA(RSA_new(),:: RSA_free);     BN_ptr亿元(BN_new(),:: BN_free);     BIO_FILE_ptr pem1(BIO_new_file(RSA-公共1.pem,W),:: BIO_free);     BIO_FILE_ptr pem2(BIO_new_file(RSA-公共2.pem,W),:: BIO_free);     BIO_FILE_ptr der1(BIO_new_file(RSA-公共1.der,W),:: BIO_free);     BIO_FILE_ptr DER2(BIO_new_file(RSA-公共2.der,W),:: BIO_free);     RC = BN_set_word(bn.get(),RSA_F4);     ASSERT(RC == 1);     //生成密钥     RC = RSA_generate_key_ex(rsa.get(),2048,bn.get(),NULL);     ASSERT(RC == 1);     //转换RSA密钥,以PKEY     EVP_KEY_ptr p键(EVP_PKEY_new(),:: EVP_PKEY_free);     RC = EVP_PKEY_set1_RSA(pkey.get(),rsa.get());     ASSERT(RC == 1);     //////////     //写只是ASN.1 / DER公钥     RC = i2d_RSAPublicKey_bio(der1.get(),rsa.get());     ASSERT(RC == 1);     //写就在PEM公共密钥     RC = PEM_write_bio_RSAPublicKey(pem1.get(),rsa.get());     ASSERT(RC == 1);     //写SubjectPublicKeyInfo进行与OID和ASN.1 / DER公钥     RC = i2d_RSA_PUBKEY_bio(der2.get(),rsa.get());     ASSERT(RC == 1);     //写SubjectPublicKeyInfo进行与OID和PEM公共密钥     RC = PEM_write_bio_PUBKEY(pem2.get(),pkey.get());     ASSERT(RC == 1);     返回0; }

设置1 EVP_PKEY_set1_RSA 碰引用计数,这样你就不会得到一个段错误的双自由

执行程序后,你会得到预期的PEM和ASN.1 / DER:

$猫RSA公开,1.pem ----- BEGIN RSA公钥----- MIIBCgKCAQEA0cgFv6wEcqoOhPtHdVmX4YFlCwodnSqooeCxFF1XadTS4sZkVJTC kszHmRqXiXL2NmqnuDQsq6nLd + sNoU5yJJ + W1hwo7UToCyJ / 81tS4n6mXvF8oilP 8YudD5QnBdW9LhqttBIN4Gk + Cxun + HG1rSJLGP9yiPPFd7DPiFz0Gd + juyWznWnP gapDIWEKqANKma3j6b9eopBDWB0XAgU0HQ71MSNbcsPvDd23Ftx0re / 7jG53V7Bn eBy7fQsPmxcn4c74Lz4CvhOr7VdQpeBzNeG2CtkefKWyTk7Vu4FZnAgNd / 202XAr c6GmEQqD2M2zXH / nVZg5oLznECDVQ1x / pwIDAQAB ----- END RSA公钥----- $猫RSA-公共2.pem ----- BEGIN公钥----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0cgFv6wEcqoOhPtHdVmX 4YFlCwodnSqooeCxFF1XadTS4sZkVJTCkszHmRqXiXL2NmqnuDQsq6nLd + sNoU5y JJ + W1hwo7UToCyJ / 81tS4n6mXvF8oilP8YudD5QnBdW9LhqttBIN4Gk + Cxun + HG1 rSJLGP9yiPPFd7DPiFz0Gd + juyWznWnPgapDIWEKqANKma3j6b9eopBDWB0XAgU0 HQ71MSNbcsPvDd23Ftx0re / 7jG53V7BneBy7fQsPmxcn4c74Lz4CvhOr7VdQpeBz NeG2CtkefKWyTk7Vu4FZnAgNd / 202XArc6GmEQqD2M2zXH / nVZg5oLznECDVQ1x / pwIDAQAB ----- END公钥----- $ dumpasn1 RSA-公共1.der   0 266:序列{   4 257:INTEGER        :00 D1 C8 05 BF交流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 6 64 54 94 92 C2 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        :公元22 4B 18 FF 72 88 F3 C5 77 B0 CF 88 5C F4 19        :【另一个129字节跳过] 265 3:INTEGER 65537        :} 0警告,0个错误。 $ dumpasn1 RSA-公共2.der   0 290:序列{   4 13:序列{   6月9日:对象标识符rsaEncryption(1 2 840 113549 111)  17 0:NULL        :}  19 271:BIT STRING,囊粒{  24 266:序列{  28 257:INTEGER        :00 D1 C8 05 BF交流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 6 64 54 94 92 C2 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        :公元22 4B 18 FF 72 88 F3 C5 77 B0 CF 88 5C F4 19        :【另一个129字节跳过] 289 3:INTEGER 65537        :}        :}        :} 0警告,0个错误。


相关信息,请参阅<一href="https://stackoverflow.com/questions/5927164/how-to-generate-rsa-private-key-using-openssl/30493975#30493975">How使用OpenSSL生成RSA私钥?。它显示了你怎么写了一些格式的RSA公钥和私钥。

I am using openssl 0.9.6g and I have created public/private keypair using RSA_generate_key(). When I save the key with PEM_write_bio_RSAPublicKey, it gives me keys like:

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

I have another module in .NET which throws an exception when passed in this key due to its format. It takes format like:

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

How to convert my keys to this format. I am using C++.

In .NET, I am using openssl.net, the code is as follows:

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);

The exception comes in line:

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

If I use the key:

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

It works fine.

I was looking around for this issue. I think what I am looking for is "how to convert rsa public key from pkcs#1 to x509 format.

解决方案

I am using openssl 0.9.6g and I have created public/private keypair using RSA_generate_key(). It gives me keys like:

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

I think what I am looking for is "how to convert rsa public key from pkcs#1 to x509 format.

Yeah, .Net can consume some ASN.1/DER encoded keys, and some PEM encoded keys. The difference is PKCS encoding versus Traditional encoding (OpenSSL calls it "Traditional"). The traditional encoding is the SubjectPublicKeyInfo and it includes the OID and the public key.

So you are looking for either an ASN.1/DER encoding or a PEM encoding that writes SubjectPublicKeyInfo, and not just the public key.


I have another module in .NET which throws an exception when passed in this key due to its format. It takes format like:

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

In this case, use PEM_write_bio_PUBKEY rather than PEM_write_bio_RSAPublicKey.

PEM_write_bio_PUBKEY writes the SubjectPublicKeyInfo; while PEM_write_bio_RSAPublicKey writes only the public key.

You will need an EVP_PKEY, so use EVP_PKEY_set1_RSA to convert it.


This is a PKCS key in OpenSSL. Its just the public key. You would use PEM_write_RSAPublicKey to write it:

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

And this is a Traditional key in OpenSSL. Its the SubjectPublicKeyInfo, and it includes an OID for the algorithm (rsaEncryption) and the public key. You would use PEM_write_bio_PUBKEY to write it:

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


Instead of saving the key with PEM_write_RSAPublicKey, you should write out the SubjectPublicKeyInfo structure in ASN.1/DER format with i2d_RSA_PUBKEY_bio; or write it out in PEM format with PEM_write_bio_PUBKEY.

The program below creates a RSA key pair, and then writes out the public key in all the formats. Be sure to save the private key, too.

(And I'm glad you have the C++ tag. unique_ptr makes this exercise so much easier).

#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
    rc = i2d_RSAPublicKey_bio(der1.get(), rsa.get());
    ASSERT(rc == 1);

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

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

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

    return 0;
}

The set1 in EVP_PKEY_set1_RSA bumps the reference count, so you don't get a segfault on a double free.

After executing the program, you get the expected PEM and 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.


Related, see How to generate RSA private key using openssl?. It shows you how to write a RSA public and private key in a number of formats.

这篇关于使用OpenSSL RSA密钥与.net的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆