RSACryptoServiceProvider.VerifyData 的性能很差?

发布于 2024-10-21 15:35:01 字数 1168 浏览 7 评论 0原文

是VerifyData的性能太差以至于该函数实际上毫无用处,还是我在下面的代码中做了一些非常错误的事情?

open System
open System.Security.Cryptography

let keySize     = 1024  // bits
let testDataLen = 1000
let iterations  = 100
let hashAlg     = "SHA1"

let timer f =
    let start = DateTime.Now
    f() |> ignore
    let finish = DateTime.Now
    finish - start


let bench () = 
    use rsaSP = new RSACryptoServiceProvider(keySize)
    let rnd = Random()
    let data = Array.create testDataLen 0uy
    rnd.NextBytes data

    let signature = rsaSP.SignData(data, hashAlg)

    let isValid = [for i in 1..iterations -> rsaSP.VerifyData(data, hashAlg, signature)]
                  |> List.forall id
    if not isValid then failwith "Bad signature."

printfn "%d iterations took %A" iterations (timer bench)

在 32 位 XP 上的 2.1 GHz 双核处理器上,对 verifyData 进行 100 次调用需要整整 3 秒。

我还尝试将“SHA1”字符串替换为重用的 SHA1CryptoServiceProvider 对象(循环中没有新的实例化),但这没有什么区别。

单次VerifyData调用耗时0.03秒——这是怎么回事?

编辑/更新:刚刚尝试使用 BigInteger.ModPow、我自己的填充函数和 SHA1CryptoServiceProvider.ComputeHash 编写 F# 函数。 100次迭代仅需0.07秒,比RSACryptoServiceProvider快40倍。(这些结果肯定是错误的。稍后会修改。)

Is the performance of VerifyData so bad that the function is practically useless, or am I doing something very wrong in the code below?

open System
open System.Security.Cryptography

let keySize     = 1024  // bits
let testDataLen = 1000
let iterations  = 100
let hashAlg     = "SHA1"

let timer f =
    let start = DateTime.Now
    f() |> ignore
    let finish = DateTime.Now
    finish - start


let bench () = 
    use rsaSP = new RSACryptoServiceProvider(keySize)
    let rnd = Random()
    let data = Array.create testDataLen 0uy
    rnd.NextBytes data

    let signature = rsaSP.SignData(data, hashAlg)

    let isValid = [for i in 1..iterations -> rsaSP.VerifyData(data, hashAlg, signature)]
                  |> List.forall id
    if not isValid then failwith "Bad signature."

printfn "%d iterations took %A" iterations (timer bench)

100 calls to VerifyData takes a full 3 seconds on a 2.1 GHz Dual-Core on 32 bit XP.

I've also tried replacing the "SHA1" string with a SHA1CryptoServiceProvider object that is reused (no new instantiations in the loop), but that makes no difference.

0.03 seconds for a single VerifyData call - what's going on here?

Edit/Update: Just tried writing F# functions, using BigInteger.ModPow, my own padding function and SHA1CryptoServiceProvider.ComputeHash. The 100 iterations finish in 0.07 seconds, which is 40 times faster than RSACryptoServiceProvider. (Those results must have been wrong. Will revise later.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月寒剑心 2024-10-28 15:35:02

不仅有 SHA1 散列,还有非对称 RSA 操作,而且这个操作相对较慢(但是,对于单个 1024 位操作来说 30 毫秒仍然有点慢)。

您是否尝试过使用自己的加密原语的替代加密实现,例如 BouncyCastle 或我们的 SecureBlackbox?尝试执行此操作来检查它们在您的系统上显示的性能。

我们还注意到,某些基本的加密操作在某些功能相当强大的处理器 (QuadCore) 上比在较旧的 DualCore 上花费更多的时间(例如,QuadCore 上的 AES 速度为 6 Mb/s,而 DualCore 笔记本上为 30 Mb/s)。即系统架构以某种方式影响托管代码的速度。

There's not just SHA1 hashing taking place, but also an asymmetric RSA operation, and this one is relatively slow (however, 30 msec is still a bit slow for a single 1024-bit operation).

Did you try alternative crypto implementations that use their own cryptographic primitives, such as BouncyCastle or our SecureBlackbox? Try doing this to check what performance they show on your system.

Also we noticed that some basic crypto operations take much more time on certain quite powerful processors (QuadCore) than on older DualCore (say speed of AES is 6 Mb/s on QuadCore against 30 Mb/s on DualCore notebook). I.e. system architecture affects speed of managed code somehow.

公布 2024-10-28 15:35:02

我将时间切换为使用 System.Diagnostics.Stopwatch,以确保您不会遇到分辨率不佳的问题。在我的双核笔记本电脑上运行您的代码 2 年,平均需要 270 毫秒,迭代 100 次。

我只对循环部分进行了计时,大约需要 70 毫秒,因此大部分工作是在循环之前完成的。进一步细分,实际上 SignData 才是这里的重点,尽管它在基准测试中只被调用一次,但它需要大约 210 毫秒。

当然,我们用的是不同的机器,但是70毫秒是你自己的验证码得到的?

计时器的更改:

let timer f =
    let sw = System.Diagnostics.Stopwatch()
    sw.Start()
    f() |> ignore
    sw.Stop()
    sw.ElapsedMilliseconds

示例细分:

Construct cryptoprovider took 0
Create test array took 0
rnd.NextBytes took 0
rsaSP.SignData took 211
VerifyData took 75
100 iterations took 287L

I switched timing to use System.Diagnostics.Stopwatch, to make sure you weren't suffering from bad resolution. Running your code on my dual-core laptop of 2 years it takes on average 270 milliseconds with 100 iterations.

I timed just the looping part, that takes around 70 milliseconds, so the bulk of the work is done prior to looping. Breaking it down further, it is actually SignData that is the hog here, it takes around 210 milliseconds even though it is called only once in the benchmark.

Of course, we are using different machines, but 70 milliseconds is what you got out of your own verifying code?

Changes to timer:

let timer f =
    let sw = System.Diagnostics.Stopwatch()
    sw.Start()
    f() |> ignore
    sw.Stop()
    sw.ElapsedMilliseconds

Sample breakdown:

Construct cryptoprovider took 0
Create test array took 0
rnd.NextBytes took 0
rsaSP.SignData took 211
VerifyData took 75
100 iterations took 287L
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文