为啥 .NET 的 RandomNumberGenerator.GetBytes 方法将其结果分配给一个字节数组参数,而不是返回一个新的字节数组?

Posted

技术标签:

【中文标题】为啥 .NET 的 RandomNumberGenerator.GetBytes 方法将其结果分配给一个字节数组参数,而不是返回一个新的字节数组?【英文标题】:Why does .NET's RandomNumberGenerator.GetBytes method assign its results to a byte array parameter instead of returning a new byte array?为什么 .NET 的 RandomNumberGenerator.GetBytes 方法将其结果分配给一个字节数组参数,而不是返回一个新的字节数组? 【发布时间】:2020-02-05 05:58:09 【问题描述】:

.NET Framework 具有用于生成加密安全随机字节的RandomNumberGenerator 类。它的主要方法之一GetBytes 具有签名void GetBytes (byte[] data) - 它采用字节数组作为参数并用随机字节填充它,而不是返回字节数组。为什么是这样?在现有阵列上操作而不是创建新阵列是否存在安全原因?

【问题讨论】:

这很可能只是出于效率原因。如果您多次使用此方法,您可以重复使用字节数组,而不必一次又一次地分配和释放字节数组内存。您还可以在其他输出字节数组的方法上看到这一点。 它也可能只是一个错误的副本,例如Java JCA 框架(很多东西毕竟可以看作是 Java 框架思想的复制品——Java 当然也复制了 C/C++ 的一些东西)。这些问题的问题在于,why 问题只能由原作者真正回答。我们只能尝试找到可以说明原因的客观原因。 是的,“为什么”问题总是至少有点棘手 - 我主要想知道分配是否存在一些安全问题,这在不询问原始创建者的情况下客观上是显而易见的。 【参考方案1】:

我认为安全性并不是托管框架中byte[] 参数的真正原因。我看不出它是由方法和外部生成的有什么区别,因为byte[] - 一个基本类型的数组 - 不太可能有多个实现。如果可能存在差异,那么让该方法生成字节数组会更有意义。

没有它,已经给出的效率理由更有意义;毕竟字节数组可能很大(-ish),并且您无法复制获取字节的调用的效率。现有数组还有另一种方法that additionally takes an offset and "count" of bytes。这使您可以直接将字节生成到还可以保存其他数据的数组中(例如,字节数组中的 IV 和密文的串联)。当然,单个参数只是该调用的一种特殊情况/便利方法。多参数是效率最重要的参数,否则您也必须复制密文;数组毕竟不能缩小。创建一个名称相同但方法签名完全不同的方法会很奇怪。

Java JCA 等其他框架对SecureRandom 具有相同的方法。因此,作者很可能知道此类框架并决定模仿这些现有的 API,除非有足够的理由进行更改。

【讨论】:

有道理,谢谢!我将把它打开一天,但如果没有更好的答案,请期待明天的绿色复选标记。 一个不同之处在于,通过接受(与返回)数组,调用者可以在调用之前固定内存(GCHandle 或fixed),从而避免 GC 压缩残留的风险。并不是说它在这里可能很重要。 啊,好的,所以这里有 byte[] 的一些可能性:) 很有趣。

以上是关于为啥 .NET 的 RandomNumberGenerator.GetBytes 方法将其结果分配给一个字节数组参数,而不是返回一个新的字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

在 .NET 中,为啥 ObjectCache 是 MemoryCache 的首选类型?

为啥.net(仍然)需要拳击?

为啥.NET 没有内存泄漏?

为啥没有设置 .NET 目标框架定义?

为啥不重用“ASP.NET_SessionId”?

为啥不升级到最新的 .NET 框架?