namespace Kit.Helpers.Rsa
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading.Tasks;

    public class DigitalSignature
    {
        private string _publicKey;
        private string _privateKey;
        private int _dwKeySize;

        public string PublicKey { get { return _publicKey; } }
        public string PrivateKey { get { return _privateKey; } }

        public DigitalSignature(int dwKeySize)
        {
            _dwKeySize = dwKeySize;
        }

        public void AssignKey(string publicKey, string privateKey)
        {
            _publicKey = publicKey;
            _privateKey = privateKey;
        }

        public void AssignNewKey()
        {
            using (var rsa = new RSACryptoServiceProvider(_dwKeySize))
            {
                rsa.PersistKeyInCsp = false;
                _publicKey = rsa.ToXmlString(false);
                _privateKey = rsa.ToXmlString(true);
            }
        }
        public byte[] SignData(string data)
        {
            return SignData(Encoding.UTF8.GetBytes(data));
        }

        public byte[] SignData(byte[] data)
        {
            using (var rsa = new RSACryptoServiceProvider(_dwKeySize))
            {
                byte[] hash;
                using (SHA256 sha256 = SHA256.Create())
                {
                    hash = sha256.ComputeHash(data);
                }

                rsa.PersistKeyInCsp = false;
                rsa.FromXmlString(_privateKey);

                var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
                rsaFormatter.SetHashAlgorithm("SHA256");
                return rsaFormatter.CreateSignature(hash);
            }
        }

        public bool VerifySignature(string data, byte[] signature)
        {

            return VerifySignature(Encoding.UTF8.GetBytes(data), signature);
        }

        public bool VerifySignature(byte[] data, byte[] signature)
        {
            using (var rsa = new RSACryptoServiceProvider(_dwKeySize))
            {
                byte[] hash;
                using (SHA256 sha256 = SHA256.Create())
                {
                    hash = sha256.ComputeHash(data);
                }

                rsa.FromXmlString(_publicKey);
                var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                rsaDeformatter.SetHashAlgorithm("SHA256");
                return rsaDeformatter.VerifySignature(hash, signature);
            }
        }

    }
}
