2016-03-04 91 views
2

我生成使用OpenSSL RSA私鑰&公鑰發送公鑰到HTML頁面進行加密的用戶名密碼&(與JSEncrypt)。該加密的內容發送到服務器使用私有key.This解密是我的解密功能:如何在.NET中解密RSA內容?

 public string RsaDecrypt(string xmlPrivateKey, string mStrDecryptString) 
     { 
      string str2; 
      try 
      { 
       RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); 
       provider.FromXmlString(xmlPrivateKey); 
       byte[] rgb = Convert.FromBase64String(mStrDecryptString); 
       byte[] buffer2 = provider.Decrypt(rgb, false); 
       str2 = new UnicodeEncoding().GetString(buffer2); 
      } 
      catch (Exception exception) 
      { 
       throw exception; 
      } 
      return str2; 
     } 

的xmlPrivateKey值爲:

MIICWwIBAAKBgQCt8y+vx9Y3Iik9l/8r6x+wjcrgPskbjVpt7fSJqtpCA/XaYl/3O2uvrRUPzyqr1wA+ejsdhdm285nYSbSaHTPem1+N/JHynp+cLQiBV6a8PayOvtrSBaHLZDDhgvntk/BLeplU406kiMltnVDko33H+Y3yaNuY2TNDEMe5Z8OlUQIDAQABAoGAdYIChMyKeVQqZ+F2D0UWcz5V/oZrdKFYpUpKF3XDWzUxsAUkru8FH/fccoGQYeUr1QjdRmRVXrHRC7s+tZ1km68oiUFD6sbCYyPQy0Se95050FncM3lEndGUJTiTelVqAYh+DPVnRURcfgA+HSvWek1/YnOZ8UNZJ36jiogSKcECQQDbRfn/UODXud7MKO7zfYOLvPhtFMgtA0Ac5w6tTJ/llZs0QtjMKCNHF9bGRxKdFvKTMA1DGBNN0chdWAc7UET/AkEAyxXUJAk1+46fRhzTH4uXRX7SEMCwEjY79DHqE23pPx8Q8VC3j2aPETQerT4EHNzaMBg6hneJE2p7xB5Rm/SFrwJAIWasaT7psRLIJHNLyt1gr2WOthcHUwv+tShhLPbSGIfMh45zNc4baZXxCm0DIdjABLm6G3FMZ3tAOS/Ski9tAwJAMYWQJn1sgXwk0KcEwIN8jsC/HsCt7rL06bYmOzipEPBVZFLnf/tlVa+c72fY/uTH+8RcuR96+JYVuhwekGYPFwJAQXbsOkyVTvZGcqRk9+SF7AUsGcHYPrImH6iafYEBsVCOrMJfjEai0zmd/9A1j+NHFq31KPAQGV0zHmV2NXscDg== 

的mStrDecryptString是:

fW9H+/Nz/yp6my/EwY0I+KP1CX/QPY8TL3bFDvfJYJDJ50LHEPfiR/RGhHl9rvViXOgD4IiXYF2/KbNPQNmno+Bioi3r8Xc5+PVNyFDJy+X4/YjX4O830g9vAhyRJ1RKbJOmJYWT4sdP0jfxwaRL2+FAl6yIsrcsH/7bRZvjDTU= 

在服務器端解密時,錯誤爲:第1行中的語法無效

我該怎麼做才能做對?

+1

'xmlPrivateKey'不是一個XML字符串,所以你不能使用''provider.FromXmlString''。 –

+0

您最好展示加密代碼。 –

回答

2

的RSA格式由OpenSSL的產生是與.NET不同,你應該轉換,因此它可以通過RSACryptoServiceProvider識別OpenSSL的RSA xmlPrivateKeyXML格式

 private static RSACryptoServiceProvider DecodeRsaPrivateKey(string priKey) 
     { 
      var privkey = Convert.FromBase64String(priKey); 
      byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; 

      // --------- Set up stream to decode the asn.1 encoded RSA private key ------ 
      var mem = new MemoryStream(privkey); 
      var binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading 
      try 
      { 
       var 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; 
       var bt = binr.ReadByte(); 
       if (bt != 0x00) 
        return null; 

       //------ all private key components are Integer sequences ---- 
       var 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 ----- 
       var rsa = new RSACryptoServiceProvider(); 
       var rsAparams = new RSAParameters 
       { 
        Modulus = MODULUS, 
        Exponent = E, 
        D = D, 
        P = P, 
        Q = Q, 
        DP = DP, 
        DQ = DQ, 
        InverseQ = IQ 
       }; 
       rsa.ImportParameters(rsAparams); 
       return rsa; 
      } 
      catch (Exception e) 
      { 
       LogHelper.Logger.Error("DecodeRsaPrivateKey failed", e); 
       return null; 
      } 
      finally 
      { 
       binr.Close(); 
      } 
     } 



     private static int GetIntegerSize(BinaryReader binary) 
     { 
      byte binaryReadByte = 0; 
      var count = 0; 
      binaryReadByte = binary.ReadByte(); 
      if (binaryReadByte != 0x02)  //expect integer 
       return 0; 
      binaryReadByte = binary.ReadByte(); 
      if (binaryReadByte == 0x81) 
      { 
       count = binary.ReadByte(); // data size in next byte 
      } 
      else 
      { 
       if (binaryReadByte == 0x82) 
       { 
        var highbyte = binary.ReadByte(); 
        var lowbyte = binary.ReadByte(); 
        byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; 
        count = BitConverter.ToInt32(modint, 0); 
       } 
       else 
       { 
        count = binaryReadByte; // we already have the data size 
       } 
      } 
      while (binary.ReadByte() == 0x00) 
      { //remove high order zeros in data 
       count -= 1; 
      } 
      binary.BaseStream.Seek(-1, SeekOrigin.Current);  //last ReadByte wasn't a removed zero, so back up a byte 
      return count; 
     } 

所以RSACryptoServiceProvider可以解密原始上下文。