You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hey!
Stumbled upon your library in some code, used to validate RSA private keys.
However, I've found that some cases where the parameter is starting with 00 byte the library would remove it, leaving the PEM it parsed not readable.
Interestingly enough, this happens only on windows, failed to reproduce on linux. I assume it's something with how the windows implementation of RSA in dotnet behaves creating values that may start with a 1 bit, requiring to pad the value with 00 byte.
I also might be missing something (possibly 😄)
The code creates a RSA pair, exports it to a PEM, tries to decode it with the library. If the decoding fails I print the following outputs:
the RSAParameters the library decoded
the RSAParameters from the originally created rsa pair
the RSAParameters from a version of RSA importing the same PEM that failed with the library.
here is some C# code that replicates it every time on windows.
Edit: I'm running on net9 and net6, on windows it reproduces quite constantly. On linux not once... maybe a difference between bcrypt and openssl?
usingSystem.Security.Cryptography;usingOpenSSL.PrivateKeyDecoder;for(inti=0;i<200;i++){varrsa=RSA.Create(512);varcert=rsa.ExportRSAPrivateKeyPem();vardecoder=newOpenSSLPrivateKeyDecoder();try{vardecoded=decoder.Decode(cert,null);}catch{Console.WriteLine(cert);PrintLineSeparator();Console.WriteLine("OpenSSLPrivateKeyDecoder:");varparameters=decoder.DecodeParameters(cert);Dump(parameters);PrintLineSeparator();Console.WriteLine("dotnet original:");Dump(rsa.ExportParameters(true));PrintLineSeparator();Console.WriteLine("dotnet reimport:");varrsa2=RSA.Create();rsa2.ImportFromPem(cert);varreimported=rsa2.ExportParameters(true);Dump(reimported);PrintLineSeparator();CompareRSAParameters(parameters,reimported);break;}}voidDump(RSAParametersparameters){Console.WriteLine($"D: {BitConverter.ToString(parameters.D!)}");Console.WriteLine($"DP: {BitConverter.ToString(parameters.DP!)}");Console.WriteLine($"DQ: {BitConverter.ToString(parameters.DQ!)}");Console.WriteLine($"EX: {BitConverter.ToString(parameters.Exponent!)}");Console.WriteLine($"IQ: {BitConverter.ToString(parameters.InverseQ!)}");Console.WriteLine($"M: {BitConverter.ToString(parameters.Modulus!)}");Console.WriteLine($"P: {BitConverter.ToString(parameters.P!)}");Console.WriteLine($"Q: {BitConverter.ToString(parameters.Q!)}");}boolCompareRSAParameters(RSAParametersleft,RSAParametersright){returnCompareByteArrays(left.D,right.D,"D")||CompareByteArrays(left.DP,right.DP,"DP")||CompareByteArrays(left.DQ,right.DQ,"DQ")||CompareByteArrays(left.Exponent,right.Exponent,"Exponent")||CompareByteArrays(left.InverseQ,right.InverseQ,"InverseQ")||CompareByteArrays(left.Modulus,right.Modulus,"Modulus")||CompareByteArrays(left.P,right.P,"P")||CompareByteArrays(left.Q,right.Q,"Q");}boolCompareByteArrays(byte[]?left,byte[]?right,stringtitle){if(left==null||right==null){Console.WriteLine("One or both byte arrays are null.");returnfalse;}intminLength=Math.Min(left.Length,right.Length);booldifferenceFound=false;for(inti=0;i<minLength;i++){if(left[i]!=right[i]){Console.WriteLine($"field diff: "+title);Console.WriteLine($"left: {BitConverter.ToString(left)}");Console.ForegroundColor=ConsoleColor.Red;Console.WriteLine(" "+newstring(' ',i*3)+"\\/");Console.WriteLine(" "+newstring(' ',i*3)+"||");Console.WriteLine(" "+newstring(' ',i*3)+"\\/");Console.ResetColor();Console.WriteLine($"right: {BitConverter.ToString(right)}");differenceFound=true;break;}}if(left.Length!=right.Length){Console.WriteLine($"length diff for array: "+title);if(!differenceFound){Console.WriteLine("left: "+BitConverter.ToString(left));Console.WriteLine("right: "+BitConverter.ToString(right));}Console.WriteLine("Arrays have different lengths.");Console.WriteLine($"{nameof(left)} Length: {left.Length}");Console.WriteLine($"{nameof(right)} Length: {right.Length}");differenceFound=true;}returndifferenceFound;}staticvoidPrintLineSeparator(){Console.WriteLine();Console.WriteLine("================================================");Console.WriteLine();}
what are your thoughts on the matter?
The text was updated successfully, but these errors were encountered:
@EugeneKrapivin
Actually, I don't have enough knowledge to assess your statements.
If you think you are correct and the code needs a fix, you can make a PR and maybe introduce a feature flag in order to not break previous functionality?
Hey!
Stumbled upon your library in some code, used to validate RSA private keys.
However, I've found that some cases where the parameter is starting with
00
byte the library would remove it, leaving the PEM it parsed not readable.Interestingly enough, this happens only on windows, failed to reproduce on linux. I assume it's something with how the windows implementation of
RSA
in dotnet behaves creating values that may start with a 1 bit, requiring to pad the value with00
byte.I also might be missing something (possibly 😄)
The code creates a
RSA
pair, exports it to aPEM
, tries to decode it with the library. If the decoding fails I print the following outputs:RSAParameters
the library decodedRSAParameters
from the originally createdrsa
pairRSAParameters
from a version ofRSA
importing the samePEM
that failed with the library.here is some C# code that replicates it every time on windows.
Edit: I'm running on net9 and net6, on windows it reproduces quite constantly. On linux not once... maybe a difference between bcrypt and openssl?
what are your thoughts on the matter?
The text was updated successfully, but these errors were encountered: