C# 加密大于RSA密钥(模数)大小的数据。将分割的数据加密成块,似乎不起作用。有什么想法吗?
请先读一读:C# 加密大于RSA密钥(模数)大小的数据。将分割的数据加密成块,似乎不起作用。有什么想法吗?,c#,rsa,rsacryptoserviceprovider,C#,Rsa,Rsacryptoserviceprovider,请先读一读: 我知道RSA不是为数据块加密而设计的。但这仍然是可能的。 我知道使用RSA加密数据块时会受到安全和性能方面的影响。 我不允许使用混合加密。因此,以下步骤在我的情况下是不可接受的: 为对称算法生成随机密钥 使用对称算法和随机密钥加密数据 使用公钥加密随机密钥,并将其存储在数据旁边(或之前)的加密格式中 但我必须尽一切努力完成给定的任务感谢您的理解 我对示例进行了极大的抽象和简化,以明确我正在努力解决的问题 string data = "message 700-1300 lett
- 我知道RSA不是为数据块加密而设计的。但这仍然是可能的。
- 我知道使用RSA加密数据块时会受到安全和性能方面的影响。
- 我不允许使用混合加密。因此,以下步骤在我的情况下是不可接受的:
但我必须尽一切努力完成给定的任务感谢您的理解 我对示例进行了极大的抽象和简化,以明确我正在努力解决的问题
string data = "message 700-1300 letters long";
byte[] bytes = data.ToUtf8EncodedByteArray();
// I'm splitting utf8 encoded bytes into chunks of 32 bytes each.
IEnumerable<IEnumerable<byte>> batches = bytes.ChunkBy(32);
LinkedList<byte[]> encryptedChunks = new LinkedList<byte[]>();
LinkedList<byte[]> decryptedChunks = new LinkedList<byte[]>();
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false;
_publicKey = rsa.ExportParameters(false);
_privateKey = rsa.ExportParameters(true);
rsa.ImportParameters(_publicKey);
byte[] encryptedBatch = null;
foreach (IEnumerable<byte> batch in batches)
{
encryptedBatch = rsa.Encrypt(batch.ToArray(), true);
encryptedChunks.AddLast(encryptedBatch);
}
// Then encryptedChunks.ToArray() will be send over the network
// When encrypted bytes are received at another endpoint, they have to be decrypted.
rsa.ImportParameters(_privateKey);
byte[] decryptedBatch = null;
foreach (byte[] chunk in encryptedChunks)
{
decryptedBatch = rsa.Decrypt(chunk, true);
decryptedChunks.AddLast(chunk);
}
}
// After decryption of each encrypted chunk of data, I project it back into an array of bytes.
byte[] decrypted = decryptedChunks.SelectMany(chunk => chunk).ToArray();
// When trying to display decoded bytes as a string (as it was initially), instead of original message I get hieroglyphs.
Console.Out.WriteLine($"Decrypted message: {decrypted.ToUtf8String()}");
string data=“消息700-1300个字母长”;
byte[]bytes=data.toutf8encodedbyteraray();
//我将utf8编码的字节分割成每个32字节的块。
IEnumerable batches=bytes.ChunkBy(32);
LinkedList encryptedChunks=新建LinkedList();
LinkedList decryptedChunks=新LinkedList();
使用(var rsa=new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp=false;
_publicKey=rsa.ExportParameters(false);
_privateKey=rsa.ExportParameters(true);
rsa.导入参数(_公钥);
字节[]encryptedBatch=null;
foreach(批量中的IEnumerable批)
{
encryptedBatch=rsa.Encrypt(batch.ToArray(),true);
encryptedChunks.AddLast(encryptedBatch);
}
//然后将通过网络发送encryptedChunks.ToArray()
//当在另一个端点接收到加密字节时,必须对其进行解密。
rsa.ImportParameters(_privateKey);
字节[]decryptedBatch=null;
foreach(encryptedChunks中的字节[]块)
{
decryptedBatch=rsa.Decrypt(区块,true);
decryptedChunks.AddLast(chunk);
}
}
//在对每个加密的数据块进行解密后,我将其投影回一个字节数组。
byte[]decrypted=decryptedChunks.SelectMany(chunk=>chunk.ToArray();
//当尝试将解码的字节显示为字符串时(就像最初一样),我得到的不是原始消息,而是象形文字。
Console.Out.WriteLine($“解密的消息:{Decrypted.ToUtf8String()}”);
如果需要,以下是扩展方法(在我的代码中使用):
public static IEnumerable<IEnumerable<TElement>> ChunkBy<TElement>(
this IEnumerable<TElement> source, int chunkSize)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value).ToArray())
.ToArray();
}
public static byte[] ToUtf8EncodedByteArray(this string source)
{
return Encoding.UTF8.GetBytes(source.ToCharArray());
}
public static string ToUtf8String(this byte[] sourceBytes)
{
return Encoding.UTF8.GetString(sourceBytes);
}
公共静态IEnumerable ChunkBy(
此IEnumerable源,int chunkSize)
{
返回源
.Select((x,i)=>new{Index=i,Value=x})
.GroupBy(x=>x.Index/chunkSize)
.Select(x=>x.Select(v=>v.Value).ToArray()
.ToArray();
}
公共静态字节[]ToUtf8EncodedByteArray(此字符串源)
{
返回Encoding.UTF8.GetBytes(source.ToCharArray());
}
公共静态字符串ToUtf8String(此字节[]源字节)
{
返回Encoding.UTF8.GetString(sourceBytes);
}
另外,我在加密数据(文本)之前也尝试过,将其编码为ASCII,而不是UTF8。这也没用 有什么想法吗?(除了切换到使用对称密钥的加密。如上所述,我不允许这样做。)我稍微修改了(查看更改的注释)您的代码,它可以工作:
public static IEnumerable<IEnumerable<TElement>> ChunkBy<TElement>(this IEnumerable<TElement> source, int chunkSize)
{
return source
.Select((x, i) => new { Index = i, Value = x })
.GroupBy(x => x.Index / chunkSize)
.Select(x => x.Select(v => v.Value).ToArray())
.ToArray();
}
public static byte[] ToUtf8EncodedByteArray(this string source)
{
// Changed: instead of source.ToCharArray() use source directly
return Encoding.UTF8.GetBytes(source);
}
public static string ToUtf8String(this byte[] sourceBytes)
{
return Encoding.UTF8.GetString(sourceBytes);
}
[STAThread]
public static void Main()
{
// Changed: Generate some sample data...
string data = string.Join(string.Empty, Enumerable.Repeat<string>("abcdefghijklmnopqrstuvwxyz0123456789<>!?", 100));
byte[] bytes = data.ToUtf8EncodedByteArray();
// I'm splitting utf8 encoded bytes into chunks of 32 bytes each.
IEnumerable<IEnumerable<byte>> batches = bytes.ChunkBy(32);
LinkedList<byte[]> encryptedChunks = new LinkedList<byte[]>();
LinkedList<byte[]> decryptedChunks = new LinkedList<byte[]>();
using (var rsa = new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp = false;
var _publicKey = rsa.ExportParameters(false);
var _privateKey = rsa.ExportParameters(true);
rsa.ImportParameters(_publicKey);
byte[] encryptedBatch = null;
foreach (IEnumerable<byte> batch in batches)
{
encryptedBatch = rsa.Encrypt(batch.ToArray(), true);
encryptedChunks.AddLast(encryptedBatch);
}
rsa.ImportParameters(_privateKey);
byte[] decryptedBatch = null;
foreach (byte[] chunk in encryptedChunks)
{
decryptedBatch = rsa.Decrypt(chunk, true);
// Changed (critical): instead of chunk (the encrypted data) use the decrypted data
decryptedChunks.AddLast(decryptedBatch);
}
}
// After decryption of each encrypted chunk of data, I project it back into an array of bytes.
byte[] decrypted = decryptedChunks.SelectMany(chunk => chunk).ToArray();
var data2 = decrypted.ToUtf8String();
// Changed: Verify that input and output are the same
var equals = data.Equals(data2);
}
public静态IEnumerable ChunkBy(此IEnumerable源代码,int chunkSize)
{
返回源
.Select((x,i)=>new{Index=i,Value=x})
.GroupBy(x=>x.Index/chunkSize)
.Select(x=>x.Select(v=>v.Value).ToArray()
.ToArray();
}
公共静态字节[]ToUtf8EncodedByteArray(此字符串源)
{
//已更改:而不是源代码。ToCharArray()直接使用源代码
返回Encoding.UTF8.GetBytes(源代码);
}
公共静态字符串ToUtf8String(此字节[]源字节)
{
返回Encoding.UTF8.GetString(sourceBytes);
}
[状态线程]
公共静态void Main()
{
//更改:生成一些示例数据。。。
字符串数据=string.Join(string.Empty,可枚举.Repeat(“abcdefghijklmnopqrstuvxyz012456789!?”,100));
byte[]bytes=data.toutf8encodedbyteraray();
//我将utf8编码的字节分割成每个32字节的块。
IEnumerable batches=bytes.ChunkBy(32);
LinkedList encryptedChunks=新建LinkedList();
LinkedList decryptedChunks=新LinkedList();
使用(var rsa=new RSACryptoServiceProvider(2048))
{
rsa.PersistKeyInCsp=false;
var _publicKey=rsa.ExportParameters(false);
var _privateKey=rsa.ExportParameters(true);
rsa.导入参数(_公钥);
字节[]encryptedBatch=null;
foreach(批量中的IEnumerable批)
{
encryptedBatch=rsa.Encrypt(batch.ToArray(),true);
encryptedChunks.AddLast(encryptedBatch);
}
rsa.ImportParameters(_privateKey);
字节[]decryptedBatch=null;
foreach(encryptedChunks中的字节[]块)
{
decryptedBatch=rsa.Decrypt(区块,true);
//已更改(关键):使用解密数据代替区块(加密数据)
decryptedChunks.AddLast(decryptedBatch);
}
}
//在对每个加密的数据块进行解密后,我将其投影回一个字节数组。
byte[]decrypted=decryptedChunks.SelectMany(chunk=>chunk.ToArray();
var data2=decrypted.ToUtf8String();
//更改:验证输入和输出是否相同
var=data.equals(数据2);
}
非常感谢您!注意力不集中是问题的原因。我很高兴它起作用了。