I recently had to move an internal tooling library from .NET Core 3.0 to 2.1. In doing so I encountered that RSA.ImportPkcs8PrivateKey()
vanished; unfortunately, I needed that method.
I went looking (admittedly briefly) for alternative methods that didn't involve third-party libraries, but didn't find much (best Google was this unanswered SO post).
I decided to stick my hand in the fire and risk a burn for an interim fix. I wrote the below (disclaimer: abridged/untested form of working solution) to reflect into some of the 2.1 internal types/methods and achieve the same results of RSA.ImportPkcs8PrivateKey()
.
I'm curious if anyone has a better (and less risky) solve? The constraints I'm working under are
- framework .NET Core 2.1
- no external libraries
- no custom PKCS parsing code
- resultant type is System.Security.Cryptography.RSA
- Input is a PKCS#8 private key in PEM format. The below code requires pre-call conversion from PEM to DER.
-----BEGIN PRIVATE KEY-----
MIIEvAIBAD...wHi59v+A==
-----END PRIVATE KEY-----
I'm guessing I've missed some lesser known method or perhaps an indirect route via an intermediate transformation (I've seen refs to going via PKCS#11)? If not, then here's a small contribution to lightening my massive SO debt.
Thanks all for saving my bacon over the years!
public static void ImportPkcs8PrivateKey(this RSA rsa, ReadOnlySpan<byte> source, out int bytesRead)
{
var assembly = typeof(RSA).Assembly;
var derSequenceReader = assembly.GetType("System.Security.Cryptography.DerSequenceReader", true);
var readerArgs = new[] { source.ToArray() };
var reader = Activator.CreateInstance(
derSequenceReader,
BindingFlags.Instance | BindingFlags.NonPublic,
null, readerArgs, null);
var helperType = assembly.GetType("System.Security.Cryptography.RsaKeyBlobHelpers", true);
var readPkcs8Blob = helperType.GetMethod(
"ReadPkcs8Blob",
BindingFlags.Static | BindingFlags.NonPublic);
var methodArgs = new[] { reader, new RSAParameters() };
readPkcs8Blob.Invoke(reader, methodArgs);
// ReadPkcs8Blob() takes an RSAParameterr object as a 'ref'.
var parameters = (RSAParameters)methodArgs[1];
rsa.ImportParameters(parameters);
}
question from:
https://stackoverflow.com/questions/66054507/whats-a-better-method-of-importing-pkcs8-private-keys-in-net-core-2-1 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…