RSA,JAVA私密金鑰加密,C#公開金鑰解密

來源:互聯網
上載者:User

標籤:cat   etc   static   img   decrypt   padding   擷取   stat   ret   

做這個東西在坑裡爬了3天才爬出來,記錄下供園友參考。C#程式員一枚,項目需要和Java做資料互動,對方甩了段密文和一個CER認證給我,然後我要對其密文進行解密。 RSA 非對稱式加密,對方用私密金鑰加密,我用公開金鑰解密。關於認證的一點說明:認證類型有兩種 .pfx 和 .cer ,其中 .pfx 認證既包含公開金鑰也包含私密金鑰, 而 .cer 認證只包含公開金鑰。

C#預設RSA只支援公開金鑰加密,私密金鑰解密。而現在的需求正好相反,因此想要直接用C#內建加密類肯定是行不通的。而且C#和Java的RSA加密並不互連。經過多方資料尋找,採用第三方類庫 BouncyCastle 實現了當前需求。具體來看代碼,這裡貼出主要程式碼片段:

 

1. 從cer認證中讀取公開金鑰。C#中的公開金鑰格式是xml格式的字串,與java中的公開金鑰格式是不一樣的。

/// <summary>/// 從認證中擷取公開金鑰/// </summary>/// <param name="cerPath"></param>/// <returns></returns>private string GetPublicKeyFromCer(string cerPath){     X509Certificate2 pubcrt = new X509Certificate2(cerPath);     RSACryptoServiceProvider pubkey = (RSACryptoServiceProvider)pubcrt.PublicKey.Key;     return pubkey.ToXmlString(false);}

 

2. 將C#格式公開金鑰轉換成Java格式公開金鑰

/// <summary>/// 將C#格式公開金鑰轉成Java格式公開金鑰/// </summary>/// <param name="publicKey"></param>/// <returns></returns>public static RsaKeyParameters RSAPublicKeyDotNet2Java(string publicKey){     XmlDocument doc = new XmlDocument();     doc.LoadXml(publicKey);     BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));     BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));     RsaKeyParameters pub = new RsaKeyParameters(false, m, p);     return pub;}

 

3. 公開金鑰解密。因為對方給的密文是經過base64編碼的,所以要先解碼。而且加密填充模式要設定成和java那邊的一致,我這裡設定的是 "RSA/ECB/PKCS1Padding"。

/// <summary>/// 公開金鑰解密/// </summary>/// <param name="xmlPublicKey">C#格式公開金鑰</param>/// <param name="strEncryptString">密文</param>/// <returns></returns>public static string RSADecryptByPublicKey(string xmlPublicKey, string strEncryptString){      //得到公開金鑰      RsaKeyParameters keyParams = RSAPublicKeyDotNet2Java(xmlPublicKey);      //參數與Java中加密解密的參數一致      IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");        //第一個參數 true-加密,false-解密;第二個參數表示密鑰      c.Init(false, keyParams);      //對密文進行base64解碼      byte[] dataFromEncrypt = Convert.FromBase64String(strEncryptString);      //解密      byte[] outBytes = c.DoFinal(dataFromEncrypt);      //明文      string clearText = Encoding.Default.GetString(outBytes);      return clearText;}

 

以上代碼都依賴於 BouncyCastle 使用前記得先添加引用。為什麼這樣一個問題在坑裡呆了3天呢?原因是Java那邊返給我的密文格式是錯誤的,導致我怎麼也解不出來。當時那個急的,還以為Java和C#實現不了互連加解密呢!最後這個問題還是我自己找出來的,丟了張給他們

 

 

就是這個原因,導致我加了兩天班.... 當你解密時遇到 Unknown block type 錯誤時,很大可能性就是編碼的問題,即密文的格式不正確。

 

RSA,JAVA私密金鑰加密,C#公開金鑰解密

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.