We have a C#/.Net 4.0 application which imports RSA Private Keys from a String in Base64 received in a WebService.
This application works perfectly for RSA-Keys in 1024 bits, but doesn't with a special kind of rsa private keys (around 1% of keys).
Here are the byte lengths:
Working-Key:
- Modulus => 128 Bytes
- Exponent => 3 Bytes
- D => 128 Bytes
- P => 64 Bytes
- Q => 64 Bytes
- DP => 64 Bytes
- DQ => 64 Bytes
- IQ => 64 Bytes
Not-Working-Key:
- Modulus => 128 Bytes
- Exponent => 3 Bytes
- D => 127 Bytes
- P => 64 Bytes
- Q => 64 Bytes
- DP => 64 Bytes
- DQ => 64 Bytes
- IQ => 64 Bytes
The difference is in the lenght of D (128 working, 127 not working). The not-working key is 1 byte shorter than the working key.
The parameters are set but when doing RSA.ImportParameters(rsaParams) it throws a CryptographicException with a "Bad Data" Message.
What should be included to solve this problem?
RSACryptoServiceProvider
has some assumptions on the data lengths which are:n
<= 4
bytes; though RSACng allows "any size"), let's call the lengthe
n
n/2
n/2
n/2
n/2
n/2
So, assuming that your second key is actually Modulus: 128 bytes (because a 64-byte P times a 64-byte Q isn't a 256 byte number), you just need to left-pad the D array with a zero to bring it up to the proper length.
.NET Core has the source code available showing that relationship. In .NET Framework it's buried inside the CLR, so not available on referencesource.