RSACryptoServiceProvider.VerifyData的性能下降?

时间:2011-03-14 20:07:27

标签: .net f# digital-signature

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双核,100次调用VerifyData需要整整3秒。

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

单个VerifyData调用

0.03秒 - 这里发生了什么?

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

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

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

您是否尝试过使用自己的加密原语的替代加密实现,例如BouncyCastleSecureBlackbox?尝试这样做以检查它们在您的系统上显示的性能。

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

答案 2 :(得分:0)

我改变了使用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