Есть ли проблемы с самим алгоритмом (может вообще не стоит его использовать)?
DSA, не входящие в ЕС, умирает.
Я предполагаю, что на самом деле это было сделано в исходной спецификации (FIPS 186-1), которая ограничивала ключи до 1024 бит, а алгоритм - до SHA-1. В 2009 году алгоритм был обновлен в соответствии со стандартом FIPS 186-3 для поддержки немного больших ключей и хэшей SHA-2. Для подписей FIPS 186-1 (и FIPS 186-2) DSA требуются только данные и закрытый ключ (для проверки требуются только данные, подпись и открытый ключ), подписи FIPS 186-3 также требуют алгоритма хеширования в качестве входных данных... поэтому API не совсем совместим.
Windows CAPI (старшая из двух криптографических платформ Windows) проигнорировала обновление FIPS 186-3, как и Apple Security.framework. Windows CNG и OpenSSL поддерживают «новый DSA». Apple не может обрабатывать сертификаты, подписанные с «новым DSA» (и, может быть, даже с «классическим DSA», я забыл), а Windows не поддерживает «новый DSA» в цепочках сертификатов, только «классический DSA».
Таким образом, сертификаты DSA, как правило, ограничены ограничениями FIPS 186-1/186-2, что означает SHA-1 (в наши дни никому не нравится) и 1024-битные ключи (которые по сегодняшним меркам слишком малы). Если вы знаете, что OpenSSL проверяет вас, вы можете использовать лучшие ключи DSA.
DSA также обычно намного медленнее проверяет подпись, чем RSA.
На уровне безопасности 80 бит, используя инструмент скорости OpenSSL на моей случайной виртуальной машине (выходные данные слегка изменены для презентационных целей, отсортированы по убыванию проверки/с):
sign verify sign/s verify/s
rsa 1024 bits 0.000301s 0.000018s 3326.3 56419.7
dsa 1024 bits 0.000309s 0.000236s 3236.2 4240.5
ecdsa 160 bits (secp160r1) 0.0005s 0.0004s 1984.6 2385.7
112 бит безопасности
sign verify sign/s verify/s
rsa 2048 bits 0.002030s 0.000062s 492.6 16062.4
ecdsa 224 bits (nistp224) 0.0001s 0.0002s 9020.6 4252.2
dsa 2048 bits 0.000885s 0.000802s 1129.4 1247.3
128 бит безопасности
sign verify sign/s verify/s
rsa 3072 bits 0.006935s 0.000135s 144.2 7401.6
ecdsa 256 bits (nistp256) 0.0001s 0.0002s 16901.5 5344.7
ecdsa 256 bits (brainpoolP256t1) 0.0010s 0.0008s 980.1 1262.5
ecdsa 256 bits (brainpoolP256r1) 0.0010s 0.0008s 1012.9 1209.5
dsa 3072 bits (not in test suite)
192 бита безопасности
sign verify sign/s verify/s
rsa 7680 bits 0.122805s 0.000820s 8.1 1220.2
ecdsa 384 bits (nistp384) 0.0024s 0.0018s 416.1 571.2
ecdsa 384 bits (brainpoolP384t1) 0.0024s 0.0018s 410.0 545.1
ecdsa 384 bits (brainpoolP384r1) 0.0025s 0.0019s 407.4 540.1
dsa 7680 bits (beyond FIPS 186-3 DSA maximum of 3072 bits)
256 бит безопасности
sign verify sign/s verify/s
ecdsa 521 bits (nistp521) 0.0006s 0.0012s 1563.1 841.3
ecdsa 512 bits (brainpoolP512t1) 0.0038s 0.0027s 265.2 369.1
ecdsa 512 bits (brainpoolP512r1) 0.0038s 0.0028s 262.4 360.5
rsa 15360 bits 0.783846s 0.003190s 1.3 313.5
dsa 15360 bits (beyond FIPS 186-3 DSA maximum of 3072 bits)
Я могу использовать только RSA и ECDsa в вызовах CertificateRequest. Есть ли причины, по которым DSA не включен?
Из треда с предложением исходной функции:
Основываясь на новых данных из Windows (и их отсутствии поддержки сертификатов DSA FIPS 186-3), я собираюсь вытащить типизированный конструктор DSA и оставить DSA в качестве сценария «опытного пользователя» (пользовательский класс X509SignatureGenerator и т. д.)
Итак, он был удален в основном потому, что DSA умирает.
Или я что-то пропустил в API?
API позволяет предоставлять пользовательские генераторы подписей. В тестах CertificateRequest это подтверждается с помощью DSAX509SignatureGenerator
X509SignatureGenerator dsaGen = new DSAX509SignatureGenerator(dsaCsp);
// Use SHA-1 because that's all DSACryptoServiceProvider understands.
HashAlgorithmName hashAlgorithm = HashAlgorithmName.SHA1;
CertificateRequest request = new CertificateRequest(
new X500DistinguishedName($"CN={KeyName}-{provType}"),
dsaGen.PublicKey,
hashAlgorithm);
DateTimeOffset now = DateTimeOffset.UtcNow;
using (X509Certificate2 cert = request.Create(request.SubjectName, dsaGen, now, now.AddDays(1), new byte[1]))
using (X509Certificate2 certWithPrivateKey = cert.CopyWithPrivateKey(dsaCsp))
using (DSA dsa = certWithPrivateKey.GetDSAPrivateKey())
{
byte[] signature = dsa.SignData(Array.Empty<byte>(), hashAlgorithm);
Assert.True(dsaCsp.VerifyData(Array.Empty<byte>(), signature, hashAlgorithm));
}
(фрагмент из https://github.com/dotnet/runtime/blob/4f9ae42d861fcb4be2fcd5d3d55d5f227d30e723/src/libraries/System.Security.Cryptography.X509Certificates/tests/CertificateCreation/PrivateKeyAssociationTests.cs#L2576-L257a>
person
bartonjs
schedule
20.12.2019