首先,让我承认我对 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);
}
}