2011-05-11 106 views
3

我寫一個.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

    回答

    -1

    你的私鑰,所以它可能更容易產生從密鑰自簽名證書。您可以使用System.Security.Cryptography.X509Certificates.X509Certificate(我想你應該有DER/ASN.1格式,而吳丹PEM證書)來加載證書和X509Certificate.GetPublicKey()獲得公共密鑰。

    +0

    對於遲到的反饋意見,但您的回答沒有幫助。我沒有從這個應用程序訪問私鑰,我的問題的核心是如何從PEM獲得DER或ASN.1。 – 2011-07-14 23:06:31

    2

    要加載私鑰讓我們用這個代碼:

    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

    相關問題