三重 DES。指定的填充模式对此算法无效

TripleDES. Specified padding mode is not valid for this algorithm

我有一个使用 core1.1 的 net core 应用程序当将 cript/decript 模块从旧的 .NET4.6 迁移到 net core 时,它​​就无法工作

First TripleDES 不再(它曾经)支持 128 位密钥并固定为 192 位密钥,尝试更改它会导致错误。

其次,在尝试描述此字符串时:

/Tk0ydguv3HauCVUWDK3Tr6U8c9BBaaRwtSt5q4/uHg=

TripleDES 使用 PKCS7 Padding saing 启动错误 "Specified padding mode is not valid for this algorithm." 这很奇怪,因为 ti 是它默认的填充。

我的project.json:

{
  "dependencies": {
    "Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    },
    "Microsoft.AspNetCore.Diagnostics": "1.1.0",
    "Microsoft.AspNetCore.Mvc": "1.0.1",
    "Microsoft.AspNetCore.Razor.Tools": {
      "version": "1.0.0-preview2-final",
      "type": "build"
    },
    "Microsoft.AspNetCore.Routing": "1.0.1",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0",
    "Microsoft.AspNetCore.Server.Kestrel": "1.0.1",
    "Microsoft.AspNetCore.StaticFiles": "1.0.0",
    "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0",
    "Microsoft.Extensions.Configuration.Json": "1.0.0",
    "Microsoft.Extensions.Logging": "1.0.0",
    "Microsoft.Extensions.Logging.Console": "1.0.0",
    "Microsoft.Extensions.Logging.Debug": "1.0.0",
    "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0",
    "Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
    "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",
    "Microsoft.EntityFrameworkCore.Design": "1.0.0-preview2-final",
    "Microsoft.EntityFrameworkCore.SqlServer.Design": "1.0.1",
    "Microsoft.AspNetCore.Mvc.WebApiCompatShim": "1.0.1",
    "Microsoft.AspNetCore.Session": "1.0.0",
    "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
  },

    "tools": {
        "BundlerMinifier.Core": "2.0.238",
        "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final",
        "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
        "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
    },

  "frameworks": {
    "netcoreapp1.1": {
        "imports": [
            "portable-net461+win8"
        ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "**/*.cshtml",
      "appsettings.json",
      "web.config"
    ]
  },

  "scripts": {
    "prepublish": [ "bower install", "dotnet bundle" ],
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

我的代码:

using System;
using System.Security.Cryptography;
using System.Text;
namespace WebApp.Class
{
    public class Md5
    {
        private static readonly byte[] IV = { 240, 3, 45, 29, 0, 76, 173, 59 };

        const int NumCryptokey = 6;
        const int NumExtraClave = 8;
        const int NumsKey = 7;


        public static string Generate(int KeyChars)
        {
            int i_key = 0;
            float Random1 = 0;
            Int16 arrIndex = default(Int16);
            StringBuilder sb = new StringBuilder();
            char RandomLetter;

            string KeyLetters = "abcdefghijklmnopqrstuvwxyz";
            string KeyNumbers = "0123456789";

            char[] LettersArray = null;
            char[] NumbersArray = null;

            LettersArray = KeyLetters.ToCharArray();
            NumbersArray = KeyNumbers.ToCharArray();

            for (i_key = 1; i_key <= KeyChars; i_key++)
            {
                Random random = new Random();
                Random1 = random.Next();

                arrIndex = -1;
                if ((Convert.ToInt32(Random1 * 111)) % 2 == 0)
                {
                    while (arrIndex < 0)
                    {
                        arrIndex = Convert.ToInt16(LettersArray.GetUpperBound(0) * Random1);
                    }
                    RandomLetter = LettersArray[arrIndex];
                    if ((Convert.ToInt32(arrIndex * Random1 * 99)) % 2 != 0)
                    {
                        RandomLetter = LettersArray[arrIndex];
                        RandomLetter = char.ToUpper(RandomLetter);
                    }
                    sb.Append(RandomLetter);
                }
                else
                {
                    while (arrIndex < 0)
                    {
                        arrIndex = Convert.ToInt16(NumbersArray.GetUpperBound(0) * Random1);
                    }
                    sb.Append(NumbersArray[arrIndex]);
                }
            }
            return sb.ToString();
        }

        public static string Encriptar(string serializedQueryString)
        {
            string functionReturnValue = null;
            string sRetorno = null;
            try
            {
                string cryptokey = "";
                string ExtraClave = "";
                string sKey = "";

                cryptokey = Generate(NumCryptokey);
                ExtraClave = Generate(NumExtraClave);
                sKey = Generate(NumsKey);

                byte[] buffer = Encoding.ASCII.GetBytes(serializedQueryString + ExtraClave);
                var des = TripleDES.Create();
                var MD5 = System.Security.Cryptography.MD5.Create();
                des.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sKey + cryptokey));
                des.IV = IV;

                sRetorno = cryptokey + ExtraClave + sKey + Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length));

                functionReturnValue = sRetorno;
            }
            catch (Exception ex)
            {
                functionReturnValue = "";
            }
            return functionReturnValue;

        }

        public static string Desencriptar(string encryptedQueryString)
        {
            string functionReturnValue = null;
            byte[] buffer = null;
            var DES = System.Security.Cryptography.TripleDES.Create();
            var Md5 = MD5.Create();
            string sRetorno = null;

            string cryptokey = "";
            string ExtraClave = "";
            string sKey = "";

            cryptokey = encryptedQueryString.Substring(0,NumCryptokey);
            ExtraClave = encryptedQueryString.Substring(NumCryptokey, NumExtraClave);
            sKey = encryptedQueryString.Substring(NumCryptokey + NumExtraClave, NumsKey);

            encryptedQueryString = encryptedQueryString.Substring(NumCryptokey + NumExtraClave + NumsKey, encryptedQueryString.Length-(NumCryptokey + NumExtraClave + NumsKey));

            try
            {
                buffer = Convert.FromBase64String(encryptedQueryString);
            byte[] by = new byte[24];
                by = Md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(sKey + cryptokey));
            Array.Resize(ref by, 24);
                DES.Key = by;
                DES.IV = IV;

                sRetorno = Encoding.ASCII.GetString(DES.CreateDecryptor().TransformFinalBlock(buffer, 0, buffer.Length)).Replace(ExtraClave, "");
                functionReturnValue = sRetorno;
            }
            catch (Exception ex)
            {
                functionReturnValue = "";
            }
            return functionReturnValue;

        }
    }
}

