Гнилая производительность RSACryptoServiceProvider.VerifyData? - PullRequest
2 голосов
/ 14 марта 2011

Производительность 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)

100 Для звонков в VerifyData требуются полные 3 секунды для двухъядерного процессора с частотой 2,1 ГГц и 32-разрядной операционной системы XP.

Я также пытался заменить строку "SHA1" на объект SHA1CryptoServiceProvider, который используется повторно (без новых экземпляров в цикле), но это не имеет значения.

0,03 секунды для одного вызова VerifyData - что здесь происходит?

Редактирование / обновление: только что попытался написать функции F #, используя BigInteger.ModPow, мою собственную функцию заполнения и SHA1CryptoServiceProvider.ComputeHash. 100 итераций заканчиваются за 0,07 секунды, что в 40 раз быстрее, чем RSACryptoServiceProvider. (Эти результаты должны были быть неверными. Будет пересмотрен позже.)

Ответы [ 3 ]

1 голос
0 голосов
/ 27 марта 2011

Я переключил время, чтобы использовать 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
0 голосов
/ 14 марта 2011

Происходит не только хеширование SHA1, но и асимметричная операция RSA, и эта операция относительно медленная (однако 30 мсек все же немного медленнее для одной 1024-битной операции).

Вы пробовали альтернативные криптографические реализации, которые используют свои собственные криптографические примитивы, такие как BouncyCastle или наш SecureBlackbox ? Попробуйте сделать это, чтобы проверить, какую производительность они показывают в вашей системе.

Также мы заметили, что некоторые базовые операции шифрования занимают гораздо больше времени на некоторых довольно мощных процессорах (QuadCore), чем на более старых DualCore (скажем, скорость AES составляет 6 Мбит / с на QuadCore против 30 Мбит / с на ноутбуке DualCore). То есть Архитектура системы как-то влияет на скорость управляемого кода.

...