Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CryptographicException in RSA.ImportParameters() - Bad Data in special 1024 keys

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?

like image 823
user1084509 Avatar asked Sep 06 '25 03:09

user1084509


1 Answers

RSACryptoServiceProvider has some assumptions on the data lengths which are:

  • Modulus: any even size, let's call the length n
  • Exponent: (<= 4 bytes; though RSACng allows "any size"), let's call the length e
  • D: n
  • P: n/2
  • Q: n/2
  • DP: n/2
  • DQ: n/2
  • InverseQ: 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.

byte[] newD = new byte[modulus.Length];
Buffer.BlockCopy(d, 0, newD, newD.Length - d.Length, d.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.

like image 163
bartonjs Avatar answered Sep 09 '25 21:09

bartonjs