.net core linux下的RSA解密

基礎(chǔ)部分參考https://blog.csdn.net/sD7O95O/article/details/78412745?locationNum=8&fps=1

但是由于這里的RSA加密/解密主要是針對(duì)于由OpenSSL生成的公鑰/私鑰字符串。ssh-keygen -t rsa 命令生成的公鑰私鑰是不行的。

如果使用帶簽名的加密方式字符串就會(huì)出現(xiàn)

rsa.ImportParameters(rsaParameters);

無(wú)法解析到相應(yīng)byte的問(wèn)題

如果使用

 rsa = new RSACryptoServiceProvider(keySize, rsaParams);

可以解析帶簽名的RSA加密字符串,但是在linux下會(huì)出現(xiàn)錯(cuò)誤

解析出錯(cuò):System.PlatformNotSupportedException: 'CspParameters' requires Windows Cryptographic API (CAPI), which is not available on this platform.

有依賴(lài)包依賴(lài)于windows環(huán)境下的dll,linux下無(wú)法解析。

解決方案:
將參考部分的RSAHelper中rsa.ImportParameters(rsaParameters);獲取公鑰私鑰byte的解析方案用下面解析方式替換掉

   /// <summary>
        /// 用PEM格式密鑰對(duì)創(chuàng)建RSA,支持PKCS#1、PKCS#8格式的PEM
        /// </summary>
        public static System.Security.Cryptography.RSA FromPEM(string pem)
        {
            var rsa = System.Security.Cryptography.RSA.Create();

            var param = new RSAParameters();

            var base64 = _PEMCode.Replace(pem, "");
            var data = RSA_Unit.Base64DecodeBytes(base64);
            if (data == null)
            {
                throw new Exception("PEM內(nèi)容無(wú)效");
            }
            var idx = 0;

            //讀取長(zhǎng)度
            Func<byte, int> readLen = (first) => {
                if (data[idx] == first)
                {
                    idx++;
                    if (data[idx] == 0x81)
                    {
                        idx++;
                        return data[idx++];
                    }
                    else if (data[idx] == 0x82)
                    {
                        idx++;
                        return (((int)data[idx++]) << 8) + data[idx++];
                    }
                    else if (data[idx] < 0x80)
                    {
                        return data[idx++];
                    }
                }
                throw new Exception("PEM未能提取到數(shù)據(jù)");
            };
            //讀取塊數(shù)據(jù)
            Func<byte[]> readBlock = () => {
                var len = readLen(0x02);
                if (data[idx] == 0x00)
                {
                    idx++;
                    len--;
                }
                var val = data.sub(idx, len);
                idx += len;
                return val;
            };
            //比較data從idx位置開(kāi)始是否是byts內(nèi)容
            Func<byte[], bool> eq = (byts) => {
                for (var i = 0; i < byts.Length; i++, idx++)
                {
                    if (idx >= data.Length)
                    {
                        return false;
                    }
                    if (byts[i] != data[idx])
                    {
                        return false;
                    }
                }
                return true;
            };




            if (pem.Contains("PUBLIC KEY"))
            {
                /****使用公鑰****/
                //讀取數(shù)據(jù)總長(zhǎng)度
                readLen(0x30);
                if (!eq(_SeqOID))
                {
                    throw new Exception("PEM未知格式");
                }
                //讀取1長(zhǎng)度
                readLen(0x03);
                idx++;//跳過(guò)0x00
                      //讀取2長(zhǎng)度
                readLen(0x30);

                //Modulus
                param.Modulus = readBlock();

                //Exponent
                param.Exponent = readBlock();
            }
            else if (pem.Contains("PRIVATE KEY"))
            {
                /****使用私鑰****/
                //讀取數(shù)據(jù)總長(zhǎng)度
                readLen(0x30);

                //讀取版本號(hào)
                if (!eq(_Ver))
                {
                    throw new Exception("PEM未知版本");
                }

                //檢測(cè)PKCS8
                var idx2 = idx;
                if (eq(_SeqOID))
                {
                    //讀取1長(zhǎng)度
                    readLen(0x04);
                    //讀取2長(zhǎng)度
                    readLen(0x30);

                    //讀取版本號(hào)
                    if (!eq(_Ver))
                    {
                        throw new Exception("PEM版本無(wú)效");
                    }
                }
                else
                {
                    idx = idx2;
                }

                //讀取數(shù)據(jù)
                param.Modulus = readBlock();
                param.Exponent = readBlock();
                param.D = readBlock();
                param.P = readBlock();
                param.Q = readBlock();
                param.DP = readBlock();
                param.DQ = readBlock();
                param.InverseQ = readBlock();
            }
            else
            {
                throw new Exception("pem需要BEGIN END標(biāo)頭");
            }

            rsa.ImportParameters(param);
            return rsa;
        }

依賴(lài)方法

 /// <summary>
    /// 封裝的一些通用方法
    /// </summary>
    public class RSA_Unit
    {
        static public string Base64EncodeBytes(byte[] byts)
        {
            return Convert.ToBase64String(byts);
        }
        static public byte[] Base64DecodeBytes(string str)
        {
            try
            {
                return Convert.FromBase64String(str);
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// 把字符串按每行多少個(gè)字?jǐn)嘈?        /// </summary>
        static public string TextBreak(string text, int line)
        {
            var idx = 0;
            var len = text.Length;
            var str = new StringBuilder();
            while (idx < len)
            {
                if (idx > 0)
                {
                    str.Append('\n');
                }
                if (idx + line >= len)
                {
                    str.Append(text.Substring(idx));
                }
                else
                {
                    str.Append(text.Substring(idx, line));
                }
                idx += line;
            }
            return str.ToString();
        }
    }

    static public class Extensions
    {
        /// <summary>
        /// 從數(shù)組start開(kāi)始到指定長(zhǎng)度復(fù)制一份
        /// </summary>
        static public T[] sub<T>(this T[] arr, int start, int count)
        {
            T[] val = new T[count];
            for (var i = 0; i < count; i++)
            {
                val[i] = arr[start + i];
            }
            return val;
        }
        static public void writeAll(this Stream stream, byte[] byts)
        {
            stream.Write(byts, 0, byts.Length);
        }
    }

這樣經(jīng)過(guò)測(cè)試上線可以在linux下解析出帶簽名的RSA加密字符串

       var rsa = new RSAHelper(RSAType.RSA, Encoding.UTF8, rsaprivate);
                Console.WriteLine("原始字符串:" + connection);
                //加密
                // string enStr = rsa.Encrypt(str);

                // Console.WriteLine("加密字符串:" + enStr);

                //解密
                // string deStr = rsa.DecodeOrNull(connection);
                var deStr = rsa.Decrypt(connection);

                Console.WriteLine("解密字符串:" + deStr);
                string finalconnection = MySqlHelper(deStr);

被坑了一下午,在同事的幫助下解決這個(gè)問(wèn)題,希望能幫助到那些還再坑里的同學(xué)吧O(∩_∩)O哈哈~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容