zoukankan      html  css  js  c++  java
  • C# AES CTR模式 CryptoJS 对应C# .NET写法

    吐槽下国内博客基本都是瞎几把转发,找了2天没找到正确的方式,都准备放弃,使用WebBrowser 来跑

    CryptoJS.AES.decrypt({ciphertext: CryptoJS.enc.Base64.parse("79VrqFVhnPb36ZbAP0DZlA==")},CryptoJS.enc.Latin1.parse("442A472D4B6150645267556B58703273"),{mode:CryptoJS.mode.CTR,iv:CryptoJS.enc.Latin1.parse("556A586E32723575"),padding: CryptoJS.pad.Pkcs7}).toString(CryptoJS.enc.Utf8);
    

      javascript解析出来明文是:hello

    // The MIT License (MIT)
    
    // Copyright (c) 2014 Hans Wolff
    
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    // THE SOFTWARE.
    
    using System;
    using System.Collections.Generic;
    using System.Security.Cryptography;
    
    public class Aes128CounterMode : SymmetricAlgorithm
    {
        private readonly byte[] _counter;
        private readonly AesManaged _aes;
    
        public Aes128CounterMode(byte[] counter)
        {
            if (counter == null) throw new ArgumentNullException("counter");
            if (counter.Length != 16)
                throw new ArgumentException(String.Format("Counter size must be same as block size (actual: {0}, expected: {1})",
                    counter.Length, 16));
    
            _aes = new AesManaged
            {
                Mode = CipherMode.ECB,
                Padding = PaddingMode.None
            };
    
            _counter = counter;
        }
    
        public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] ignoredParameter)
        {
            return new CounterModeCryptoTransform(_aes, rgbKey, _counter);
        }
    
        public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] ignoredParameter)
        {
            return new CounterModeCryptoTransform(_aes, rgbKey, _counter);
        }
    
        public override void GenerateKey()
        {
            _aes.GenerateKey();
        }
    
        public override void GenerateIV()
        {
            // IV not needed in Counter Mode
        }
    }
    
    public class CounterModeCryptoTransform : ICryptoTransform
    {
        private readonly byte[] _counter;
        private readonly ICryptoTransform _counterEncryptor;
        private readonly Queue<byte> _xorMask = new Queue<byte>();
        private readonly SymmetricAlgorithm _symmetricAlgorithm;
    
        public CounterModeCryptoTransform(SymmetricAlgorithm symmetricAlgorithm, byte[] key, byte[] counter)
        {
            if (symmetricAlgorithm == null) throw new ArgumentNullException("symmetricAlgorithm");
            if (key == null) throw new ArgumentNullException("key");
            if (counter == null) throw new ArgumentNullException("counter");
            if (counter.Length != symmetricAlgorithm.BlockSize / 8)
                throw new ArgumentException(String.Format("Counter size must be same as block size (actual: {0}, expected: {1})",
                    counter.Length, symmetricAlgorithm.BlockSize / 8));
    
            _symmetricAlgorithm = symmetricAlgorithm;
            _counter = counter;
    
            var zeroIv = new byte[_symmetricAlgorithm.BlockSize / 8];
            _counterEncryptor = symmetricAlgorithm.CreateEncryptor(key, zeroIv);
        }
    
        public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
        {
            var output = new byte[inputCount];
            TransformBlock(inputBuffer, inputOffset, inputCount, output, 0);
            return output;
        }
    
        public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            for (var i = 0; i < inputCount; i++)
            {
                if (NeedMoreXorMaskBytes()) EncryptCounterThenIncrement();
    
                var mask = _xorMask.Dequeue();
                outputBuffer[outputOffset + i] = (byte)(inputBuffer[inputOffset + i] ^ mask);
            }
    
            return inputCount;
        }
    
        private bool NeedMoreXorMaskBytes()
        {
            return _xorMask.Count == 0;
        }
    
        private void EncryptCounterThenIncrement()
        {
            var counterModeBlock = new byte[_symmetricAlgorithm.BlockSize / 8];
    
            _counterEncryptor.TransformBlock(_counter, 0, _counter.Length, counterModeBlock, 0);
            IncrementCounter();
    
            foreach (var b in counterModeBlock)
            {
                _xorMask.Enqueue(b);
            }
        }
    
        private void IncrementCounter()
        {
            for (var i = _counter.Length - 1; i >= 0; i--)
            {
                if (++_counter[i] != 0)
                    break;
            }
        }
    
        public int InputBlockSize { get { return _symmetricAlgorithm.BlockSize / 8; } }
        public int OutputBlockSize { get { return _symmetricAlgorithm.BlockSize / 8; } }
        public bool CanTransformMultipleBlocks { get { return true; } }
        public bool CanReuseTransform { get { return false; } }
    
        public void Dispose()
        {
        }
    }
    

      

    using RGiesecke.DllExport;
    using System;
    using System.Runtime.InteropServices;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace AES_CTR_NET
    {
    
        [ComVisible(true)]
        [Guid("8871C5E0-B296-4AB8-AEE7-F2553BACB730"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IAES_CTR
        {
            [return: MarshalAs(UnmanagedType.I4)]
            int Encripta(string base64Data, string base64Llave, [MarshalAs(UnmanagedType.BStr)] out string base64Resultado);
    
            [return: MarshalAs(UnmanagedType.I4)]
            int Desencripta(string base64Data, string base64Llave, [MarshalAs(UnmanagedType.BStr)] out string base64Resultado);
    
            [return: MarshalAs(UnmanagedType.BStr)]
            string GetID();
    
            void SetID(string v);
    
            [return: MarshalAs(UnmanagedType.BStr)]
            string Version();
        }
    
        public class AES_CTR : IAES_CTR
        {
    
            private string _VERSION_ = "1.0.0.1";
            static private string _S_VERSION_ = "1.0.0.1";
    
            public string Version() { return this._VERSION_; }
    
            public string ID { get; set; }
    
            public void SetID(string v) { ID = v; }
    
            public string GetID() { return ID; }
    
            /// <summary>
            ///     Encripta un valor en AES_CTR
            /// </summary>
            /// <param name="base64Data">Cadena de texto en Base64 a encriptar</param>
            /// <param name="llave">Llave en claro</param>
            /// <param name="resultado">Cadena de texto en Base64 obtenida del arreglo de bytes</param>
            /// <returns> Cantidad de Bytes obtenido al encriptar</returns>       
            public int Encripta(string base64Data, string llave, out string base64Resultado)
            {
    
                int result = -1;
                base64Resultado = "";
                byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                byte[] outData = null;
                byte[] llaveB = null;
                byte[] data = null;
                try
                {
                    #region Validaciones
                    try
                    {
                        Encoding.UTF8.GetString(Convert.FromBase64String(base64Data));
                    }
                    catch (Exception)
                    {
                        throw new Exception(string.Format("La data a encriptar NO es un Base64 Valido [{0}]", base64Data));
                    }
    
                    try
                    {
                        Encoding.UTF8.GetString(Convert.FromBase64String(llave));
                    }
                    catch (Exception)
                    {
                        throw new Exception(string.Format("La llave NO es un Base64 Valido [{0}]", llave));
                    }
                    #endregion
    
                    data = Encoding.UTF8.GetBytes(base64Data);
                    outData = new byte[base64Data.Length];
                    llaveB = Encoding.UTF8.GetBytes(llave);// Convert.FromBase64String(base64Llave);
    
                    Aes128CounterMode am = new Aes128CounterMode(iv);
                    ICryptoTransform ict = am.CreateEncryptor(llaveB, null);
                    ict.TransformBlock(data, 0, outData.Length, outData, 0);
    
                    base64Resultado = Convert.ToBase64String(outData);
    
                    result = outData.Length;
    
                }
                catch (Exception e)
                {
                    base64Resultado = e.Message;
                }
    
    
                return result;
            }       /// <summary>
    
            /// <summary>
            ///     Encripta un valor en AES_CTR
            /// </summary>
            /// <param name="data">Cadena de texto en Base64 a encriptar</param>
            /// <param name="llave">Llave en claro</param>
            /// <param name="resultado">Cadena de texto en Base64 obtenida del arreglo de bytes</param>
            /// <returns> Cantidad de Bytes obtenido al encriptar</returns>       
            public int Encripta(byte[] data, byte[] llave, out byte[] resultado)
            {
    
                int result = -1;
                byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                resultado = null;
                try
                {
                    resultado = new byte[data.Length];
    
                    Aes128CounterMode am = new Aes128CounterMode(iv);
                    ICryptoTransform ict = am.CreateEncryptor(llave, null);
                    ict.TransformBlock(data, 0, resultado.Length, resultado, 0);
    
                    result = resultado.Length;
    
                }
                catch (Exception e)
                {
                    resultado = Encoding.UTF8.GetBytes(e.Message);
                }
    
    
                return result;
            }
    
            /// <summary>
            ///     Desencripta un valor en AES_CTR
            /// </summary>
            /// <param name="base64Data">Data Encriptada</param>
            /// <param name="llave">Llave en claro</param>
            /// <param name="resultado">Cadena de texto obtenida del arreglo de bytes</param>
            /// <returns> Cantidad de Bytes obtenido al desencriptar </returns>
            public int Desencripta(string base64Data, string llave, out string resultado)
            {
    
                int result = -1;
                resultado = "";
                byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
                byte[] outData = null;
                byte[] llaveB = null;
                byte[] data = null;
    
                try
                {
    
                    #region Validaciones
                    try
                    {
                        Encoding.UTF8.GetString(Convert.FromBase64String(base64Data));
                    }
                    catch (Exception)
                    {
                        throw new Exception(string.Format("La data a desencriptar NO es un Base64 Valido [{0}]", base64Data));
                    }
    
                    try
                    {
                        Encoding.UTF8.GetString(Convert.FromBase64String(llave));
                    }
                    catch (Exception)
                    {
                        throw new Exception(string.Format("La llave NO es un Base64 Valido [{0}]", llave));
                    }
                    #endregion
    
                    data = Convert.FromBase64String(base64Data);
                    outData = new byte[data.Length];
                    llaveB = Encoding.UTF8.GetBytes(llave);// Convert.FromBase64String(base64Llave);
    
                    Aes128CounterMode am = new Aes128CounterMode(iv);
                    ICryptoTransform ict = am.CreateDecryptor(llaveB, null);
                    ict.TransformBlock(data, 0, data.Length, outData, 0);
    
                    resultado = Encoding.UTF8.GetString(outData);
    
                    result = outData.Length;
    
                }
                catch (Exception e)
                {
                    resultado = e.Message;
                }
    
                return result;
            }
    
            /// <summary>
            ///     Desencripta un valor en AES_CTR
            /// </summary>
            /// <param name="dataIn">Data Encriptada</param>
            /// <param name="llave">Arreglo de bytes (32 bytes)</param>
            /// <param name="resultado">Cadena de texto obtenida del arreglo de bytes</param>
            /// <returns> Cantidad de Bytes obtenido al desencriptar </returns>
            public int Desencripta(byte[] data, byte[] llave,byte[] iv, out byte[] resultado)
            {
    
                int result = -1;
                resultado = null;
    
                try
                {
                    resultado = new byte[data.Length];
    
                    Aes128CounterMode am = new Aes128CounterMode(iv);
                    ICryptoTransform ict = am.CreateDecryptor(llave, null);
                    ict.TransformBlock(data, 0, data.Length, resultado, 0);
    
    
                    result = resultado.Length;
    
                }
                catch (Exception e)
                {
                    resultado = Encoding.UTF8.GetBytes(e.Message);
                }
    
                return result;
            }
    
            [DllExport(CallingConvention = CallingConvention.Cdecl)]
            public static void CreaObjeto([MarshalAs(UnmanagedType.Interface)] out IAES_CTR miAES)
            {
                miAES = new AES_CTR();
                miAES.SetID("_UNDEF_");
            }
    
            [DllExport("VersionNTS", CallingConvention = CallingConvention.Cdecl)]
            public static void VersionNTS([MarshalAs(UnmanagedType.BStr)] out string version)
            {
                version = _S_VERSION_;
            }
    
            [DllExport("EncriptaNTS", CallingConvention = CallingConvention.Cdecl)]
            public static int EncriptaNTS(IntPtr base64Data_P, IntPtr base64Llave_P, [MarshalAs(UnmanagedType.BStr)] out string base64Resultado)
            {
                string base64Data = Marshal.PtrToStringAuto(base64Data_P);
                string base64Llave = Marshal.PtrToStringAuto(base64Llave_P);
    
                var a = new AES_CTR();
                var ok = a.Encripta(base64Data, base64Llave, out base64Resultado);
                a = null;
                return ok;
            }
    
            [DllExport("DesencriptaNTS", CallingConvention = CallingConvention.Cdecl)]
            public static int DesencriptaNTS(IntPtr base64Data_P, IntPtr base64Llave_P, [MarshalAs(UnmanagedType.BStr)] out string base64Resultado)
            {
    
                string base64Data = Marshal.PtrToStringAuto(base64Data_P);
                string base64Llave = Marshal.PtrToStringAuto(base64Llave_P);
                var a = new AES_CTR();
                var ok = a.Desencripta(base64Data, base64Llave, out base64Resultado);
                a = null;
                return ok;
            }
    
            public static int EncriptaNTS(string base64Data, string base64Llave, out string base64Resultado)
            {
                var a = new AES_CTR();
                var ok = a.Encripta(base64Data, base64Llave, out base64Resultado);
                a = null;
                return ok;
            }
    
            public static int DesencriptaNTS(string base64Data, string base64Llave, out string base64Resultado)
            {
                var a = new AES_CTR();
                var ok = a.Desencripta(base64Data, base64Llave, out base64Resultado);
                a = null;
                return ok;
            }
            public static int DesencriptaNTS(byte[] base64Data, byte[] base64Llave, byte[] iv, out byte[] base64Resultado)
            {
                var a = new AES_CTR();
                var ok = a.Desencripta(base64Data, base64Llave, iv, out base64Resultado);
                a = null;
                return ok;
            }
    
        }
    }
    

      

    .CS源代码下载:<<=没毛病,就是在这里

    DEMO

    AES_CTR_NET.AES_CTR.DesencriptaNTS(Convert.FromBase64String("79VrqFVhnPb36ZbAP0DZlA=="), System.Text.Encoding.UTF8.GetBytes("5A7234753778214125442A472D4B6150"), System.Text.Encoding.UTF8.GetBytes("556A586E32723575"), out resultbytes);
  • 相关阅读:
    Vue路由重定向
    Vue使用rules对表单字段进行校验
    CSS Flex弹性布局实现Div
    Leetcode5 最长回文子串
    Java中char与String的相互转换
    [剑指offer] 替换空格
    Leetode最长回文串
    JavaScript 常用正则表达式集锦
    JavaScript 函数节流
    JavaScript target 与 currentTarget 区别
  • 原文地址:https://www.cnblogs.com/wangjiayuan/p/13042078.html
Copyright © 2011-2022 走看看