Ich fühle mich wie das, was ich versuche, ist sehr einfach. Aber aus irgendeinem Grunde nicht will, dass es nicht arbeiten:RSA Encryption öffentlicher Schlüssel nicht aus dem Container zurückgegeben?
Dies ist der komplette Code-Schnipsel zu testen, was ich zu tun versucht:
using System;
using System.Xml;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
namespace XmlCryptographySendingTest
{
class Program
{
static void Main(string[] args)
{
string fullKeyContainer = "fullKeyContainer";
string publicKeyContainer = "publicKeyContainer";
//create the two providers
RSACryptoServiceProvider serverRSA = GetKeyFromContainer(fullKeyContainer);
//save public and full key pairs
SaveKeyToContainer(fullKeyContainer, serverRSA.ExportParameters(true));
SaveKeyToContainer(publicKeyContainer, serverRSA.ExportParameters(false));
//get rid of them from memory
serverRSA.Clear();
serverRSA = null;
GC.Collect();
//retrieve a full server set and a private client set
serverRSA = GetKeyFromContainer(fullKeyContainer);
RSACryptoServiceProvider clientRSA = GetKeyFromContainer(publicKeyContainer);
//at this point the public key should be the same for both RSA providers
string clientPublicKey = clientRSA.ToXmlString(false);
string serverPublicKey = serverRSA.ToXmlString(false);
if (clientPublicKey.Equals(serverPublicKey))
{//they have the same public key.
// Create an XmlDocument object.
XmlDocument xmlDoc = new XmlDocument();
// Load an XML file into the XmlDocument object.
try
{
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("test.xml");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
//we can encypt with the clientRSA using the public key
Encrypt(xmlDoc, "Fields", "DataFields", clientRSA, "test");
Console.WriteLine("Encrypted: \r\n" + xmlDoc.OuterXml);
//and should be able to decrypt with the serverRSA using the private key
Decrypt(xmlDoc, serverRSA, "test");
Console.WriteLine("Decrypted : \r\n" + xmlDoc.OuterXml);
}
else
{
Console.WriteLine("The two RSA have different public keys...");
}
Console.ReadLine();
}
private static CspParameters GetCspParameters(string containerName)
{
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters tmpParameters = new CspParameters();
tmpParameters.Flags = CspProviderFlags.UseMachineKeyStore; //use the machine key store--this allows us to use the machine level container when applications run without a logged-in user
tmpParameters.ProviderType = 1;
tmpParameters.KeyNumber = (int)KeyNumber.Exchange;
tmpParameters.KeyContainerName = containerName;
return tmpParameters;
}
public static void SaveKeyToContainer(string containerName, RSAParameters rsaParameters)
{
CspParameters tmpParameters = GetCspParameters(containerName);
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(tmpParameters);
//set the key information from the text
rsa.ImportParameters(rsaParameters);
}
public static RSACryptoServiceProvider GetKeyFromContainer(string containerName)
{
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters tmpParameters = GetCspParameters(containerName);
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(tmpParameters);
return rsa;
}
public static void DeleteKeyFromContainer(string containerName)
{
// Create the CspParameters object and set the key container
// name used to store the RSA key pair.
CspParameters tmpParameters = GetCspParameters(containerName);
// Create a new instance of RSACryptoServiceProvider that accesses
// the key container.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(tmpParameters);
// Delete the key entry in the container.
rsa.PersistKeyInCsp = false;
// Call Clear to release resources and delete the key from the container.
rsa.Clear();
}
public static void Encrypt(XmlDocument Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (ElementToEncrypt == null)
throw new ArgumentNullException("ElementToEncrypt");
if (EncryptionElementID == null)
throw new ArgumentNullException("EncryptionElementID");
if (Alg == null)
throw new ArgumentNullException("Alg");
if (KeyName == null)
throw new ArgumentNullException("KeyName");
////////////////////////////////////////////////
// Find the specified element in the XmlDocument
// object and create a new XmlElemnt object.
////////////////////////////////////////////////
XmlElement elementToEncrypt = Doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
// Throw an XmlException if the element was not found.
if (elementToEncrypt == null)
{
throw new XmlException("The specified element was not found");
}
RijndaelManaged sessionKey = null;
try
{
//////////////////////////////////////////////////
// Create a new instance of the EncryptedXml class
// and use it to encrypt the XmlElement with the
// a new random symmetric key.
//////////////////////////////////////////////////
// Create a 256 bit Rijndael key.
sessionKey = new RijndaelManaged();
sessionKey.KeySize = 256;
EncryptedXml eXml = new EncryptedXml();
byte[] encryptedElement = eXml.EncryptData(elementToEncrypt, sessionKey, false);
////////////////////////////////////////////////
// Construct an EncryptedData object and populate
// it with the desired encryption information.
////////////////////////////////////////////////
EncryptedData edElement = new EncryptedData();
edElement.Type = EncryptedXml.XmlEncElementUrl;
edElement.Id = EncryptionElementID;
// Create an EncryptionMethod element so that the
// receiver knows which algorithm to use for decryption.
edElement.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
// Encrypt the session key and add it to an EncryptedKey element.
EncryptedKey ek = new EncryptedKey();
byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, Alg, false);
ek.CipherData = new CipherData(encryptedKey);
ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA15Url);
// Create a new DataReference element
// for the KeyInfo element. This optional
// element specifies which EncryptedData
// uses this key. An XML document can have
// multiple EncryptedData elements that use
// different keys.
DataReference dRef = new DataReference();
// Specify the EncryptedData URI.
dRef.Uri = "#" + EncryptionElementID;
// Add the DataReference to the EncryptedKey.
ek.AddReference(dRef);
// Add the encrypted key to the
// EncryptedData object.
edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
// Set the KeyInfo element to specify the
// name of the RSA key.
// Create a new KeyInfoName element.
KeyInfoName kin = new KeyInfoName();
// Specify a name for the key.
kin.Value = KeyName;
// Add the KeyInfoName element to the
// EncryptedKey object.
ek.KeyInfo.AddClause(kin);
// Add the encrypted element data to the
// EncryptedData object.
edElement.CipherData.CipherValue = encryptedElement;
////////////////////////////////////////////////////
// Replace the element from the original XmlDocument
// object with the EncryptedData element.
////////////////////////////////////////////////////
EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
}
catch (Exception e)
{
// re-throw the exception.
throw e;
}
finally
{
if (sessionKey != null)
{
sessionKey.Clear();
}
}
}
public static void Decrypt(XmlDocument Doc, RSA Alg, string KeyName)
{
// Check the arguments.
if (Doc == null)
throw new ArgumentNullException("Doc");
if (Alg == null)
throw new ArgumentNullException("Alg");
if (KeyName == null)
throw new ArgumentNullException("KeyName");
// Create a new EncryptedXml object.
EncryptedXml exml = new EncryptedXml(Doc);
// Add a key-name mapping.
// This method can only decrypt documents
// that present the specified key name.
exml.AddKeyNameMapping(KeyName, Alg);
// Decrypt the element.
exml.DecryptDocument();
}
}
}
Diese feinen, so lange zu arbeiten scheint, wie ich bin Speicher/Abrufen eines RSACryptoServiceProvider mit einem privaten und einem öffentlichen Schlüssel Sobald ich einen RSACryptoServiceProvider mit JUST einen öffentlichen Schlüssel speichere, das nächste Mal, wenn ich versuche, alles abzurufen, bekomme ich einen NEUEN und UNTERSCHIEDLICHEN RSACryptoServiceProvider!
Wie Sie sich vorstellen können, können Sie nicht etwas mit einem Schlüsselsatz verschlüsseln und dann versuchen, mit einem ganz neuen Satz zu entschlüsseln!
Alle Ideen, warum dies geschieht? oder was wäre der richtige Weg, einen öffentlichen Schlüssel zu speichern?
Ist das richtig: Einmal speichere ich eine RSACryptoServiceProvider nur mit einem privaten Schlüssel Meinten Sie Sobald ich eine RSACryptoServiceProvider nur mit einem öffentlichen Schlüssel speichern – Christian
Ja, ich bin für die Tippfehler leider –