Как ограничить максимальную длину пароля шифрования AES - PullRequest
0 голосов
/ 10 октября 2019

Я хотел бы ограничить длину зашифрованного выходного кода, например, 8, 10 или 12 символами и т. Д.

Я создал очень маленький зашифрованный код, используя «Расширенный стандарт шифрования (AES)» с криптографией. .SymmetricAlgorithm.IV.

Но результат зашифрованного кода, как показано ниже:

Входной пароль = "090400551"

Преобразованный вывод = "mkopj3WFb6RZMp34urFLew ==" //Это должно быть вдвое меньше длины

Я хочу уменьшить длину от 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();
        }

    }
}

1 Ответ

0 голосов
/ 10 октября 2019

Если вы переведете Rijndael в режим CFB с размером блока 8, то он будет действовать как потоковый шифр - для каждого вставленного байта вы снова получаете байт.

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 (см. эту проблему GitHub ).


Обратите внимание, что шифрование не предотвращает взлом! Люди не могут прочитать ваше открытое текстовое сообщение, но они могут очень легко изменить зашифрованный текст, чтобы контролировать то, к чему оно расшифровывается. Потоковые шифры, как правило, особенно уязвимы для этого. Если вам нужно запретить кому-либо контролировать то, во что расшифровывается зашифрованный вывод, то вам нужна подпись.

Также обратите внимание, что вы не должны использовать один и тот же IV для нескольких сообщений. Создайте случайный IV и передайте его вместе с вашим сообщением, часто в виде первых 2 байтов.

...