Threefish分组密码,ECB,.NET实现:加密和解密(初始明文)字符串的长度不同
我正在使用ECB密码模式和Threefish对称分组密码对.NET中的字符串进行加密和解密,我已将其实现作为.dll附加到我的项目中 密钥大小等于块大小,在我的例子中是256位 就我所知,输入字符串的长度,明文,必须等于密文的长度。还是一定要这样?例如,在我的例子中,考虑到ASCII编码,明文被分为块,每个块包含32个字符,但每个块总是有12个额外的密文字符,正如我所发现的!也就是说,密文的长度=初始文本的长度+12*n,其中n是文本块的数量,即str.length/32 str-初始字符串,已填充为32的倍数 我下面的代码中是否有错误,或者我的理解是否仅适用于非常简单的分组密码,仅使用XOR操作进行加密,而对于复杂的.NET加密系统,此规则不适用?如果是后一种情况,那么请解释到底是什么使这些长度不同!!!先谢谢你Threefish分组密码,ECB,.NET实现:加密和解密(初始明文)字符串的长度不同,.net,encryption,cryptography,block-cipher,.net,Encryption,Cryptography,Block Cipher,我正在使用ECB密码模式和Threefish对称分组密码对.NET中的字符串进行加密和解密,我已将其实现作为.dll附加到我的项目中 密钥大小等于块大小,在我的例子中是256位 就我所知,输入字符串的长度,明文,必须等于密文的长度。还是一定要这样?例如,在我的例子中,考虑到ASCII编码,明文被分为块,每个块包含32个字符,但每个块总是有12个额外的密文字符,正如我所发现的!也就是说,密文的长度=初始文本的长度+12*n,其中n是文本块的数量,即str.length/32 str-初始字符串,已
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using SkeinFish;
using System.Security.Cryptography;
namespace ComputerSecurity_Threefish
{
class Program
{
static void Main(string[] args)
{
string plainText = inputProperString(), decryptedText, cipherText;
Threefish th = new Threefish();
th.GenerateIV();
th.GenerateKey();
cipherText = EncryptWithThreefish(plainText, th);
Console.WriteLine("\nThis is how your encrypted string looks like:\n" + cipherText + "\n\nNow it will be decrypted...");
Console.WriteLine(cipherText.Length);
decryptedText = DecryptWithThreefish(cipherText, th);
Console.WriteLine("\nAnd here is your initial string decrypted:\n" + decryptedText);
Console.Read();
}
public static string inputProperString()
{
Console.Write("Enter a string for encryption: ");
string str = Console.ReadLine();
int remainder = str.Length % 32;
if (remainder != 0)
{
Console.WriteLine("\nYour string's length is not a multiple of 32, which is the equivalent of Threefish-256 blocksize for the length of ASCII string. The string will be padded with spaces.");
for (int i = 0; i < 32 - remainder; i++)
str += " ";
}
return str;
}
public static string EncryptWithThreefish(string plainText, Threefish th)
{
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform threefishEncryptor = th.CreateEncryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, threefishEncryptor, CryptoStreamMode.Write);
byte[] plainBytes = Encoding.ASCII.GetBytes(plainText);
cryptoStream.Write(plainBytes, 0, plainBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] cipherBytes = memoryStream.ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherBytes, 0, cipherBytes.Length);
}
public static string DecryptWithThreefish(string cipherText, Threefish th)
{
MemoryStream memoryStream = new MemoryStream();
ICryptoTransform threefishDecryptor = th.CreateDecryptor();
CryptoStream cryptoStream = new CryptoStream(memoryStream, threefishDecryptor, CryptoStreamMode.Write);
string decryptedText = String.Empty;
try
{
byte[] cipherBytes = Convert.FromBase64String(cipherText);
cryptoStream.Write(cipherBytes, 0, cipherBytes.Length);
cryptoStream.FlushFinalBlock();
byte[] plainBytes = memoryStream.ToArray();
decryptedText = Encoding.ASCII.GetString(plainBytes, 0, plainBytes.Length);
}
finally
{
memoryStream.Close();
cryptoStream.Close();
}
return decryptedText;
}
}
}
如果明文可按块大小划分,则如果使用PKCS7填充,则为ECB模式加密添加完整的填充块。Threefish的块大小为32、64或128字节,PKCS7填充是.NET中的默认值。然而,base 64将结果扩展为大约1/3加上一些可能的四舍五入,因此12个base 64字符听起来大致正确 分组密码通常不应用明文的异或进行加密。然而,使用流模式(如CTR)的流密码或分组密码。这种加密确实需要一个IV或至少一个nonce,否则,如果密钥被重用,它就会失败
总而言之,您确实不应该使用ECB模式加密,而且Threefish还没有完全指定用于加密。我建议至少使用CBC模式加密和AES。经过身份验证的密码(如GCM或EAX)会更好。修复了答案,而不是删除它。请回复答案。