1

首先,让我承认我对 C# 非常陌生,特别是在使用密码学方面。我开发了一个 C# 应用程序来管理我的登录和密码信息。我从 Winform 读取信息并存储在 XML 中。XML 已加密。

该程序在我有代码的机器上运行良好。在调试器中工作,当我使用 exe(在 Visual Studio 之外)时也可以工作。

现在,当我将 exe(整个 bin 目录)带到我的家用计算机(具有 C# express 2010)时,它在尝试读取/写入 xml 中的任何信息时崩溃。这是我在异常对话框中得到的错误:

See the end of this message for details on invoking 
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.Security.Cryptography.CryptographicException: Bad Data.

   at System.Security.Cryptography.CryptographicException.ThrowCryptogaphicException(Int32 hr)
   at System.Security.Cryptography.Utils._DecryptKey(SafeKeyHandle hPubKey, Byte[] key, Int32 dwFlags)
   at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[] rgb, Boolean fOAEP)
   at System.Security.Cryptography.RSAPKCS1KeyExchangeDeformatter.DecryptKeyExchange(Byte[] rgbIn)
   at System.Security.Cryptography.Xml.EncryptedXml.DecryptKey(Byte[] keyData, RSA rsa, Boolean useOAEP)
   at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
   at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
   at MyCal.Calendar.Decrypt(String Doc, RSA Alg, String KeyName) in C:\Users\mpaudel\Desktop\MyCal\MyCal\Form1.cs:line 191
   at MyCal.Calendar.btnSaveAdd_Click(Object sender, EventArgs e) in C:\Users\mpaudel\Desktop\MyCal\MyCal\Form1.cs:line 971
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5448 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
----------------------------------------
MyCal
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/remoteuser/Desktop/Release/MyCal.exe
----------------------------------------
System.Windows.Forms
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5446 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5453 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Windows.Forms.Calendar
    Assembly Version: 1.0.4359.17528
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/remoteuser/Desktop/Release/System.Windows.Forms.Calendar.DLL
----------------------------------------
RicherTextBox
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/remoteuser/Desktop/Release/RicherTextBox.DLL
----------------------------------------
System.Xml
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
System.Configuration
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
33fead0k
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5453 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
Microsoft.mshtml
    Assembly Version: 7.0.3300.0
    Win32 Version: 7.0.3300.0
    CodeBase: file:///C:/Windows/assembly/GAC/Microsoft.mshtml/7.0.3300.0__b03f5f7f11d50a3a/Microsoft.mshtml.dll
----------------------------------------
System.Security
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Security/2.0.0.0__b03f5f7f11d50a3a/System.Security.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
    <system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

请帮助我度过难关。非常感谢您调查它。- 议员

更新:-

这是我的代码。如果代码很糟糕,请原谅:-) 这是我的学习项目。

