【问题标题】:encrypt in .net core with TripleDES使用 TripleDES 在 .net 核心中加密
【发布时间】:2017-08-05 11:27:02
【问题描述】:
public static string Encrypt(string toEncrypt, string secretKey)
    {
        byte[] keyArray;
        byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

        var md5Serv = System.Security.Cryptography.MD5.Create();
        keyArray = md5Serv.ComputeHash(UTF8Encoding.UTF8.GetBytes(secretKey));
        md5Serv.Dispose();


        var tdes = System.Security.Cryptography.TripleDES.Create();


        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes.
        //We choose ECB(Electronic code Book)
        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)

        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        //transform the specified region of bytes array to resultArray
        byte[] resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0,
          toEncryptArray.Length);
        //Release resources held by TripleDes Encryptor
        tdes.Dispose();
        //Return the encrypted data into unreadable string format
        return Convert.ToBase64String(resultArray, 0, resultArray.Length);
    }

secretkey = 16 个字符的字符串

在这一行:

tdes.Key = keyArray;

我收到此错误: Message = "指定的密钥不是该算法的有效大小。"

error Message screen shot

如何在 asp.net core 1.1.0 中解决这个问题? 如何将字节[16]转换为字节[24]?

更新帖子

感谢帮助 :) 但是!

我在 .Net Framework 4.6.2 中使用此代码进行加密:

public static string Encrypt(string toEncrypt, string secretKey)
{
    byte[] keyArray;
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

    System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();


        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(secretKey));

        hashmd5.Clear();



    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    //set the secret key for the tripleDES algorithm
    tdes.Key = keyArray;
    //mode of operation. there are other 4 modes.
    //We choose ECB(Electronic code Book)
    tdes.Mode = CipherMode.ECB;
    //padding mode(if any extra byte added)

    tdes.Padding = PaddingMode.PKCS7;

    ICryptoTransform cTransform = tdes.CreateEncryptor();
    //transform the specified region of bytes array to resultArray
    byte[] resultArray =
      cTransform.TransformFinalBlock(toEncryptArray, 0,
      toEncryptArray.Length);
    //Release resources held by TripleDes Encryptor
    tdes.Clear();
    //Return the encrypted data into unreadable string format
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

并在 .Net Core 1.1 中使用它:

public static string Encrypt(string toEncrypt, string secretKey)
{
    byte[] keyArray;
    byte[] resultArray;
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

    using (var md5Serv = System.Security.Cryptography.MD5.Create())
    {
        keyArray = md5Serv.ComputeHash(UTF8Encoding.Unicode.GetBytes(secretKey));
        if(keyArray.Length==16)
        {
            byte[] tmp = new byte[24];
            Buffer.BlockCopy(keyArray, 0, tmp, 0, keyArray.Length);
            Buffer.BlockCopy(keyArray, 0, tmp, keyArray.Length, 8);
            keyArray = tmp;
        }
    }

    using (var tdes = System.Security.Cryptography.TripleDES.Create())
    {
        //set the secret key for the tripleDES algorithm
        tdes.Key = keyArray;
        //mode of operation. there are other 4 modes.
        //We choose ECB(Electronic code Book)
        tdes.Mode = CipherMode.ECB;
        //padding mode(if any extra byte added)

        tdes.Padding = PaddingMode.PKCS7;

        ICryptoTransform cTransform = tdes.CreateEncryptor();
        //transform the specified region of bytes array to resultArray
        resultArray =
          cTransform.TransformFinalBlock(toEncryptArray, 0,
          toEncryptArray.Length);
    }

    //Return the encrypted data into unreadable string format
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

但我不知道为什么这些方法会给我不同的结果?!

【问题讨论】:

  • documentation 表示密钥参数状态 此算法支持从 128 位到 192 位的密钥长度,以 64 位为增量。 但我们不知道里面是什么var toEncrypt 因为它没有包含在问题中。
  • 一般来说,前 8 个字节被复制到第 16-23 个字节。有些 3DES 实现会自动执行此操作,有些则不会。一些实现会将一个 8 字节的密钥复制到 24 位。最好完全指定加密函数的输入。当然,如果可能,最好不要使用 3DES,并且不再认为 2 键 3DES 是安全的。
  • 3DES、ECB 模式和 MD5 都因不安全而被弃用。为什么不在安全模式下使用 AES 和 SHA2 或 SHA3 哈希?
  • @rossum 1. 3-key 3DES 未被弃用,2-key 3DES 已被 NIST 弃用,请参阅 3DES keying options。您是正确的,3DES 不应该用于新工作。 2. SHA2 或 SHA3 用于获取密码稍微好一点,不应该使用,它们太快了。取而代之的是密码派生函数,例如 PBKDF2,迭代次数/成本约为 100 毫秒。
  • @PoPo 在您的 NetFx 示例中您使用 UTF8Encoding.UTF8,在 CoreFx 中您使用 UTF8Encoding.Unicode。假设您将 UTF8Encoding 别名为 System.Text.Encoding,则 Unicode 是 UCS-2,与 UTF-8 非常不同的字节模式,因此您没有使用相同的 MD5 输入。

标签: encryption cryptography .net-core secret-key tripledes


【解决方案1】:
if (key.Length == 16)
{
    byte[] tmp = new byte[24];
    Buffer.BlockCopy(key, 0, tmp, 0, key.Length);
    Buffer.BlockCopy(key, 0, tmp, key.Length, 8);
    key = tmp;
}

这会将您的 2DES 密钥 (k1, k2) 转换为 3DES 密钥 (k1, k2, k1)。 FWIW,此问题已针对 .NET Core 2.0 (https://github.com/dotnet/corefx/issues/9966) 修复。

所以,现在您的代码将再次运行。但是,正如其他人在 cmets 中指出的那样,您的代码中发生了很多事情,现代标准不认为这些代码在密码学上是合理的。您应该强烈考虑将此作为增强加密的机会。 (如果您不能“因为它不能使用现有数据”,那么您应该借此机会为您的数据添加加密敏捷性,以允许您随着时间的推移迁移到不同的密钥方案和/或算法。 )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    相关资源
    最近更新 更多