問題描述
我有一個導出的 RSAParameters 私鑰,我想將它導入另一臺機器.我可以將 new 密鑰保存到本地計算機或用戶容器中,但我無法嘗試導入 現有 密鑰.
I have an exported RSAParameters private key that I'd like to import into another machine. I can save new keys into the local machine or user containers, but I'm stuck trying to import an existing key.
下面的代碼將生成一個新的密鑰對,我知道我可以直接在容器中生成一個新密鑰 - 但我希望能夠生成一個密鑰并將同一個密鑰導入到少數不同的計算機中.
The code below will generate a new key pair, and I know I could just generate a new key directly into the container - but I want to be able to generate a single key and import that same key into a handful of different computers.
如何獲取 RSAParameters 或 XML 字符串(任一)并將其導入本地用戶(或機器)容器?
How can I take either an RSAParameters or a string of XML (either one) and import that into a local user (or machine) container?
public async Task<KeyGenerationResult> GenerateNewKeyAsync(int keySize)
{
var csp = new RSACng(keySize);
var privKey = await Task.Run(() => csp.ExportParameters(includePrivateParameters: true));
var pubKey = csp.ExportParameters(includePrivateParameters: false);
var pubKeyString = exportKeyToString(pubKey);
var privKeyString = exportKeyToString(privKey);
return new KeyGenerationResult
{
PrivateKey = privKey,
PublicKey = pubKey,
PrivateKeyCleartext = privKeyString,
PublicKeyCleartext = pubKeyString
};
}
private static string exportKeyToString(RSAParameters key)
{
string keyString;
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, key);
keyString = sw.ToString();
return keyString;
}
public void SavePrivateKeyToLocalMachine(RSAParameters privateKey, string keyName)
{
//Stuck here. :(
}
CngKey.Import() 需要一個字節[],這看起來很有希望,但我無法找到任何方法來創建 CngKey.Import() 所需的字節[].
CngKey.Import() takes a byte[] and that looks promising, but I haven't been able to find any method to create the byte[] that CngKey.Import() requires.
var d = new RSACryptoServiceProvider();
d.ImportParameters(privateKey);
var keyBlob = d.ExportCspBlob(true);
var key = CngKey.Import(keyBlob, CngKeyBlobFormat.Pkcs8PrivateBlob);
這給了我一個字節[],但無論我使用什么 CngKeyBlobFormat,我都會遇到異常.我被卡住了.
That gets me a byte[] but regardless of what CngKeyBlobFormat I use, I get an exception. I'm stuck.
更新
我找到了一種使用
var cp = new CngKeyCreationParameters();
cp.KeyUsage = CngKeyUsages.AllUsages;
cp.ExportPolicy = CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowExport | CngExportPolicies.AllowArchiving | CngExportPolicies.AllowPlaintextArchiving;
cp.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None));
var key = CngKey.Create(CngAlgorithm.Rsa, null, cp);
var bytes = key.Export(CngKeyBlobFormat.{I have tried them all});
這段代碼看起來像它應該讓我導入字節[]
And this code looks like it should let me import the byte[]
/* try to save this key to the local user container */
var keyParameters = new CngKeyCreationParameters()
{
KeyCreationOptions = CngKeyCreationOptions.OverwriteExistingKey,
Provider = CngProvider.MicrosoftSoftwareKeyStorageProvider,
KeyUsage = CngKeyUsages.AllUsages,
ExportPolicy = CngExportPolicies.AllowPlaintextExport
};
keyParameters.KeyCreationOptions = CngKeyCreationOptions.None;
keyParameters.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None));
keyParameters.Parameters.Add(new CngProperty(blobType.Format, bytes, CngPropertyOptions.None));
var newKey = CngKey.Create(CngAlgorithm.Rsa, "MyTestName", keyParameters);
...但再一次,沒有骰子.我嘗試什么 CngKeyBlobFormat 都沒關系,它們都給了我例外,我無法將密鑰導入本地密鑰存儲提供程序.
...but once again, no dice. It doesn't matter what CngKeyBlobFormat I try, they all give me exceptions and I'm unable to import the key into a local key storage provider.
我需要什么神奇的設置和參數組合才能完成這項工作?
What magic mix of settings and parameters do I need to make this work?
推薦答案
好吧,我終于搞定了.這是最終穩定下來的代碼.
Well, I finally got it working. Here's the code as it finally settled down.
public class KeyGenerationResult
{
public RSAParameters PublicKey { get; set; }
public string PublicKeyCleartext { get; set; }
public string PrivateKeyCleartext { get; set; }
public byte[] PrivateBytes { get; set; }
public int KeySize { get; set; }
public CngKeyBlobFormat BlobFormat { get; set; }
}
public async Task<KeyGenerationResult> GenerateNewKeyAsync(int keySize)
{
var cp = new CngKeyCreationParameters();
cp.KeyUsage = CngKeyUsages.AllUsages;
cp.ExportPolicy = CngExportPolicies.AllowPlaintextExport | CngExportPolicies.AllowExport | CngExportPolicies.AllowArchiving | CngExportPolicies.AllowPlaintextArchiving;
cp.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(keySize), CngPropertyOptions.None));
var key = await Task.Run(() => CngKey.Create(CngAlgorithm.Rsa, null, cp)).ConfigureAwait(false);
var blobType = CngKeyBlobFormat.GenericPrivateBlob;
var bytes = await Task.Run(() => key.Export(blobType)).ConfigureAwait(false);
var rsa = new RSACng(key);
var pubKey = rsa.ExportParameters(includePrivateParameters: false);
var pubKeyString = exportKeyToString(pubKey);
return new KeyGenerationResult
{
PublicKey = pubKey,
PrivateKeyCleartext = Convert.ToBase64String(bytes),
PublicKeyCleartext = pubKeyString,
PrivateBytes = bytes,
BlobFormat = blobType,
KeySize = keySize
};
}
private static string exportKeyToString(RSAParameters key)
{
string keyString;
var sw = new StringWriter();
var xs = new XmlSerializer(typeof(RSAParameters));
xs.Serialize(sw, key);
keyString = sw.ToString();
return keyString;
}
public void SavePrivateKeyToLocalMachine(KeyGenerationResult keyData, string keyName)
{
var myKSP = CngProvider.MicrosoftSoftwareKeyStorageProvider;
const bool MachineKey = false;
if (!CngKey.Exists(keyName, myKSP))
{
var keyParams = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = (MachineKey) ? CngKeyCreationOptions.MachineKey : CngKeyCreationOptions.None,
Provider = myKSP
};
keyParams.Parameters.Add(new CngProperty("Length", BitConverter.GetBytes(keyData.KeySize), CngPropertyOptions.None));
keyParams.Parameters.Add(new CngProperty(keyData.BlobFormat.Format, keyData.PrivateBytes, CngPropertyOptions.None));
CngKey.Create(CngAlgorithm.Rsa, keyName, keyParams);
}
else
{
throw new CryptographicException($"The key with the name '{keyName}' already exists!");
}
}
這篇關于導入 RSA CngKey 并存儲在 MicrosoftSoftwareKeyStorageProvider 中的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!