-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Estimated signature size calculation for ECDsa and RSA may be incorrect #67059
Comments
Tagging subscribers to this area: @dotnet/area-system-security, @vcsjones Issue DetailsBased on recent discussions with @bartonjs where I needed to also obtain an estimated size. As per Jeremy, ECDsa should use What is currently being used is this: runtime/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.SignVerify.cs Lines 21 to 29 in ea4ebaa
and this: runtime/src/libraries/Common/src/System/Security/Cryptography/RSACng.SignVerify.cs Line 62 in ea4ebaa
For ECDsa and RSA respectively. It is not a bug as the code handles the case where the signature buffer wasn't big enough but I think we should be consistent on how to calculate it, maybe even consider adding a
|
The difference is actually just the rounding. For common key sizes that's not going to be a problem since they happen to round up nicely, or they are already special cased in ECDsa (521). |
I could see the utility in that. I would probably do something more along the lines of: namespace System.Security.Cryptography {
public partial class ECDsa {
public int GetMaxSignatureSize(DSASignatureFormat signatureFormat);
}
public partial class DSA {
public int GetMaxSignatureSize(DSASignatureFormat signatureFormat);
}
public partial class RSA {
public int GetMaxSignatureSize();
}
} The |
Yeah, we use those calculations all over the place. Making there be methods seems reasonable. |
I made the logical leap to public methods, thus an API proposal, but maybe that wasn't intended. Though, I do think that these methods would be handy with |
Adding them as public API, and also adding the non-Try versions of the Span-writing methods, seems good. Since RSA has always had a key-sized output, I don't think For the -DSA types we could also add a non-Max version like |
I'm going to change my suggestion to |
Yeah, I just liked everything having a neat name.
Hm. If we had In that sense then, the proposal looks like: namespace System.Security.Cryptography {
public partial class ECDsa {
public int GetMaxSignatureSize(DSASignatureFormat signatureFormat);
public int GetSignatureSizeIeeeP1363();
}
} Okay, but that is a little weird to have one dedicated to IEEEP1363 and another one for namespace System.Security.Cryptography {
public partial class ECDsa {
public int GetMaxSignatureSizeRfc3279();
public int GetSignatureSizeIeeeP1363();
}
} Well, that works but maybe it's a bit odd that we have the enum and don't use it. If a caller had a The API shape I had in mind was: public void SignMyStuff(DSASignatureFormat format, ReadOnlySpan<byte> data) {
ECDsa ecdsa = ECDsa.Create();
// Set up ecdsa
byte[] rented = ArrayPool<byte>.Shared.Rent(ecdsa.GetMaxSignatureSize(format));
bool didItWork = ecdsa.TrySign(data, rented, HashAlgorithmName.SHA256, format, out int written);
Debug.Assert(didItWork);
ReadOnlySpan<byte> signature = rented.AsSpan(0, written);
// Do something with signature
ArrayPool<byte>.Shared.Return(rented, true);
} While I see the utility in knowing exactly how big a signature is (if we can) I envisioned these further as something to say "You need a buffer that is X bytes in size". If folks are using If they are using If they want a Granted, it's only the case of DER DSA signatures that we don't know the absolute size. |
The reason, to me, for having the P1363 size method is that it's a) simpler and b) matches the Sign/Verify that don't take the format parameter. If we wanted to pretend we didn't have X509Der support yet then it'd just be I do like the one that takes the format, for the reason you pointed out... if you took the format as a parameter you don't want to have to switch on it yourself. |
Yeah. But now to talk myself out of it... that's probably only useful to library / framework authors. Consumers of the APIs will want one format or another. So if library authors (.NET Libraries) need to do a little switching for a better APIs suited for application developers, that makes sense to me. Okay. So something like namespace System.Security.Cryptography {
public partial class ECDsa {
public int GetMaxSignatureSizeRfc3279();
public int GetSignatureSizeIeeeP1363();
}
public partial class DSA {
public int GetMaxSignatureSizeRfc3279();
public int GetSignatureSizeIeeeP1363();
}
public partial class RSA {
public int GetSignatureSize();
}
} |
Oh, huh. This API already exists. https://apisof.net/catalog/30126e10-f818-2b5c-0b80-7e7787f3a4d9 |
So we're just missing |
Seems so. |
Based on recent discussions with @bartonjs where I needed to also obtain an estimated size. As per Jeremy, ECDsa should use
2 * ((KeySize + 7) / 8)
and for RSA(KeySize + 7) / 8
.What is currently being used is this:
runtime/src/libraries/Common/src/System/Security/Cryptography/ECDsaCng.SignVerify.cs
Lines 21 to 29 in ea4ebaa
and this:
runtime/src/libraries/Common/src/System/Security/Cryptography/RSACng.SignVerify.cs
Line 62 in ea4ebaa
For ECDsa and RSA respectively.
It is not a bug as the code handles the case where the signature buffer wasn't big enough but I think we should be consistent on how to calculate it, maybe even consider adding a
GetSignatureSize()
API.The text was updated successfully, but these errors were encountered: