如何从 .Net Core 中包含私有/Public 密钥的 PEM 文件导入 PKCS1 密钥
How to import PKCS1 keys from a PEM file containing Private / Public keys in .Net Core
我正在尝试使用 .Net Core 从 PEM 文件加载私有密钥和 Public 密钥。
我的代码如下所示:
var localPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var path = Path.Combine(localPath, this._configManager.JwtPem);
var rsaCryptoServiceProvider = new RSACryptoServiceProvider();
var linesList = File.ReadAllLines(path).ToList();
var line = string.Concat(linesList.GetRange(1, linesList.Count - 2));
rsaCryptoServiceProvider.ImportCspBlob(Convert.FromBase64String(line));
我遇到的异常是:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException : Bad Version of provider
at Internal.NativeCrypto.CapiHelper.ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, Boolean addNoSaltFlag, Byte[] keyBlob, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.ImportCspBlob(Byte[] keyBlob)
at StepNexusCA.ServiceLayer.Authorization.TokenService.GenerateToken(List`1 claims)
包含我开发的 Private/Public 密钥的 PKCS1 格式的 PEM 文件在这里:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwgs8kmIwk+4geRO7dGZjzYpgD2OiaUrnOOIk+ObXt/CcjhwX
lSst+jBmfMF1Wp/mF4aUQsePxN59MYV2BsqPLEkzVdq/fb/7V2wbZcooJAQKkJwT
emtYHrBN00KBBeu9uQZlFOw365ij4GrbP7mcr4tNFZ3TPnRFUUFqhvB6mEG1aZsb
lOn1lgL34tAycQHNxttXz/aGfPyTefQ+yISvSY2n8288OVlyfu6wKDONQYS+/stC
tCV+a+/dDUSUjaZsXM1+BMSflsINqIcCTCMvPa6fb5Z+USfPDcDNwzUyX20LBzH5
wFwPLIvuoqJeeczcaHaT+dS2ZZREj6kgUsdC+QIBAwKCAQEAgVzTDEF1t/QVpg0n
ou7tM7GVX5fBm4dE0JbDUJnlJUsTCWgPuMdz/CBEUyujkb/uulm4LIUKgz7+IQOk
BIcKHYYiOTx/qSqnj51nmTFwGAKxtb1iUZzlacrejNcArp0pJgRDY0glR7sX6vHn
f9ETH7IzY76M1E2Di4Dxr0r8ZX/3ozsrSXp+GMJLeN9sCjKSyxoE5Y71eDBTCX2N
tShJJjhqUDz61bhKlX9j5c3jWvTXx46dE8wjoJ/BW1XJo5J1gzHQ/OLYeOXIdxlj
jVSlEuU69UT588B7UEEK9N9xK5K/c0Yw5gd02RUv/o7qdpYQICeGtQMMaFkm75xy
nUOxwwKBgQD/orUvgNJfFKyvGY8XJTuek5q8IcFD8AFO3b7pNnPynw8llyEpACAv
Onf9aJSPZvtrabSqrpO8k8Ijyhe2Ino39GuRV8RURl46GmFN31RoYV1wHI4K7Emh
68cdKbCEBudog+kImImldBAfo+QmBtqhS+u4B5qQwwnFa8DriQoiYwKBgQDCUg0r
Jd/ZXDLXk/H5PHpTApmUVd7SWLLIDfkBAlRO8Sni4/Ka+KTTZDec5uoo0hoP6cCs
Z9+MZz4XOiwv9dCEI5czMawGmwsm23+fGM/PP/lW4yD8dz10KZggKjWElymDVl+n
zsc6ctwHAOfYwREi7E+R4rWTBgTEvH2I3deV8wKBgQCqbHjKVeGUuHMfZl9kw30U
YmcoFoDX9VY0k9SbeaKhv19uZMDGABV00aVTmw2071JHm83HHw0oYoFtMWUkFvwl
TZ0Lj9g4Lul8EZYz6jhFlj5KvbQHSDEWnS9oxnWtWe+bAptbEFvDorVqbULEBJHA
3UfQBRG111vY8oCdBgbBlwKBgQCBjAjHbpU7ksyPt/amKFGMrGZi4+nhkHcwCVCr
VuLfS3FB7UxnUG3iQs+970bF4Wa1RoBy7+pdmilk0XLKo+BYF7oiIR1ZvLIZ56pq
EIqKKqY57MCoT35NcRAVcXkDD3ECOZUaidom9z1aAJqQgLYXSDUL7HkMrq3YfakF
6Tpj9wKBgEPCSW7EMFjK2NzmB+4b+skxXcfCZ0ldNtwoUDijuAMFg8ueC3j2qFUX
bAXSApi3mQMow1/JwQxiZ+b+GDLdTcE/PrBVBRkL/5RkmnVagbjBrdZhVjpC+dUo
eEkCChClGGpRyPJ+DYYRyX1Fk9Und8Xbd49Vv+/6RL76ys3gGQl8
-----END RSA PRIVATE KEY-----
为什么我不能使用 ImportCspBlob(...) 导入密钥?我没有在网上找到太多关于异常的信息,但我的代码哪里错了?我知道 BouncyCastle,但我正在尝试使用 .Net Core 本机执行此操作。
ImportCspBlob 的格式是 ExportCspBlob 的格式,这是 CryptImportKey 要求的 PRIVATEKEY blob 格式。由于 .NET 只是透明地将其传递给 Windows CAPI,ImportCspBlob 方法会在非 Windows 平台上抛出。
我过去为导入私钥(包括 PKCS#1 RSAPrivateKey)给出的另一个答案有点像元答案,其中包含使事情正常运行的链接:Digital signature in c# without using BouncyCastle。
.NET Core 3.0 的每日构建版本内置了该功能。大多。 PEM 格式在实践中很容易,但在规范中有些烦人,因此这些方法将其留给调用者 "un-PEM" 数据...对于没有属性的单值有效负载的默认格式(如你在你的例子中)你可以通过
每天构建
private static RSA ReadKeyFromFile(string filename)
{
string pemContents = System.IO.File.ReadAllText(filename);
const string RsaPrivateKeyHeader = "-----BEGIN RSA PRIVATE KEY-----";
const string RsaPrivateKeyFooter = "-----END RSA PRIVATE KEY-----";
if (pemContents.StartsWith(RsaPrivateKeyHeader))
{
int endIdx = pemContents.IndexOf(
RsaPrivateKeyFooter,
RsaPrivateKeyHeader.Length,
StringComparison.Ordinal);
string base64 = pemContents.Substring(
RsaPrivateKeyHeader.Length,
endIdx - RsaPrivateKeyHeader.Length);
byte[] der = Convert.FromBase64String(base64);
RSA rsa = RSA.Create();
rsa.ImportRSAPrivateKey(der, out _);
return rsa;
}
// "BEGIN PRIVATE KEY" (ImportPkcs8PrivateKey),
// "BEGIN ENCRYPTED PRIVATE KEY" (ImportEncryptedPkcs8PrivateKey),
// "BEGIN PUBLIC KEY" (ImportSubjectPublicKeyInfo),
// "BEGIN RSA PUBLIC KEY" (ImportRSAPublicKey)
// could any/all be handled here.
throw new InvalidOperationException();
}
可以从 https://github.com/dotnet/core-sdk/#installers-and-binaries
获取 .NET Core SDK 的每日构建
如果代码中不需要PEM转DER,可以使用openssl获取DER编码的私钥文件:
openssl rsa -in key.pem -out key.der -outform der
.Net Cryptographic API 不支持业界广泛使用的 PEM 文件,因此我们需要将其转换为 Microsoft 推出的 XML 格式。基本上,解决方案是在 C# Extract public key from RSA PEM private key.
的另一个类似问题中找到的
有很多将 PEM 转换为 XML 的在线工具,只需将您的 pem 转换为 xml,然后
RSA.FromXmlString(string xmlString)
我正在尝试使用 .Net Core 从 PEM 文件加载私有密钥和 Public 密钥。 我的代码如下所示:
var localPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var path = Path.Combine(localPath, this._configManager.JwtPem);
var rsaCryptoServiceProvider = new RSACryptoServiceProvider();
var linesList = File.ReadAllLines(path).ToList();
var line = string.Concat(linesList.GetRange(1, linesList.Count - 2));
rsaCryptoServiceProvider.ImportCspBlob(Convert.FromBase64String(line));
我遇到的异常是:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException : Bad Version of provider
at Internal.NativeCrypto.CapiHelper.ImportKeyBlob(SafeProvHandle saveProvHandle, CspProviderFlags flags, Boolean addNoSaltFlag, Byte[] keyBlob, SafeKeyHandle& safeKeyHandle)
at System.Security.Cryptography.RSACryptoServiceProvider.ImportCspBlob(Byte[] keyBlob)
at StepNexusCA.ServiceLayer.Authorization.TokenService.GenerateToken(List`1 claims)
包含我开发的 Private/Public 密钥的 PKCS1 格式的 PEM 文件在这里:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAwgs8kmIwk+4geRO7dGZjzYpgD2OiaUrnOOIk+ObXt/CcjhwX
lSst+jBmfMF1Wp/mF4aUQsePxN59MYV2BsqPLEkzVdq/fb/7V2wbZcooJAQKkJwT
emtYHrBN00KBBeu9uQZlFOw365ij4GrbP7mcr4tNFZ3TPnRFUUFqhvB6mEG1aZsb
lOn1lgL34tAycQHNxttXz/aGfPyTefQ+yISvSY2n8288OVlyfu6wKDONQYS+/stC
tCV+a+/dDUSUjaZsXM1+BMSflsINqIcCTCMvPa6fb5Z+USfPDcDNwzUyX20LBzH5
wFwPLIvuoqJeeczcaHaT+dS2ZZREj6kgUsdC+QIBAwKCAQEAgVzTDEF1t/QVpg0n
ou7tM7GVX5fBm4dE0JbDUJnlJUsTCWgPuMdz/CBEUyujkb/uulm4LIUKgz7+IQOk
BIcKHYYiOTx/qSqnj51nmTFwGAKxtb1iUZzlacrejNcArp0pJgRDY0glR7sX6vHn
f9ETH7IzY76M1E2Di4Dxr0r8ZX/3ozsrSXp+GMJLeN9sCjKSyxoE5Y71eDBTCX2N
tShJJjhqUDz61bhKlX9j5c3jWvTXx46dE8wjoJ/BW1XJo5J1gzHQ/OLYeOXIdxlj
jVSlEuU69UT588B7UEEK9N9xK5K/c0Yw5gd02RUv/o7qdpYQICeGtQMMaFkm75xy
nUOxwwKBgQD/orUvgNJfFKyvGY8XJTuek5q8IcFD8AFO3b7pNnPynw8llyEpACAv
Onf9aJSPZvtrabSqrpO8k8Ijyhe2Ino39GuRV8RURl46GmFN31RoYV1wHI4K7Emh
68cdKbCEBudog+kImImldBAfo+QmBtqhS+u4B5qQwwnFa8DriQoiYwKBgQDCUg0r
Jd/ZXDLXk/H5PHpTApmUVd7SWLLIDfkBAlRO8Sni4/Ka+KTTZDec5uoo0hoP6cCs
Z9+MZz4XOiwv9dCEI5czMawGmwsm23+fGM/PP/lW4yD8dz10KZggKjWElymDVl+n
zsc6ctwHAOfYwREi7E+R4rWTBgTEvH2I3deV8wKBgQCqbHjKVeGUuHMfZl9kw30U
YmcoFoDX9VY0k9SbeaKhv19uZMDGABV00aVTmw2071JHm83HHw0oYoFtMWUkFvwl
TZ0Lj9g4Lul8EZYz6jhFlj5KvbQHSDEWnS9oxnWtWe+bAptbEFvDorVqbULEBJHA
3UfQBRG111vY8oCdBgbBlwKBgQCBjAjHbpU7ksyPt/amKFGMrGZi4+nhkHcwCVCr
VuLfS3FB7UxnUG3iQs+970bF4Wa1RoBy7+pdmilk0XLKo+BYF7oiIR1ZvLIZ56pq
EIqKKqY57MCoT35NcRAVcXkDD3ECOZUaidom9z1aAJqQgLYXSDUL7HkMrq3YfakF
6Tpj9wKBgEPCSW7EMFjK2NzmB+4b+skxXcfCZ0ldNtwoUDijuAMFg8ueC3j2qFUX
bAXSApi3mQMow1/JwQxiZ+b+GDLdTcE/PrBVBRkL/5RkmnVagbjBrdZhVjpC+dUo
eEkCChClGGpRyPJ+DYYRyX1Fk9Und8Xbd49Vv+/6RL76ys3gGQl8
-----END RSA PRIVATE KEY-----
为什么我不能使用 ImportCspBlob(...) 导入密钥?我没有在网上找到太多关于异常的信息,但我的代码哪里错了?我知道 BouncyCastle,但我正在尝试使用 .Net Core 本机执行此操作。
ImportCspBlob 的格式是 ExportCspBlob 的格式,这是 CryptImportKey 要求的 PRIVATEKEY blob 格式。由于 .NET 只是透明地将其传递给 Windows CAPI,ImportCspBlob 方法会在非 Windows 平台上抛出。
我过去为导入私钥(包括 PKCS#1 RSAPrivateKey)给出的另一个答案有点像元答案,其中包含使事情正常运行的链接:Digital signature in c# without using BouncyCastle。
.NET Core 3.0 的每日构建版本内置了该功能。大多。 PEM 格式在实践中很容易,但在规范中有些烦人,因此这些方法将其留给调用者 "un-PEM" 数据...对于没有属性的单值有效负载的默认格式(如你在你的例子中)你可以通过
每天构建private static RSA ReadKeyFromFile(string filename)
{
string pemContents = System.IO.File.ReadAllText(filename);
const string RsaPrivateKeyHeader = "-----BEGIN RSA PRIVATE KEY-----";
const string RsaPrivateKeyFooter = "-----END RSA PRIVATE KEY-----";
if (pemContents.StartsWith(RsaPrivateKeyHeader))
{
int endIdx = pemContents.IndexOf(
RsaPrivateKeyFooter,
RsaPrivateKeyHeader.Length,
StringComparison.Ordinal);
string base64 = pemContents.Substring(
RsaPrivateKeyHeader.Length,
endIdx - RsaPrivateKeyHeader.Length);
byte[] der = Convert.FromBase64String(base64);
RSA rsa = RSA.Create();
rsa.ImportRSAPrivateKey(der, out _);
return rsa;
}
// "BEGIN PRIVATE KEY" (ImportPkcs8PrivateKey),
// "BEGIN ENCRYPTED PRIVATE KEY" (ImportEncryptedPkcs8PrivateKey),
// "BEGIN PUBLIC KEY" (ImportSubjectPublicKeyInfo),
// "BEGIN RSA PUBLIC KEY" (ImportRSAPublicKey)
// could any/all be handled here.
throw new InvalidOperationException();
}
可以从 https://github.com/dotnet/core-sdk/#installers-and-binaries
获取 .NET Core SDK 的每日构建如果代码中不需要PEM转DER,可以使用openssl获取DER编码的私钥文件:
openssl rsa -in key.pem -out key.der -outform der
.Net Cryptographic API 不支持业界广泛使用的 PEM 文件,因此我们需要将其转换为 Microsoft 推出的 XML 格式。基本上,解决方案是在 C# Extract public key from RSA PEM private key.
的另一个类似问题中找到的有很多将 PEM 转换为 XML 的在线工具,只需将您的 pem 转换为 xml,然后
RSA.FromXmlString(string xmlString)