C#使用私鑰進行RSA加密

背景:接口方開發環境是Java,要求我使用私鑰對數據進行加密,他使用公鑰進行解密。

開發時遇到的問題:

1).Net平臺默認是使用公鑰進行加密,私鑰進行解密。私鑰加密需要自己實現或者使用第三方dll。

2)雙方平臺不一致,出現了我加密的數據對方不能解密,對方加密的數據我不能解密,但是自身是可以正常加密解密。


解決辦法:

1)使用第三方dll,此處使用的是C#的BouncyCastle.Crypto進行加密及解密。在官網http://www.bouncycastle.org/csharp/ 下載最新dll。

2)設置Cipher爲“RSA/ECB/PKCS1Padding”,與Java平臺統一。


這是實現的方法,方法後面是解決過程,有興趣可以看一看。如果這個代碼不能解決你的問題,建議看下後面的解決過程,裏面的鏈接也許對你有幫助。

    /// <summary>用私鑰給數據進行RSA加密
    /// 
    /// </summary>
    /// <param name="xmlPrivateKey">私鑰</param>
    /// <param name="m_strEncryptString">待加密數據</param>
    /// <returns>加密後的數據(Base64)</returns>
    public static string RSAEncryptByPrivateKey(string xmlPrivateKey, string strEncryptString) 
    {
        //加載私鑰
        RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
        privateRsa.FromXmlString(xmlPrivateKey);

        //轉換密鑰
        AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);

        IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 參數與Java中加密解密的參數一致     
        //第一個參數爲true表示加密,爲false表示解密;第二個參數表示密鑰
        c.Init(true, keyPair.Private);

        byte[] DataToEncrypt = Encoding.UTF8.GetBytes(strEncryptString);
        byte[] outBytes = c.DoFinal(DataToEncrypt);//加密
        string strBase64 = Convert.ToBase64String(outBytes);
        
        return strBase64;
    }


-------------------------------------解決過程-------------------------------------

1.確認是使用私鑰進行加密後,發現.Net沒有使用私鑰進行加密的方法。搜索後得知需要自己實現。

2.搜索實現方式,但得到的方法裏需要兩個BigInteger,由於對私鑰的xml並不瞭解,不清楚參數該用什麼值。只好放棄這種方式。不過後來查資料找到私鑰xml中各節點的含義以及加密時該用哪些節點的值。不過這是後話了。

微軟對公鑰私鑰各節點的解釋:RSAParameters 結構 https://msdn.microsoft.com/zh-cn/library/system.security.cryptography.rsaparameters%28v=vs.110%29.aspx

加密解密時該使用什麼節點:http://blog.csdn.net/a351945755/article/details/21965533

3.找到一個已經封裝好的方法,只需要把密鑰和加密數據傳進去就可以實現的方法。但是加密出來的結果本身可以解密,但是對方無法解密。對方提供的加密數據使用此方法無法解密。

此處使用的代碼:http://www.codeproject.com/Articles/38739/RSA-Private-Key-Encryption

4.在前兩步搜索資料的時候,得知BouncyCastle。看到相關介紹,於是使用其提供的dll進行加密解密操作。但是此時網上找到的都是BouncyCastle自動生成密鑰進行加密解密而不是讀取.Net的密鑰進行加密解密。

使用BouncyCastle進行加密解密的代碼是:http://blog.csdn.net/popozhu/article/details/5789382

5.查找密鑰轉換方式,找到以下資料:http://stackoverflow.com/questions/3240222/get-private-key-from-bouncycastle-x509-certificate-c-sharp

使用“CriGoT”或者“majkinetor”提供的代碼都可以進行私鑰的轉換。

6.通過第四步和第五步可以獲得完整的加密解密方法。在使用此方法進行私鑰加密後對方解密時報錯“javax.crypto.BadPaddingException: Blocktype mismatch: 0”,查找資料後得知,也許與Cipher.getInstance("RSA")中的參數有關,需要改爲“RSA/ECB/PKCS1Padding”。但對方排查後應當默認就是“RSA/ECB/PKCS1Padding”。最終在 http://www.xuebuyuan.com/301023.html 找到另一種調用的方法可以傳入“RSA/ECB/PKCS1Padding”。

至此.Net和Java之間RSA私鑰加密公鑰解密進行數據交互完成。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章