求C#实现JAVA中SHA1withECDSA数字签名

JAVA代码如下:

//密钥
String key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

byte[] keyByte = Base64.decodeBase64(key);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyByte);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

Signature signature = Signature.getInstance("SHA1withECDSA");
signature.initSign(privateKey);
signature.update("1122334455667788".getBytes());
byte[] res = signature.sign();
System.out.println("签名:" + Base64.encodeBase64String(res));

求C#版本实现!

已解决,谢谢各位!
AsymmetricKeyParameter priKey = GetPrivateKeyParameter(key);
byte[] byteData = System.Text.Encoding.UTF8.GetBytes(data);

        ISigner normalSig = SignerUtilities.GetSigner("SHA1withECDSA");
        normalSig.Init(true, priKey);
        normalSig.BlockUpdate(byteData, 0, byteData.Length);
        byte[] normalResult = normalSig.GenerateSignature(); //签名结果
        return Convert.ToBase64String(normalResult);

采纳一下,谢谢
源码给你

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
 
namespace Common
{
    public  class SHA1withRSA
    {
 
        /// <summary>
        /// SHA1withRSA签名
        /// </summary>
        /// <param name="content">待签名字符串</param>
        /// <param name="privateKey">私钥</param>
        /// <param name="input_charset">编码格式</param>
        /// <returns>签名后字符串</returns>
        public static string Sign(string content, string privateKey, string input_charset)
        {
            byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);
            RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey);
            using (var sh = SHA1.Create())
            {
                byte[] signData = rsa.SignData(Data, sh);
                return Convert.ToBase64String(signData);
            }
 
        }
        /// <summary>
        /// pem格式公钥验签
        /// </summary>
        /// <param name="content">待验签字符串</param>
        /// <param name="signedString">签名</param>
        /// <param name="publicKey">公钥</param>
        /// <param name="input_charset">编码格式</param>
        /// <returns>true(通过),false(不通过)</returns>
        public static bool Verify(string content, string signedString, string publicKey, string input_charset)
        {
            bool result = false;
            byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);
            byte[] data = Convert.FromBase64String(signedString);
            RSAParameters paraPub = ConvertFromPublicKey(publicKey);
            RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider();
            rsaPub.ImportParameters(paraPub);
            using (var sh = SHA1.Create())
            {
                result = rsaPub.VerifyData(Data, sh, data);
                return result;
            }
 
        }
 
        #region 内部方法
 
        private static RSACryptoServiceProvider DecodePemPrivateKey(String pemstr)
        {
            RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(Convert.FromBase64String(pemstr));
            return rsa;
        }
 
        private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
        {
            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();
                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
            {
                return null;
            }
            finally
            {
                binr.Dispose();
            }
        }
 
        private static int GetIntegerSize(BinaryReader binr)
        {
            byte bt = 0;
            byte lowbyte = 0x00;
            byte highbyte = 0x00;
            int count = 0;
            bt = binr.ReadByte();
            if (bt != 0x02) //expect integer
                return 0;
            bt = binr.ReadByte();
 
            if (bt == 0x81)
                count = binr.ReadByte();    // data size in next byte
            else
            if (bt == 0x82)
            {
                highbyte = binr.ReadByte(); // data size in next 2 bytes
                lowbyte = binr.ReadByte();
                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
                count = BitConverter.ToInt32(modint, 0);
            }
            else
            {
                count = bt; // we already have the data size
            }
 
            while (binr.ReadByte() == 0x00)
            {   //remove high order zeros in data
                count -= 1;
            }
            binr.BaseStream.Seek(-1, SeekOrigin.Current);   //last ReadByte wasn't a removed zero, so back up a byte
            return count;
        }
 
        #endregion
 
        #region 生成的Pem
        private static RSAParameters ConvertFromPublicKey(string pemFileConent)
        {
 
            if (string.IsNullOrEmpty(pemFileConent))
            {
                throw new ArgumentNullException("pemFileConent", "This arg cann't be empty.");
            }
            pemFileConent = pemFileConent.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
            byte[] keyData = Convert.FromBase64String(pemFileConent);
            bool keySize1024 = (keyData.Length == 162);
            bool keySize2048 = (keyData.Length == 294);
            if (!(keySize1024 || keySize2048))
            {
                throw new ArgumentException("pem file content is incorrect, Only support the key size is 1024 or 2048");
            }
            byte[] pemModulus = (keySize1024 ? new byte[128] : new byte[256]);
            byte[] pemPublicExponent = new byte[3];
            Array.Copy(keyData, (keySize1024 ? 29 : 33), pemModulus, 0, (keySize1024 ? 128 : 256));
            Array.Copy(keyData, (keySize1024 ? 159 : 291), pemPublicExponent, 0, 3);
            RSAParameters para = new RSAParameters();
            para.Modulus = pemModulus;
            para.Exponent = pemPublicExponent;
            return para;
        }
 
        #endregion
    }
}