如何将由openSSL生成的RSA公钥加载到RSACryptoServiceProvider中?

问题描述:

我写一个.NET类读取从我们的*认证服务器的cookie。它包含UserId,一些时间戳和由openssl_sign()使用2048位RSA密钥和SHA1哈希创建的签名。如何将由openSSL生成的RSA公钥加载到RSACryptoServiceProvider中?

当前的公钥OpenSSL中的PEM格式提供的服务器和偶尔的变化上。我无法读取使用的.Net独(还)托管代码,并制定了以下程序得到它的工作重点:从公钥

  • 检查关键

    • 提取指数和模量仍然是2048位
    • 存储密钥长度,指数在资源的弹性模量,编译和部署(从模量下降,导致零,使其工作)

    的类,然后创建一个new RSACryptoServiceProvider(2048)并使用RSAParameters结构到CSP饲料公共组件。验证签名然后成功。

    我希望得到这个工作没有我创建,编译和每次部署新议会的主要变化。为了使事情变得有趣,我只想坚持托管代码(排除我发现的大多数例子)。创造AsnEncodedData(oid, data)实例,但我发现,可以匹配的唯一OID,RSA又名1.2.840.113549.1.1.1时,没有工作,只生产原始字节的东西,听起来很完美,是内部ASN.1读者。

    补充:前公钥

    ----- BEGIN PUBLIC KEY -----
    MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMW90O6C17fapbS35auKolsy7kI0FOE1
    C08y5HqgZ0rMXoocV4nHSHYBm2HVx2QSR5OLQtERgWDmxOu + vwU1GXUCAwEAAQ ==
    ----- END PUBLIC KEY-- ---

    我发现pempublic.cs似乎解决这个使用(因为它似乎)来自openSSL的源代码。我将留下这个问题,看看是否有其他解决方案。

  • +0

    任何运气有了这个?看到5个相同的问题,最接近的答案是pempublic.cs文件。仍然这个文件看起来有点乱。 – Devela 2014-01-27 06:40:25

    你的私钥,所以它可能更容易产生从密钥自签名证书。您可以使用System.Security.Cryptography.X509Certificates.X509Certificate(我想你应该有DER/ASN.1格式,而吴丹PEM证书)来加载证书和X509Certificate.GetPublicKey()获得公共密钥。

    +0

    对于迟到的反馈意见,但您的回答没有帮助。我没有从这个应用程序访问私钥,我的问题的核心是如何从PEM获得DER或ASN.1。 – 2011-07-14 23:06:31

    要加载私钥让我们用这个代码:

    private RSACryptoServiceProvider GetPrivateKey(string privateKey) 
        { 
         byte[] privkey = Convert.FromBase64String(privateKey); 
         byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; 
    
         // --------- Set up stream to decode the asn.1 encoded RSA private key ------ 
         MemoryStream mem = new MemoryStream(privkey); 
         BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading 
         byte bt = 0; 
         ushort twobytes = 0; 
         int elems = 0; 
         try 
         { 
          twobytes = binr.ReadUInt16(); 
          if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) 
           binr.ReadByte(); //advance 1 byte 
          else if (twobytes == 0x8230) 
           binr.ReadInt16(); //advance 2 bytes 
          else 
           return null; 
    
          twobytes = binr.ReadUInt16(); 
          if (twobytes != 0x0102) //version number 
           return null; 
          bt = binr.ReadByte(); 
          if (bt != 0x00) 
           return null; 
    
    
          //------ all private key components are Integer sequences ---- 
          elems = GetIntegerSize(binr); 
          MODULUS = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          E = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          D = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          P = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          Q = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          DP = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          DQ = binr.ReadBytes(elems); 
    
          elems = GetIntegerSize(binr); 
          IQ = binr.ReadBytes(elems); 
    
          // ------- create RSACryptoServiceProvider instance and initialize with public key ----- 
          CspParameters CspParameters = new CspParameters(); 
          CspParameters.Flags = CspProviderFlags.UseMachineKeyStore; 
          RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters); 
          RSAParameters RSAparams = new RSAParameters(); 
          RSAparams.Modulus = MODULUS; 
          RSAparams.Exponent = E; 
          RSAparams.D = D; 
          RSAparams.P = P; 
          RSAparams.Q = Q; 
          RSAparams.DP = DP; 
          RSAparams.DQ = DQ; 
          RSAparams.InverseQ = IQ; 
          RSA.ImportParameters(RSAparams); 
          return RSA; 
         } 
         catch (Exception ex) 
         { 
          return null; 
         } 
         finally 
         { 
          binr.Close(); 
         } 
        } 
    

    要加载公钥让我们用这个代码:

    private RSACryptoServiceProvider GetPublicKey(string publicKeyString) 
        { 
         // encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1" 
         byte[] SeqOID = {0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00} ; 
         byte[] x509key; 
         byte[] seq = new byte[15]; 
         int x509size; 
    
         x509key = Convert.FromBase64String(publicKeyString); 
         x509size = x509key.Length; 
    
         // --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------ 
         MemoryStream mem = new MemoryStream(x509key); 
         BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading 
         byte bt = 0; 
         ushort twobytes = 0; 
    
         try 
         { 
    
          twobytes = binr.ReadUInt16(); 
          if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) 
           binr.ReadByte(); //advance 1 byte 
          else if (twobytes == 0x8230) 
           binr.ReadInt16(); //advance 2 bytes 
          else 
           return null; 
    
          seq = binr.ReadBytes(15);  //read the Sequence OID 
          if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct 
           return null; 
    
          twobytes = binr.ReadUInt16(); 
          if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81) 
           binr.ReadByte(); //advance 1 byte 
          else if (twobytes == 0x8203) 
           binr.ReadInt16(); //advance 2 bytes 
          else 
           return null; 
    
          bt = binr.ReadByte(); 
          if (bt != 0x00)  //expect null byte next 
           return null; 
    
          twobytes = binr.ReadUInt16(); 
          if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) 
           binr.ReadByte(); //advance 1 byte 
          else if (twobytes == 0x8230) 
           binr.ReadInt16(); //advance 2 bytes 
          else 
           return null; 
    
          twobytes = binr.ReadUInt16(); 
          byte lowbyte = 0x00; 
          byte highbyte = 0x00; 
    
          if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81) 
           lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus 
          else if (twobytes == 0x8202) 
          { 
           highbyte = binr.ReadByte(); //advance 2 bytes 
           lowbyte = binr.ReadByte(); 
          } 
          else 
           return null; 
          byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order 
          int modsize = BitConverter.ToInt32(modint, 0); 
    
          int firstbyte = binr.PeekChar(); 
          if (firstbyte == 0x00) 
          { //if first byte (highest order) of modulus is zero, don't include it 
           binr.ReadByte(); //skip this null byte 
           modsize -= 1; //reduce modulus buffer size by 1 
          } 
    
          byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes 
    
          if (binr.ReadByte() != 0x02)   //expect an Integer for the exponent data 
           return null; 
          int expbytes = (int)binr.ReadByte();  // should only need one byte for actual exponent data (for all useful values) 
          byte[] exponent = binr.ReadBytes(expbytes); 
    
          // ------- create RSACryptoServiceProvider instance and initialize with public key ----- 
          RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); 
          RSAParameters RSAKeyInfo = new RSAParameters(); 
          RSAKeyInfo.Modulus = modulus; 
          RSAKeyInfo.Exponent = exponent; 
          RSA.ImportParameters(RSAKeyInfo); 
    
          return RSA; 
         } 
    
         finally 
         { 
          binr.Close(); 
         } 
        } 
    

    可以读取original post here获得更详细

    +0

    我如何获得整数? – th1rdey3 2016-02-10 13:48:20

    +0

    在[link](http:// langcongnghe。com/2014/11/10/tony/cach-thuc-doc-rsa-private-key-va-public-key-in-c.html) – 2016-04-17 15:52:03