RSAServiceProvider를 이용해서 xml 파일에 서명 및 Decryption 하는 과정
RSAServiceProvider를 제공된 public key를 이용해서 얻어내는 것이 이 코드의 핵심.
RSAServiceProvider를 제공된 public key를 이용해서 얻어내는 것이 이 코드의 핵심.
001.
private
String publicOnlyKey;
002.
private
void
btnSign_Click(
object
sender, EventArgs e)
003.
{
004.
try
005.
{
006.
/////////////////////////////////////////////////////////////////
007.
// Create a new RSA signing key and export public key for
008.
// verification.
009.
010.
RSACryptoServiceProvider rsaKey =
new
RSACryptoServiceProvider();
011.
012.
//Public Key exported
013.
//Public Key 뿐 아니라 Private Key도 얻어내는 것이 가능하다. 사용자에게 Key를 보내거나 저장할 때 이용 가능
014.
publicOnlyKey = rsaKey.ToXmlString(
false
);
015.
tbxRSAParameters.Text = publicOnlyKey;
016.
017.
/////////////////////////////////////////////////////////////////
018.
// Sign the XML document.
019.
//
020.
021.
SignXml(xmlDoc, rsaKey);
022.
MessageBox.Show(
"XML file signed."
);
023.
024.
025.
/////////////////////////////////////////////////////////////////
026.
// Save and display the signed document.
027.
//
028.
029.
xmlDoc.Save(
"test1.xml"
);
030.
tbxDigitalSignature.Text = xmlDoc.OuterXml;
031.
}
032.
catch
(Exception ex)
033.
{
034.
Console.WriteLine(ex.Message);
035.
}
036.
}
037.
038.
///XML파일을 RSA를 이용해서 서명. SignedXml class가 있는 것을 기억하고 있을것!
039.
public
static
void
SignXml(XmlDocument Doc, RSA Key)
040.
{
041.
// Check arguments.
042.
if
(Doc ==
null
)
043.
throw
new
ArgumentException(
"Doc"
);
044.
if
(Key ==
null
)
045.
throw
new
ArgumentException(
"Key"
);
046.
047.
try
048.
{
049.
// Create a SignedXml object to generate signature.
050.
SignedXml signedXml =
new
SignedXml(Doc);
051.
052.
// Add the key to the SignedXml document
053.
signedXml.SigningKey = Key;
054.
055.
// Create a reference to be signed
056.
Reference reference =
new
Reference();
057.
reference.Uri =
""
;
058.
059.
// Add an enveloped transformation to the reference
060.
XmlDsigEnvelopedSignatureTransform env =
new
XmlDsigEnvelopedSignatureTransform();
061.
reference.AddTransform(env);
062.
063.
// Add the reference to the SignedXml object
064.
signedXml.AddReference(reference);
065.
066.
// Compute the signature
067.
signedXml.ComputeSignature();
068.
069.
// Get the XML representation of the signature and save
070.
// it to an XmlElement object.
071.
XmlElement xmlDigitalSignature = signedXml.GetXml();
072.
073.
// Append the element to the XML document.
074.
Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature,
true
));
075.
}
076.
catch
(Exception ex)
077.
{
078.
MessageBox.Show(ex.Message);
079.
}
080.
}
081.
082.
private
void
btnVerify_Click(
object
sender, EventArgs e)
083.
{
084.
/////////////////////////////////////////////////////////////////////
085.
// Create a new RSA signing key and import public key for
086.
// verification.
087.
//
088.
089.
//NOTE:Public RSA Key를 이용해서 RSACryptoService Generate
090.
RSACryptoServiceProvider rsaKey =
new
RSACryptoServiceProvider();
091.
rsaKey.FromXmlString(publicOnlyKey);
092.
/////////////////////////////////////////////////////////////////////
093.
// Load the signed XML, and call VerifyXml to verify the signature of
094.
// the signed XML.
095.
//
096.
097.
XmlDocument xmlDoc =
new
XmlDocument();
098.
xmlDoc.Load(
"test1.xml"
);
099.
100.
bool
result = VerifyXml(xmlDoc, rsaKey);
101.
102.
if
(result)
103.
{
104.
MessageBox.Show(
"The XML signature is valid."
);
105.
}
106.
else
107.
{
108.
MessageBox.Show(
"The XML signature is not valid."
);
109.
}
110.
}
111.
112.
public
static
Boolean VerifyXml(XmlDocument Doc, RSA Key)
113.
{
114.
// Check arguments.
115.
if
(Doc ==
null
)
116.
throw
new
ArgumentException(
"Doc"
);
117.
if
(Key ==
null
)
118.
throw
new
ArgumentException(
"Key"
);
119.
120.
121.
/////////////////////////////////////////////////////////////////////
122.
// Create a SignedXml object to verify the signature
123.
//
124.
125.
SignedXml signedXml =
new
SignedXml(Doc);
126.
127.
// Find Signature node and create a new XmlNodeList object
128.
XmlNodeList nodeList = Doc.GetElementsByTagName(
"Signature"
);
129.
130.
// Throw an exception if no signature was found.
131.
if
(nodeList.Count <= 0)
132.
{
133.
throw
new
CryptographicException(
134.
"Verification failed:"
+
135.
" No Signature was found in the document."
);
136.
}
137.
138.
// This example only supports one signature for entire XML document
139.
if
(nodeList.Count >= 2)
140.
{
141.
throw
new
CryptographicException(
142.
"Verification failed: More that one signature was found."
);
143.
}
144.
145.
// Load the first <signature> node.
146.
signedXml.LoadXml((XmlElement)nodeList[0]);
147.
148.
// Check the signature and return the result.
149.
return
signedXml.CheckSignature(Key);
150.
}
151.
152.
private
void
btnChangeXML_Click(
object
sender, EventArgs e)
153.
{
154.
// Modify the value of the Xml document for test.
155.
156.
XDocument xDoc = XDocument.Load(
"test1.xml"
);
157.
158.
if
(xDoc !=
null
)
159.
{
160.
xDoc.Element(
"invoice"
).Element(
"items"
).
161.
Element(
"creditcard"
).Element(
"number"
).SetValue(
"19834210"
);
162.
163.
xDoc.Save(
"test1.xml"
);
164.
165.
tbxModifiedMessage.Text = xDoc.ToString();
166.
}
167.
}
168.
</signature>