Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何限制AES加密密码的最大长度_C#_Encryption_Cryptography_Aes_Rijndaelmanaged - Fatal编程技术网

C# 如何限制AES加密密码的最大长度

C# 如何限制AES加密密码的最大长度,c#,encryption,cryptography,aes,rijndaelmanaged,C#,Encryption,Cryptography,Aes,Rijndaelmanaged,我想限制加密输出代码的长度,如8、10或12个字符等 我使用“高级加密标准(AES)”和Cryptography.SymmetricAlgorithm.IV创建了非常小的加密coed 但加密代码的结果如下所示: 输入密码=“090400551” Converted Output=“mkopj3wfb6rzmp34urflied=”//这应该是长度的一半 我想把8到12个字符的长度缩短。任何C#加密库或算法都可以 using System; using System.Collections.Gen

我想限制加密输出代码的长度,如8、10或12个字符等

我使用“高级加密标准(AES)”和Cryptography.SymmetricAlgorithm.IV创建了非常小的加密coed

但加密代码的结果如下所示:

输入密码=“090400551”

Converted Output=“mkopj3wfb6rzmp34urflied=”//这应该是长度的一半

我想把8到12个字符的长度缩短。任何C#加密库或算法都可以

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace AnotherEncryption
{
    class Encryption
    {

        public static class Global
        {
            // set password
            public const string strPassword = "090400551";   
            public const String strPermutation = "Secure1234";
            public const Int32 bytePermutation1 = 0x78;
            public const Int32 bytePermutation2 = 0x56;
            public const Int32 bytePermutation3 = 0x34;
            public const Int32 bytePermutation4 = 0x88;
        }

        static void Main(string[] args)
        {
            Console.Title = "Secure Password v2";
            Console.WriteLine("Output---");
            Console.WriteLine("");

            Console.WriteLine("Password:  " + Global.strPassword);

            string strEncrypted = (Encrypt(Global.strPassword));
            Console.WriteLine("Encrypted: " + strEncrypted);

            string strDecrypted = Decrypt(strEncrypted);
            Console.WriteLine("Decrypted: " + strDecrypted);

            //mkopj3WFb6RZMp34urFLew==

            Console.ReadKey();
        }

        public static string Encrypt(string strData)
        {
            byte[] test = Encoding.UTF8.GetBytes(strData);
            return Convert.ToBase64String(Encrypt(test));
        }

        public static string Decrypt(string strData)
        {
            return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(strData)));

        }

        // encrypt
        public static byte[] Encrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged(); 

            aes.Key = passbytes.GetBytes(aes.KeySize / 8);
            aes.IV = passbytes.GetBytes(aes.BlockSize / 8);  

            CryptoStream cryptostream = new CryptoStream(memstream, aes.CreateEncryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }

        // decrypt
        public static byte[] Decrypt(byte[] strData)
        {
            PasswordDeriveBytes passbytes =
            new PasswordDeriveBytes(Global.strPermutation,
            new byte[] { Global.bytePermutation1,
                         Global.bytePermutation2,
                         Global.bytePermutation3,
                         Global.bytePermutation4
            });

            MemoryStream memstream = new MemoryStream();
            Aes aes = new AesManaged();
            aes.Key = passbytes.GetBytes(aes.KeySize / 8);
            aes.IV = passbytes.GetBytes(aes.BlockSize / 8);

            CryptoStream cryptostream = new CryptoStream(memstream,
            aes.CreateDecryptor(), CryptoStreamMode.Write);
            cryptostream.Write(strData, 0, strData.Length);
            cryptostream.Close();
            return memstream.ToArray();
        }

    }
}

如果您将Rijndael放入块大小为8的CFB模式,那么它将充当流密码-对于输入的每个字节,您将再次获得一个字节

public static void Main(string[] args)
{
    var algorithm = new RijndaelManaged()
    {
        Mode = CipherMode.CFB,

        // This is the equivalent of BlockSize in CFB mode. We set it to 8 (bits) to prevent any buffering of data 
        // while waiting for whole blocks.
        FeedbackSize = 8,
    };

    // Don't hard-code in real life, obviously
    var key = new byte[32];
    var iv = new byte[16];

    var input = new byte[] { 1, 2, 3 };

    byte[] result;
    using (var ms = new MemoryStream())
    {
        using (var cryptoStream = new CryptoStream(ms, algorithm.CreateEncryptor(key, iv), CryptoStreamMode.Write))
        {
            cryptoStream.Write(input, 0, input.Length);
        }
        result = ms.ToArray();
    }
}
请注意,这似乎只适用于.NET Framework-.NET Core似乎不支持CFB(请参阅)


请注意,加密不能防止篡改!人们无法阅读您的明文信息,但他们可以很容易地更改密文以控制解密内容。流密码往往特别容易受到这种攻击。如果需要阻止某人控制加密输出的解密内容,则需要签名


还请注意,您不应该在多条消息中使用相同的IV。创建一个随机IV,并将其与您的消息一起传输,通常为前2个字节。

正是转换为基64字符串使输出比输入长。AES是一种基于块的密码,块大小为128位或16字节。您将无法获得不是16字节倍数的输出。您好,除了AES之外,还有其他算法或库用于获取字符较少的密码吗?为什么要首先加密密码?最典型的情况是你想要散列一个密码,而不是加密它。嗨,我需要加密的密码,而不是散列。但是密码的长度很长,用户很难输入。我正在创建Xamarin表单(Android移动平台)。在手机上,超过20个字符太长了。你还忘了存储IV,如果没有唯一的IV,这种加密方法会泄露数据。@Maarten我绝对不会说应该如何处理IV。我知道OP没有正确处理静脉注射:请随意做出自己的解释。我在回答的底部加了一个简短的注释。但是,使用CBC(问题中使用的默认模式),如果前16个字节相同,则只会泄漏最小的信息。使用CFB和同一个IV时,您泄漏了几乎所有的信息,即所有密码(!)
FeedbackSize=8
-他们可能应该使用完整的块大小作为反馈。@jww如果您增加
FeedbackSize
,那么您的输出将是这个值的倍数,我的回忆是否正确?也就是说,您可以得到比输入更长的输出?