我在 ASP.NET Core 中遇到了同样的问题。但是,我没有指定任何 IV。

我只是在指定密钥后加密和解密时添加了这一行。

DES3.IV = new byte[DES3.BlockSize / 8];

如果没有这一行,我会收到上述错误。

根据 https://msdn.microsoft.com/en-us/library/system.security.cryptography.symmetricalgorithm.iv(v=vs.110).aspx

上的文档

The IV property is automatically set to a new random value whenever you create a new instance of one of the SymmetricAlgorithm classes or when you manually call the GenerateIV method.

但是,我仍然不明白为什么这会起作用,因为即使我尝试为 IV 提供静态值(就像您所讨论的那样),但它仍然失败了。

找到了!

    public static string Encriptar(string serializedQueryString)
    {
        string functionReturnValue = null;
        string sRetorno = null;
        try
        {
            string cryptokey = "";
            string ExtraClave = "";
            string sKey = "";

            cryptokey = Generate(NumCryptokey);
            ExtraClave = Generate(NumExtraClave);
            sKey = Generate(NumsKey);

            byte[] buffer = Encoding.ASCII.GetBytes(serializedQueryString + ExtraClave);
            var des = TripleDES.Create();
            var Md5 = MD5.Create();

            byte[] by = new byte[24];
            by = Md5.ComputeHash(Encoding.ASCII.GetBytes(sKey + cryptokey));
            Array.Resize(ref by, 24);
            Array.Copy(by, 0, by, 16, 8);
            des.Key = by;
            des.IV = IV;
            //es.Padding = PaddingMode.None;
            sRetorno = cryptokey + ExtraClave + sKey + Convert.ToBase64String(des.CreateEncryptor().TransformFinalBlock(buffer, 0, buffer.Length));

            functionReturnValue = sRetorno;

        }
        catch (Exception ex)
        {
            functionReturnValue = "";
        }
        return functionReturnValue;
    }