C# 如何限制AES加密密码的最大长度
我想限制加密输出代码的长度,如8、10或12个字符等 我使用“高级加密标准(AES)”和Cryptography.SymmetricAlgorithm.IV创建了非常小的加密coed 但加密代码的结果如下所示: 输入密码=“090400551” Converted Output=“mkopj3wfb6rzmp34urflied=”//这应该是长度的一半 我想把8到12个字符的长度缩短。任何C#加密库或算法都可以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
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
,那么您的输出将是这个值的倍数,我的回忆是否正确?也就是说,您可以得到比输入更长的输出?