Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加密大于RSA密钥(模数)大小的数据。将分割的数据加密成块,似乎不起作用。有什么想法吗?_C#_Rsa_Rsacryptoserviceprovider - Fatal编程技术网

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);
    }
    
    非常感谢您!注意力不集中是问题的原因。我很高兴它起作用了。