如何RSA加密XmlFile在一个程序和解密在另一个? [英] How to RSA Encrypt XmlFile in one program and decrypt in another?

查看:140
本文介绍了如何RSA加密XmlFile在一个程序和解密在另一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要加密/解密整个XML文件。我在此MSDN帖子中使用RSA,但问题是我必须在一个程序中加密,Windows窗体程序和在Windows服务中解密。 Windows服务如何知道我为了解密而生成的RSA密钥?

I have a requirement to encrypt/decrypt a whole XML file. I am using RSA like in this MSDN post but the issue is that I have to encrypt in one program, an Windows Form program and decrypt in a Windows Service. How will the Windows Service know the RSA key I generated in order to decrypt?

加密/解密代码是:

 public class EncryptDecrpt
    {
        public static void Encrypt(XmlDocument doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg,
            string KeyName)
        {
            try
            {
                //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 XmlElement object
                XmlElement elementToEncrypt = doc.GetElementsByTagName(ElementToEncrypt)[0] as XmlElement;
                if (elementToEncrypt == null)
                    throw new XmlException("The specified element was not found");

                RijndaelManaged sessionKey = null;

                // Create a 256 bit Rijandel 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;

                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);

                DataReference dRef = new DataReference();

                // Specify the EncryptedData URI
                dRef.Uri = "#" + EncryptionElementID;

                ek.AddReference(dRef);

                edElement.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));

                KeyInfoName kin = new KeyInfoName();

                kin.Value = KeyName;

                ek.KeyInfo.AddClause(kin);

                edElement.CipherData.CipherValue = encryptedElement;

                // Replace the element from the original XmlDocument
                // object with the EncrytedData element
                EncryptedXml.ReplaceElement(elementToEncrypt, edElement, false);
            }
            catch (Exception e)
            {
                // rethrow the exception
                throw e;
            }

        }

        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();

        }

    }

Windows Form程序是:

The code in the Windows Form program is:

 private void SaveForm()
        {
            try
            {
                string fileName = System.IO.Path.Combine(Application.StartupPath, "alphaService.xml");
                XDocument doc = new XDocument();
                XElement xml = new XElement("Info",
                    new XElement("DatabaseServerName", txtServerName.Text),
                    new XElement("DatabaseUserName", txtDatabaseUserName.Text),
                    new XElement("DatabasePassword", txtDatabasePassword.Text),
                    new XElement("ServiceAccount", txtAccount.Text),
                    new XElement("ServicePassword", txtServicePassword.Text),
                    new XElement("RegistrationCode", txtRegistrationCode.Text));

                doc.Add(xml);
                doc.Save(fileName);

                // Encrypt
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(fileName);
                // Create a new CspParameters object to specify
                // a key container
                CspParameters cspParams = new CspParameters();
                cspParams.KeyContainerName = "XML_ENC_RSA_KEY";

                RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);

                EncryptDecrpt.Encrypt(xmlDoc, "info", "EncryptedElement1", rsaKey, "rsaKey");

                xmlDoc.Save(fileName);

                MessageBox.Show(xmlDoc.OuterXml);

                EncryptDecrpt.Decrypt(xmlDoc, rsaKey, "rsaKey");

Windows服务如何知道RSA密钥或如何这样做?

How will the Windows Service know the RSA key or how can I do this?

推荐答案

您需要在两个应用程序之间共享您的公钥。只要做新的RSACryptoServiceProvider()每次都会生成新的密钥。我在项目的app.config中共享了我的密钥:

You need to share your public key between both of your applications. Just doing new RSACryptoServiceProvider() every time will generate new keys. I shared my keys in the project's app.config:

<applicationSettings>
    <YpurApp.Properties.Settings>
        <setting name="PublicKeyXml" serializeAs="String">
            <value>&lt;RSAKeyValue&gt;&lt;Modulus&gt;YOURMODULUS&lt;/Modulus&gt;&lt;Exponent&gt;YOUREXP&lt;/Exponent&gt;&lt;/RSAKeyValue&gt;</value>
        </setting>

一旦程序读入,XML实际上就是这样:

The XML actually looks like this, once read in by the program:

<RSAKeyValue><Modulus>YOURMODULUS</Modulus><Exponent>YOUREXP</Exponent></RSAKeyValue>

然后你可以使用这样的代码在公共应用程序中加密:

Then you can use code like this to encrypt in the public application:

    private static byte[] Encrypt(byte[] bytes)
    {
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
        {
            rsa.FromXmlString(Properties.Settings.Default.PublicKeyXml);
            return rsa.Encrypt(bytes, true);
        }
    }

私人应用程序还应该具有匹配的PrivateKey硬编码或在app.config中。您不想将私钥与任何可能使用它破解您的加密的公共共享。数据使用私钥解密,如下所示:

The private application should also have the matching PrivateKey, either hard coded or in the app.config. You would not want to share the private key with anything "public" that could use it to break your encryption. Data is decrypted using the private key like this:

    private static byte[] Decrypt(byte[] bytes)
    {
        using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
        {
            rsa.FromXmlString(Properties.Settings.Default.PrivateKeyXml);
            return rsa.Decrypt(bytes, true);
        }
    }

要生成密钥,请执行以下操作:

To generate the keys, do this:

        CspParameters cspParams = new CspParameters();
        cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
        RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
        string keyXML = rsaKey.ToXmlString(true);

这将包含公钥和私钥。公共密钥是 < Modulus>< / Modulus>< Exponent>< / Exponent> 私钥是整个事物,包括< / p>< Q>< / DP>< / DP>< DQ>< / Inverse Q>< / Inverse Q>< / D> 。将该字符串复制/粘贴到app.config中,并将其拆分为两个选项,如上所述的 PublicKey PrivateKey 。不要在加密应用程序的app.config中包含私有密钥。

This will contain the public and private keys. The public key is the <RSAKeyValue><Modulus></Modulus><Exponent></Exponent> part. The private key is the whole thing, including the <P></P><Q></Q><DP></DP><DQ></DQ><InverseQ></InverseQ><D></D>. Copy/Paste that string into your app.config, and split it into two options, PublicKey and PrivateKey as noted above. DO NOT INCLUDE THE PRIVATE KEY in the encrypting application's app.config.

这篇关于如何RSA加密XmlFile在一个程序和解密在另一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