using System;
using Org.BouncyCastle.Utilities.Encoders;
using System.Text;
using Newtonsoft.Json.Linq;
using System.Runtime.InteropServices;

namespace SMCryptoUtils
{

    [ClassInterface(ClassInterfaceType.None)]
    public class SMUtil:ISMUtil
    {

        private readonly static EasyGmUtils easyGmUtils = new EasyGmUtils();

        private readonly static SignUtil signUtil = new SignUtil();

        /**
        * 加密
        *
        * @param data
        * @param appId
        * @param appSecret
        * @return
        */
        public string encrypt(string data, string appId, string appSecret)
        {
            //加密流程
            //用appId加密appSecret获取新秘钥
            byte[] appSecretEncData = easyGmUtils.sm4Encrypt(Encoding.UTF8.GetBytes(appId.Substring(0, 16)), Encoding.UTF8.GetBytes(appSecret));
            //新秘钥串
            byte[] secKey = Encoding.UTF8.GetBytes(Hex.ToHexString(appSecretEncData).ToUpper().Substring(0, 16));
            //加密0数据
            string encryptDataStr = Hex.ToHexString(easyGmUtils.sm4Encrypt(secKey, Encoding.UTF8.GetBytes(data))).ToUpper();
            return encryptDataStr;
        }

        /**
         * 解密
         *
         * @param data
         * @param appId
         * @param appSecret
         * @return
        */
        public string decrypt(string data, string appId, string appSecret)
        {
            byte[] appSecretEncDataDecode = easyGmUtils.sm4Encrypt(Encoding.UTF8.GetBytes(appId.Substring(0, 16)), Encoding.UTF8.GetBytes(appSecret));
            byte[] secKeyDecode = Encoding.UTF8.GetBytes(Hex.ToHexString(appSecretEncDataDecode).ToUpper().Substring(0, 16));
            string decryptDataStr = Encoding.UTF8.GetString(easyGmUtils.sm4Decrypt(secKeyDecode, Hex.Decode(data)));
            return decryptDataStr;
        }

        /**
        * 签名
        *
        * @param jsonObject
        * @param appSecret
        * @param privateKey
        * @return
        */
        public string sign(JObject jsonObject, string appSecret, string privateKey)
        {
            // 获取签名串
            byte[] signText = Encoding.UTF8.GetBytes(signUtil.getSignText(jsonObject, appSecret));
            byte[] userId = Encoding.UTF8.GetBytes(appSecret);
            byte[] prvkey = Base64.Decode(privateKey);
            string responseSign = Base64.ToBase64String(easyGmUtils.signSm3WithSm2(signText, userId, prvkey));
            return responseSign;
        }

        /**
         * 验签
         *
         * @param jsonObject
         * @param appSecret
         * @param publicKey
         * @param responseSign
         * @return
         */
        public Boolean verify(JObject jsonObject, string appSecret, string publicKey, string responseSign)
        {
            //验签
            byte[] msg = Encoding.UTF8.GetBytes(signUtil.getSignText(jsonObject, appSecret));
            byte[] userIdDecode = Encoding.UTF8.GetBytes(appSecret);
            byte[] pubkey = Base64.Decode(publicKey);
            byte[] signData = Base64.Decode(responseSign);
            return easyGmUtils.verifySm3WithSm2(msg, userIdDecode, signData, pubkey);
        }
    }
}
