jjzjj

c# - 要解密的数据长度无效

coder 2024-05-28 原文

我正在尝试使用 RijndaelManaged 通过套接字加密和解密文件流,但我一直遇到异常

CryptographicException: Length of the data to decrypt is invalid.
    at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
    at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
    at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)

The exception is thrown at the end of the using statement in receiveFile, when the whole file has been transferred.

I tried searching the web but only found answers to problems that arise when using Encoding when encrypting and decrypting a single string. I use a FileStream, so I don't specify any Encoding to be used, so that should not be the problem. These are my methods:

private void transferFile(FileInfo file, long position, long readBytes)
{
    // transfer on socket stream
    Stream stream = new FileStream(file.FullName, FileMode.Open);
    if (position > 0)
    {
        stream.Seek(position, SeekOrigin.Begin);
    }
    // if this should be encrypted, wrap the encryptor stream
    if (UseCipher)
    {
        stream = new CryptoStream(stream, streamEncryptor, CryptoStreamMode.Read);
    }
    using (stream)
    {
        int read;
        byte[] array = new byte[8096];
        while ((read = stream.Read(array, 0, array.Length)) > 0)
        {
            streamSocket.Send(array, 0, read, SocketFlags.None);
            position += read;
        }
    }
}

private void receiveFile(FileInfo transferFile)
{
    byte[] array = new byte[8096];
    // receive file
    Stream stream = new FileStream(transferFile.FullName, FileMode.Append);
    if (UseCipher)
    {
        stream = new CryptoStream(stream, streamDecryptor, CryptoStreamMode.Write);
    }
    using (stream)
    {
        long position = new FileInfo(transferFile.Path).Length;
        while (position < transferFile.Length)
        {
            int maxRead = Math.Min(array.Length, (int)(transferFile.Length - position));
            int read = position < array.Length
                        ? streamSocket.Receive(array, maxRead, SocketFlags.None)
                        : streamSocket.Receive(array, SocketFlags.None);
            stream.Write(array, 0, read);
            position += read;
        }
    }
}

这是我用来设置密码的方法。 byte[] init 是生成的字节数组。

private void setupStreamCipher(byte[] init)
{
    RijndaelManaged cipher = new RijndaelManaged();
    cipher.KeySize = cipher.BlockSize = 256; // bit size
    cipher.Mode = CipherMode.ECB;
    cipher.Padding = PaddingMode.ISO10126;
    byte[] keyBytes = new byte[32];
    byte[] ivBytes = new byte[32];

    Array.Copy(init, keyBytes, 32);
    Array.Copy(init, 32, ivBytes, 0, 32);

    streamEncryptor = cipher.CreateEncryptor(keyBytes, ivBytes);
    streamDecryptor = cipher.CreateDecryptor(keyBytes, ivBytes);
}

有人知道我可能做错了什么吗?

最佳答案

在我看来你没有正确发送最后一个 block 。您至少需要 FlushFinalBlock() 发送 CryptoStream 以确保发送最终 block (接收流正在寻找的 block )。

顺便说一下,CipherMode.ECB is more than likely an epic fail就你正在做的事情的安全性而言。至少使用 CipherMode.CBC(密码 block 链接),它实际上使用 IV 并使每个 block 都依赖于前一个 block 。

编辑:糟糕,加密流处于读取模式。在这种情况下,您需要确保读取到 EOF,以便 CryptoStream 可以处理最后一个 block ,而不是在 readBytes 之后停止。如果以写入模式运行加密流,可能更容易控制。

请注意:您不能假设输入的字节数等于输出的字节数。 block 密码具有它们处理的固定 block 大小,除非您使用将 block 密码转换为流密码的密码模式,否则将会有填充使密文比明文更长。

关于c# - 要解密的数据长度无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/942139/

有关c# - 要解密的数据长度无效的更多相关文章

  1. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  2. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  5. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  6. ruby-on-rails - Rails 5 Active Record 记录无效错误 - 2

    我有两个Rails模型,即Invoice和Invoice_details。一个Invoice_details属于Invoice,一个Invoice有多个Invoice_details。我无法使用accepts_nested_attributes_forinInvoice通过Invoice模型保存Invoice_details。我收到以下错误:(0.2ms)BEGIN(0.2ms)ROLLBACKCompleted422UnprocessableEntityin25ms(ActiveRecord:4.0ms)ActiveRecord::RecordInvalid(Validationfa

  7. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  8. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  9. ruby - 从 String#split 返回的零长度字符串 - 2

    在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"

  10. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

随机推荐