﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using com.huawei.esdk.tp.professional.local;
using com.huawei.esdk.tp.professional.DataType;
using System.Security.Cryptography.X509Certificates;
using System.Numerics;
using System.Web.Services.Protocols;
using com.huawei.esdk.platform.professional.local.impl.utils;


namespace com.huawei.esdk.tp.professional.Utils
{
    public class RSA2048
    {
        PlatformKeyServiceProvider platformKey;

        private const int maxLength = 256;

        public RSA2048()
        {
            platformKey = PlatformKeyServiceProvider.Instance();
        }

        // 密钥协商从服务端获取RSA2048的密钥
        public string getPublicKey()
        {
            TPSDKResponseEx<string> result = new TPSDKResponseEx<string>();
            result = platformKey.getPublicKey();
            return result.result;
        }

        // 密钥协商的RSA2048加密，这里加密的是AES128的密钥和iv
        public string RSAEncrypt(string password, string publicKey)
        {
            byte[] keyByte = Convert.FromBase64String(publicKey);
            RSA2048Utils rsa2048 = new RSA2048Utils();
            rsa2048.key = keyByte;
            var message = Encoding.UTF8.GetBytes(password);
            var cipherbytes = rsa2048.encode(message);

            string output = Convert.ToBase64String(cipherbytes);
            return output;

        }

        /// <summary>        
        /// RSA2048加密       
        /// </summary>        
        /// <param name="publickey"></param>        
        /// <param name="content"></param>        
        /// <returns></returns>        
        //public string RSA2048Encrypt(string password, string publicKey)
        //{
        //    //TPSDKResponseEx<string> result = new TPSDKResponseEx<string>();
        //    //result = platformKey.getPublicKey();

        //    //byte[] keyByte = Convert.FromBase64String(result.result);
        //    byte[] keyByte = Convert.FromBase64String(publicKey);

        //    byte[] modulus = new byte[256];
        //    for (int i = 33; i < 289; i++)
        //    {
        //        modulus[i - 33] = keyByte[i];
        //    }

        //    byte[] exponent = new byte[3];
        //    for (int i = 291; i < keyByte.Length; i++)
        //    {
        //        exponent[i - 291] = keyByte[i];
        //    }

        //    //把3个变量转化为System.Numerics.BigInteger 
        //    var modulusBigInteger = new BigInteger(modulus);

        //    var exponentBigInteger = new BigInteger(exponent);

        //    var modulusBytes = modulusBigInteger.ToByteArray();

        //    var exponentBytes = exponentBigInteger.ToByteArray();

        //    var rsaCsp = new RSACryptoServiceProvider();
        //    RSAParameters parameters = new RSAParameters();
        //    parameters.Modulus = modulusBytes;
        //    parameters.Exponent = exponentBytes;
        //    rsaCsp.ImportParameters(parameters);

        //    var cipherbytes = rsaCsp.Encrypt(Encoding.UTF8.GetBytes(password), false);

        //    string cipher = Convert.ToBase64String(cipherbytes);
        //    return cipher;

        //}

        /// <summary>
        /// 密钥协商的AES128加密     
        /// </summary>    
        //public string AESEncrypt(string password, byte[] secretKey, byte[] iv)
        //{
        //    RijndaelManaged rijndaelCipher = new RijndaelManaged();
        //    rijndaelCipher.Mode = CipherMode.CBC;
        //    rijndaelCipher.Padding = PaddingMode.PKCS7;
        //    rijndaelCipher.KeySize = 128;
        //    rijndaelCipher.BlockSize = 128;
        //    //byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(secretKey);
        //    byte[] pwdBytes = secretKey;
        //    byte[] keyBytes = new byte[16];
        //    int len = pwdBytes.Length;
        //    if (len > keyBytes.Length)
        //        len = keyBytes.Length;
        //    System.Array.Copy(pwdBytes, keyBytes, len);
        //    rijndaelCipher.Key = keyBytes;
        //    byte[] ivBytes = iv;
        //    rijndaelCipher.IV = ivBytes;
        //    ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
        //    byte[] plainText = Encoding.UTF8.GetBytes(password);
        //    byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
        //    return Convert.ToBase64String(cipherBytes);
        //}

        /// <summary>
        /// 生成随机数
        /// </summary>
        /// <returns></returns>
        public byte[] GetRandomNumber()
        {
            System.Security.Cryptography.RandomNumberGenerator gen = System.Security.Cryptography.RandomNumberGenerator.Create(); 
            byte[] data = new byte[16]; 
            gen.GetBytes(data);
            
            return data;
        }

        /// <summary>
        /// 发送AES128的密钥和iv
        /// </summary>
        /// <param name="secretKey"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        public int SendSecretKey(byte[] secretKey, byte[] iv, string publicKey)
        {
            try
            {
                string secretKeyStr = string.Empty;
                foreach (byte b in secretKey)
                {
                    secretKeyStr += b.ToString("X2");
                }
                string ivStr = string.Empty;
                foreach (byte b in iv)
                {
                    ivStr += b.ToString("X2");
                }

                int result = platformKey.setSecretKey(RSAEncrypt(secretKeyStr, publicKey), RSAEncrypt(ivStr, publicKey));
                return result;
            }
            catch (SoapHeaderException e)
            {
                int errorCode = ExceptionUtils.processSoapException(e);
                return errorCode;
            }
        }
    }
}
