How to limit the maximmum length of the AES Encryption Password

杀马特。学长 韩版系。学妹 提交于 2019-12-24 22:53:17

问题


I would like to limit the length of the encrypted output code like 8 or 10 or 12 character etc.

I have created the very small encrypted coed using he "Advanced Encryption Standard (AES)" with Cryptography.SymmetricAlgorithm.IV.

But the result of the Encrypted code as example below:

Input Password = "090400551"

Converted Output = "mkopj3WFb6RZMp34urFLew==" // This should be half the length

I want to reduce the length of 8 to 12 character. Any C# cryptography library or algorithm would be fine

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();
        }

    }
}

回答1:


If you put Rijndael into CFB mode with a block size of 8, then it acts as a stream cipher - for every byte you put in, you get a byte out again.

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();
    }
}

Note that this only appears to work on .NET Framework - .NET Core doesn't seem to support CFB (see this GitHub issue).


Note that encryption doesn't prevent tampering! People can't read your plaintext message, but they can very easily change the ciphertext to control what it gets decrypted to. Stream ciphers tend to be particularly vulnerable to this. If you need to stop someone controlling what the encrypted output decrypts into, then you need a signature.

Also note that you should not use the same IV across multiple messages. Create a random IV, and transfer it alongside your message, frequently as the first 2 bytes.



来源:https://stackoverflow.com/questions/58321231/how-to-limit-the-maximmum-length-of-the-aes-encryption-password

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!