C#分割byte[]数组

5

我正在进行RSA加密,必须将我的长字符串拆分为小的byte []并对它们进行加密。 然后,我组合这些数组并转换为字符串,写入安全文件。

然后加密会创建byte [128]

我使用以下方式进行组合:

public static byte[] Combine(params byte[][] arrays)
{
    byte[] ret = new byte[arrays.Sum(x => x.Length)];
    int offset = 0;
    foreach (byte[] data in arrays)
    {
        Buffer.BlockCopy(data, 0, ret, offset, data.Length);
        offset += data.Length;
    }
    return ret;
}

当我解密时,我会将字符串转换为byte[]数组,现在需要拆分它来解码块,然后再转换为字符串。有什么想法吗?谢谢。
编辑:我认为现在已经拆分了,但解密失败了。这是因为RSA密钥等问题吗?在TimePointA时进行加密,然后在TimePointB尝试解密,但失败了。公钥不同,所以不确定是否是问题所在。
5个回答

4

当您进行解密时,可以创建一个数组来存储您的解密缓冲区并重复使用它:

通常情况下,RSA被用于加密像AES这样的对称密钥,然后对称算法用于加密实际数据。对于超过1个密码块的任何内容,这种方法都要快得多。要解密数据,您需要使用RSA解密对称密钥,然后使用该密钥解密数据。

byte[] buffer = new byte[BlockLength];
// ASSUMES SOURCE IS padded to BlockLength
for (int i = 0; i < source.Length; i += BlockLength)
{
    Buffer.BlockCopy(source, i, buffer, 0, BlockLength);
    // ... decode buffer and copy the result somewhere else
}

编辑 2:如果你将数据存储为字符串而不是原始字节,请使用 Convert.ToBase64String()Convert.FromBase64String() 作为最安全的转换解决方案。

编辑 3:从他的编辑中:

private static List<byte[]> splitByteArray(string longString)
{
    byte[] source = Convert.FromBase64String(longString);
    List<byte[]> result = new List<byte[]>();

    for (int i = 0; i < source.Length; i += 128)
    {
        byte[] buffer = new byte[128];
        Buffer.BlockCopy(source, i, buffer, 0, 128);
        result.Add(buffer);
    }
    return result;
}

它可以分割成任意大小的数组。 :) 此外,请检查添加的第二段内容。 - Sam Harwell
如果您的数据包含特定的字节序列,那么它将干扰UTF-16转换。如果您想确保数据正常工作,请使用base-64转换或直接序列化字节数组。 - Sam Harwell
谢谢你的建议。我会使用Base64。我已经发布了我的代码。它成功地分割了byte[],但在解密时出现了坏数据异常。 - Jon
你的代码没有返回经过编码的byte[128],例如我的第一个byte[]在编码后是47,89,142。在转换为base 64后将数组分割成128个后,第一个byte[]变成了95,219,47。 - Jon
@Jon,你使用它的方式出乎我的意料。请看我的更新。 - Sam Harwell
是的,在我回到这里之前,我刚刚注意到了那个问题!谢谢。看起来这确实将其恢复为编码后的状态,但是当我解密时仍然会出现BadData异常,这很奇怪。 - Jon

3
我认为这样的内容可以胜任:

我会这样表述:

        byte[] text = Encoding.UTF8.GetBytes(longString);
        int len = 128;

        for (int i = 0; i < text.Length; )
        {
            int j = 0;
            byte[] chunk = new byte[len];
            while (++j < chunk.Length && i < text.Length)
            {
                chunk[j] = text[i++];
            }
            Convert(chunk); //do something with the chunk
        }

接受的答案中给出的Buffer.* API调用更好。 - Matt Jacobsen

0
为什么需要将字符串分成可变长度的块?固定长度的块,或者根本不分块,都会大大简化这个问题。

RSA不会加密一个byte[1024]。 - Jon

0

"公钥不同"?

您使用私钥进行加密,然后使用与私钥对应的公钥进行解密。

其他任何操作都会给您带来无意义的结果。


我已经通过在编码时设置 RSA.FromXmlString(key) 使其工作,然后在解码时做同样的事情。这似乎可以工作,但是该密钥在我的代码中,这可能不安全? - Jon
1
没错,它不安全。要保证安全,你必须了解安全性。在Stackoverflow上提问并不能让你掌握基础知识。建议阅读Simon Singh的《密码编码学》,这本书非常易懂有趣,读完后你会开始理解基本原理。 - Will
哦,而且你不使用相同的密钥进行加密和解密。你使用“公共”密钥进行加密,使用匹配的“私有”密钥进行解密。 - Will
谢谢,我会看一下。虽然时间很宝贵,但目前这种方式可以工作,尽管需要在代码中明确保留编码/解码密钥。你还将它放在哪里,然后加密吗?这是一个恶性循环。 - Jon
哦,而且加密和解密不使用相同的密钥。 - 你有C# RSA的例子吗? - Jon
购买或借阅由专业人士撰写的适当书籍,然后将所学知识和理解应用于编写程序。没有复制粘贴的捷径会对您有益。 - Will

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接