public partial class frmLogOn : Form
    {
        public frmLogOn()
        {
            InitializeComponent();
        }

        string LOGON_FILE_NAME = "logon.xml";//"logon.xml";

        private void btnEnterLogon_Click(object sender, EventArgs e)
        {

            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams); 
            Decrypt(LOGON_FILE_NAME, rsaKey, "rsaKey");


            //Read Password from the xml file
            XmlDocument xmlDoc = new XmlDocument();

            if (File.Exists(LOGON_FILE_NAME))
            {
                XmlTextReader rdrXml = new XmlTextReader(LOGON_FILE_NAME);
                string existingpswd;
                do
                {
                       switch (rdrXml.NodeType)
                       {
                        case XmlNodeType.Text:
                        existingpswd = rdrXml.Value;
                        if (this.txtpswdLogon.Text == existingpswd)
                        {
                            this.DialogResult = DialogResult.OK;

                        }
                        else
                        {
                            MessageBox.Show("Password did not match", "Validate Entry", MessageBoxButtons.OK);
                            rdrXml.Close();
                            Encrypt(LOGON_FILE_NAME, "Pswrds", "EncryptedElement1", rsaKey, "rsaKey");
                            return;

                        }
                        break;
                       }


                } while (rdrXml.Read());
                rdrXml.Close();
                Encrypt(LOGON_FILE_NAME, "Pswrds", "EncryptedElement1", rsaKey, "rsaKey");
            }
        }

        private void chkChangepswdLogon_CheckedChanged(object sender, EventArgs e)
        {
            if (this.chkChangepswdLogon.Checked == true)
            {
                this.Height = 180;
                this.txtNewPswdLogon.Visible = true;
                this.txtOldPswdLogon.Visible = true;
                this.btnChangeLogOn.Visible = true;
                this.txtOldPswdLogon.Focus();
            }
            else if (this.chkChangepswdLogon.Checked == false)
            {
                this.Height = 105;
                this.txtNewPswdLogon.Visible = false;
                this.txtOldPswdLogon.Visible = false;
                this.btnChangeLogOn.Visible = false;
            }
        }

        private void frmLogOn_Load(object sender, EventArgs e)
        {

        }

        private void btnChangeLogOn_Click(object sender, EventArgs e)
        {
            CspParameters cspParams = new CspParameters();
            cspParams.KeyContainerName = "XML_ENC_RSA_KEY";
            RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);


            Decrypt(LOGON_FILE_NAME, rsaKey, "rsaKey");
            XmlTextReader reader = new XmlTextReader(LOGON_FILE_NAME);
            XmlDocument doc = new XmlDocument();
            doc.Load(reader);
            reader.Close();
            XmlNode oldRecord;
            XmlElement root = doc.DocumentElement;
            try
            {
                oldRecord = root.SelectSingleNode("/Pswrds/pswd[password='" + this.txtOldPswdLogon.Text + "']");
                if (oldRecord == null)
                {
                    MessageBox.Show("Wrong existing password, not authorized to change");
                    this.txtNewPswdLogon.Text = "";
                    this.txtOldPswdLogon.Text = "";
                    this.txtpswdLogon.Text = "";
                    return;
                    Encrypt(LOGON_FILE_NAME, "Pswrds", "EncryptedElement1", rsaKey, "rsaKey");
                }
            }
            catch
            {
                MessageBox.Show("Wrong existing password, not authorized to change");
                return;
                Encrypt(LOGON_FILE_NAME, "Pswrds", "EncryptedElement1", rsaKey, "rsaKey");
            }
            string aa = oldRecord.Value;
            XmlElement newRecord = doc.CreateElement("pswd");

            newRecord.InnerXml = "<password>" + this.txtNewPswdLogon.Text + "</password>" ;

            root.ReplaceChild(newRecord, oldRecord);
            //save the output to a file 
            doc.Save(LOGON_FILE_NAME);
            MessageBox.Show("Password successfully changed.");
            this.txtNewPswdLogon.Text = "";
            this.txtOldPswdLogon.Text = "";
            this.txtpswdLogon.Text = "";
            this.chkChangepswdLogon.Checked = false;


            Encrypt(LOGON_FILE_NAME, "Pswrds", "EncryptedElement1", rsaKey, "rsaKey");
        }



        public static void Encrypt(string Doc, string ElementToEncrypt, string EncryptionElementID, RSA Alg, string KeyName)
        {
            // Create an XmlDocument object.
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load(Doc);

            // 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 = xmlDoc.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);
                xmlDoc.Save(Doc);
            }
            catch (Exception e)
            {
                // re-throw the exception.
                throw e;
            }
            finally
            {
                if (sessionKey != null)
                {
                    sessionKey.Clear();
                }

            }

        }

        public static void Decrypt(string Doc, RSA Alg, string KeyName)
        {
            // Create an XmlDocument object.
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.PreserveWhitespace = true;
            xmlDoc.Load(Doc);
            // 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(xmlDoc);

            // 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();
            xmlDoc.Save(Doc);

        }





    }
4

2 回答 2

1

这些是评论,但评论框不够大,无法容纳它们。这段代码:

catch (Exception e)
{
    // re-throw the exception.
    throw e;
}

正在丢弃您的堆栈跟踪,因此您看不到导致错误的原因。删除该代码。

我怀疑Doc你传递给的那个Decrypt是无效的。xmlDoc.Load(Doc)在调用和检查之前设置断点。你必须向我们展示你传递的是什么Doc,或者至少从哪里MyCal.Calendar.btnSaveAdd_Click得到它。

另外,你在打电话

if (Doc == null)
    throw new ArgumentNullException("Doc");

使用DocxmlDoc.Load(Doc)。为时已晚,您必须在使用参数之前验证参数,而不是之后。

于 2012-07-06T18:10:26.027 回答
0

我终于发现我试图运行应用程序的两台机器都没有安装 X.509 证书,因此代码在尝试解密时会抛出异常。我从这个链接 [microsoft.com/en-us/download/details.aspx?id=14089] 安装了证书,重新编译了应用程序,现在它就像一个魅力!感谢大家的帮助!

于 2012-07-11T21:01:55.267 回答