473,407 Members | 2,314 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,407 software developers and data experts.

Canonicalize and signing in C#

Hi,

I'm having a problem canonicalizing an xml document and getting a hash
that matches that of an existing document so I was wondering if somebody
knew what I was doing wrong.

I generate an XML document and need to do the following:
- Canonicalize (14n) the XML Document
- Generate a 160-bit binary secure has from the canonicalized XML using
SHA-1 algorithm
- Encode the binary data using base-64 to produce a 28 characters string
- Encode the binary data using base-32 to produce an easily human
readable 32 characters string

I've included an example of a typical XML file below. The part that
needs to be canonicalized and hashed is the Body element. Within <Body>,
you'll notice an IRmark element. This element should not be there for
the process of canonicalization and hashing. The hash that is included
is supposed to be valid, although I have never been able to get a
similar hash.

The code simply tries to do all the steps taking, a file called irmark-
canonical.xml which is identical to the one pasted below bar the IRmark
element not being there. I try to retrieve the <Body> element,
canonicalize it and hash it. I then retrieve the IRmark element in
irmark-example.xml (the file pasted below) and display the values on
screen. Well, they never match! I guess the biggest problem here is that
I'm just not very familiar with all these processes. I get the
impression that I might be using the wrong canonicalize function.

I also attached a java code snippet which was provided by the
organization that is at the receiving end of the document. Maybe this
will help somebody figuring out what I'm doing wrong? I haven't been
able to figure out how to get the
base-32 requirement either.

Any help will be greatly appreciated.

Pollux

XML File
++++++++
<?xml version="1.0"?>
<!-- Generic IRmark example instance - supplied credentials are not to
be used for any other purpose --> <GovTalkMessage
xmlns="http://www.govtalk.gov.uk/CM/envelope">
<EnvelopeVersion>2.0</EnvelopeVersion>
<Header>
<MessageDetails>
<Class>IR-SA-SA100</Class>
<Qualifier>request</Qualifier>
<Function>submit</Function>
<CorrelationID></CorrelationID>
<Transformation>XML</Transformation>
<GatewayTest>1</GatewayTest>
<GatewayTimestamp></GatewayTimestamp>
</MessageDetails>
<SenderDetails>
<IDAuthentication>
<SenderID>SA0154</SenderID>
<Authentication>
<Method>clear</Method>
<Role>principal</Role>
<Value>testing1</Value>
</Authentication>
</IDAuthentication>
</SenderDetails>
</Header>
<GovTalkDetails>
<Keys>
<Key Type="UTR">1000000154</Key>
</Keys>
<TargetDetails>
<Organisation>IR</Organisation>
</TargetDetails>
<ChannelRouting>
<Channel>
<URI>9999</URI>
<Product>Generic IRmark</Product>
<Version>1.0</Version>
</Channel>
</ChannelRouting>
</GovTalkDetails>
<Body>
<IRenvelope xmlns="http://www.govtalk.gov.uk/taxation/SA">
<IRheader>
<TestMessage>0</TestMessage>
<Keys>
<Key Type="UTR">1000000154</Key>
</Keys>
<PeriodEnd>2004-04-05</PeriodEnd>
<Manifest>
<Contains>
<Reference>
<Namespace>
http://www.inlandrevenue.gov.uk</Namespace>
<SchemaVersion>2004-v1.0
</SchemaVersion>
<TopElementName>SA100
</TopElementName>
</Reference>
</Contains>
</Manifest>
<IRmark Type="generic">
v0wMpG9kYq0AJzQG4/rXQu/wejE=</IRmark>
<Sender>Individual</Sender>
</IRheader>
<SA100><MainReturn><FullName>Case 1</FullName>
<SelfEmployment>yes</SelfEmployment>
<StudentLoanLiable>no
</StudentLoanLiable>
<TaxCalculation><CalculateOwnTax>yes
</CalculateOwnTax>
<Class4NICdue>9.36
</Class4NICdue>
<TotalTaxDue>21.06
</TotalTaxDue>

<ClaimToReduceYourPaymentsOnAccount>no
</ClaimToReduceYourPaymentsOnAccount>
</TaxCalculation>
<ClaimRepayment><Claim>no</Claim>
</ClaimRepayment>
<OtherPersonalDetails><Forename>John
</Forename>
<MaritalStatus>S
</MaritalStatus>
<NINO>YY672978C</NINO>
</OtherPersonalDetails>

<FurtherInformation><DoNotWantToPayThroughTaxCodin g>no
</DoNotWantToPayThroug
hTaxCoding>

<TaxReturnContainsProvisionalFigures>no
</TaxReturnContainsProvisionalFigures


<ReliefClaimedNowForCertainLosses>no</ReliefClaimedNowForCertainLosses>
<PostCessationReceiptsEtc>no
</PostCessationReceiptsEtc>
</FurtherInformation>
</MainReturn>

<SelfEmployments><SelfEmployment><BusinessDetails> <NameOfBusiness>B
</NameOfB
usiness>
<Description>Plumber
</Description>
<Address><Line>Address
</Line>
</Address>
<AccountingPeriodStart>
2003-01-01</AccountingPeriodStart>
<AccountingPeriodEnd>
2003-08-31</AccountingPeriodEnd>
<DetailsChanged>no
</DetailsChanged>
<DateOfCessation>2003-
08-31</DateOfCessation>
<SpecialArrangements>no
</SpecialArrangements>

<EnteredDetailsElsewhere>no</EnteredDetailsElsewhere>
<DoNotCover>no
</DoNotCover>
<DateHasChanged>no
</DateHasChanged>
<FurtherChange>no
</FurtherChange>
</BusinessDetails>
<CapitalAllowancesSummary>
<Cars>1161.00</Cars>
<TotalAllowances>1161.00
</TotalAllowances>

<EnhancedCapitalAllowances>no</EnhancedCapitalAllowances>
</CapitalAllowancesSummary>
<IncomeAndExpenses><IncludeVAT>
no</IncludeVAT>
<SalesBusinessIncome>
16788.00</SalesBusinessIncome>

<DisallowableSubContractorCosts>270.00</DisallowableSubContractorCosts>

<DisallowableEmployeeCosts>212.00</DisallowableEmployeeCosts>

<DisallowableMotorExpenses>143.00</DisallowableMotorExpenses>
<DisallowableTravel>
62.00</DisallowableTravel>
<GrossProfitLoss>
16788.00</GrossProfitLoss>
<EmployeeCosts>1500.00
</EmployeeCosts>
<PremisesCosts>1252.00
</PremisesCosts>

<GeneralAdministrativeExpenses>961.00
</GeneralAdministrativeExpenses>
<MotorExpenses>3133.00
</MotorExpenses>
<Travel>545.00</Travel>
<LegalCosts>2150.00
</LegalCosts>
<OtherExpenses>59.00
</OtherExpenses>
<TotalExpenses>9600.00
</TotalExpenses>
<NetProfitOrLoss>7188.00
</NetProfitOrLoss>
</IncomeAndExpenses>
<TaxAdjustments>
<DisallowableExpenses>687.00</DisallowableExpenses>

<TotalAdditionsToNetProfit>687.00</TotalAdditionsToNetProfit>
<CapitalAllowances>
1161.00</CapitalAllowances>

<DeductionsFromNetProfit>1161.00</DeductionsFromNetProfit>
<NetProfitLoss>6714.00
</NetProfitLoss>
</TaxAdjustments>

<AdjustmentsForTaxableProfitOrLoss><BasisPeriodBeg ins>2003-01-01
</BasisPerio
dBegins>
<BasisPeriodEnds>2003-
08-31</BasisPeriodEnds>
<ProfitFromOtherBoxes>
6714.00</ProfitFromOtherBoxes>

<OverlapProfitBroughtForward>1982.00</OverlapProfitBroughtForward>
<ReliefUsedThisYear>
1982.00</ReliefUsedThisYear>
<NetProfit>4732.00
</NetProfit>

<TaxableProfitAfterBroughtForward>4732.00
</TaxableProfitAfterBroughtForward>
<TotalTaxableProfits>
4732.00</TotalTaxableProfits>
<Provisional>no
</Provisional>

</AdjustmentsForTaxableProfitOrLoss>

<SummaryOfBalanceSheet><Assets><StockAndWorkInProg ress>250.00
</StockAndWorkI
nProgress>
<BankEtcBalances>
2591.00</BankEtcBalances>
<TotalAssets>
2841.00</TotalAssets>
</Assets>
<NetBusinessAssets>
2841.00</NetBusinessAssets>

<CapitalAccount><BalanceAtStartOfPeriod>2403.00</BalanceAtStartOfPeriod>
<NetProfitLoss>
7188.00</NetProfitLoss>
<Drawings>6750.00
</Drawings>

<CapitalAccountBalanceAtEndOfPeriod>2841.00
</CapitalAccountBalanceAtEndOfPer
iod>
</CapitalAccount>
</SummaryOfBalanceSheet>
</SelfEmployment>
</SelfEmployments>
</SA100>
</IRenvelope>
</Body>
</GovTalkMessage>

C# Code
++++
using System;
using System.Xml;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Windows.Forms;
using System.IO;
using System.Text;

namespace irmark
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
XmlDocument docStripped = new XmlDocument();
docStripped.Load("irmark-canonical.xml");
XmlNamespaceManager nsmgr = new
XmlNamespaceManager(docStripped.NameTable);

// The default namespace has been changed. We need
to create a prefix for it
nsmgr.AddNamespace("tax",
"http://www.govtalk.gov.uk/taxation/SA" );
nsmgr.AddNamespace("env",
"http://www.govtalk.gov.uk/CM/envelope" );

XmlNode strippedNode = docStripped.SelectSingleNode
("//env:Body", nsmgr);
XmlDocument myDoc = new XmlDocument();
myDoc.LoadXml(strippedNode.OuterXml);

XmlDocument docOriginal = new XmlDocument();
docOriginal.Load("irmark-example.xml");
XmlNode currentNode =
docOriginal.DocumentElement.SelectSingleNode("//tax:IRmark", nsmgr);
string correctIRmark = currentNode.InnerText;

XmlDsigC14NTransform t = new XmlDsigC14NTransform();
t.LoadInput (myDoc);
Stream s = (Stream) t.GetOutput(typeof(Stream));
SHA1 sha1 = SHA1.Create();

byte[] hash = sha1.ComputeHash(s);
Console.WriteLine("Original IRmark: " +
correctIRmark);
string base64String = Convert.ToBase64String(hash);
Console.WriteLine("My IRmark: " + base64String);
}
}
}

Java Code
+++++++++

import java.io.*;
import javax.xml.parsers.*;
import java.security.*;

import org.w3c.dom.*;

import org.apache.xml.security.signature.*;
import org.apache.xml.security.transforms.*;
import org.apache.xml.security.Init;

import org.bouncycastle.util.encoders.Base64;

/**
* This code generates an IRmark value for an input document.
* The value is a base64 encoded SHA1 digest of a signature
* transform over a certain style of document. The value has
* to be placed inside documents to be signed by the XPE when
* used in a EDS/IR deployment.
*
* The code has a number of jar dependencies:-
* xmlsec.jar - The Apache XML Security Library
* log4j-1.2.5.jar - The Apache Log utility
* xalan.jar - Apache XSLT/XPath processor
* xercesImpl.jar - Apache XML processor
* bc-jce-jdk13-114.jar - Bouncy Castle JCE library
*
* The Bouncy Castle JCE provider is automatically downloaded
* by the Apache XML sec library build so you may already have
* that.
*/
public class IRMark {

/**
* Generate and print the IRmark.
*
* @param args - Pass the filename of the input document
* @throws Exception
*/
public static void main(String args[]) throws Exception {

// Init the Apache XML security library
Init.init();

// Check we are given a file to work with
if (args.length!=1) {
System.out.println("Use: IRmark <file> ");
return;
}

// Open the input file
FileInputStream fis=null;
try {
fis=new FileInputStream(args[0]);
} catch (FileNotFoundException e) {
System.out.println("The file " + args[0] + " could
not be opened.");
return;
}

// Load file into a byte array
byte[] data=null;
try {
int bytes=fis.available();
data=new byte[bytes];
fis.read(data);
} catch (IOException e) {
System.out.println("Error reading file.");
e.printStackTrace();
}

// First part is to run the a transform over the input to
extract the
// fragment to be digested. This is done by setting up a
Transforms
// object from a Template and then executing against the
input document

// The transforms to be performed are specified by using
the template XML below.
String transformStr =
"<?xml version='1.0'?>\n"
+ "<dsig:Transforms
xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'
xmlns:gt='http://www.govtalk.gov.uk/CM/envelope'
xmlns:ir='http://www.govtalk.gov.uk/taxation/SA'>\n"
+ "<dsig:Transform
Algorithm='http://www.w3.org/TR/1999/REC-xpath-19991116'>\n"
+ "<dsig:XPath>\n"
+
"count(ancestor-or-self::node()|/gt:GovTalkMessage/gt:Body)=count
(ancestor-o
r-self::node())\n"
+ " and count(self::ir:IRmark)=0 \n"
+ " and count(../self::ir:IRmark)=0 \n"
+ "</dsig:XPath>\n"
+ "</dsig:Transform>\n"
+ "<dsig:Transform
Algorithm='http://www.w3.org/TR/2001/REC-xml-c14n-20010315
#WithComments'/>\n
"
+ "</dsig:Transforms>\n"
;

// Parse the transform details to create a document
DocumentBuilderFactory
dbf=DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.parse(new ByteArrayInputStream
(transformStr.getBytes()));

// Construct a Apache security Transforms object from that
document
Transforms transforms = new Transforms
(doc.getDocumentElement(), null);

// Now perform the transform on the input to get the
results.
XMLSignatureInput input = new XMLSignatureInput(data);
XMLSignatureInput result = transforms.performTransforms(input);

// Uncomment this line to see transform output
// System.out.println(new String(result.getBytes()));

// Second part is to run output via SHA1 digest
// This is done via the standard java.security API
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(result.getBytes());
byte[] digest=md.digest();

// And finally print a Base64 of the digest with
// The help of the BouncyCastle JCE library
System.out.println("IRmark: " + new String(Base64.encode
(digest)));
}
}
Nov 12 '05 #1
0 8391

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Martin | last post by:
I have a couple of questions around code signing with MS technology: 1. Is there a way to transfer the generated strong name signing private key directly to a smartcard (or generate it on the...
4
by: Oleg Subachev | last post by:
I need to canonicalize (in the sence of http://www.w3.org/TR/xml-c14n) some input XML and get canonicalized output XML. How can I perform this under .NET ? -- Oleg Subachev
1
by: Pollux | last post by:
Hi I previously posted a question which hasn't been answered, so I figured it must have been too complicated. I must admit that I didn't make it very easy to follow. In fact, the information I...
0
by: Martin Silar | last post by:
Hi, I canonicalize document subset and result is different from w3c.org examples. Do you know where is the problem? thanks Martin String xPath="(//. | //@* | //namespace::*)"; ...
0
by: Pollux | last post by:
Hi, I'm having a problem canonicalizing an xml document and getting a hash that matches that of an existing document so I was wondering if somebody knew what I was doing wrong. I generate an...
0
by: Martin | last post by:
Hi, I canonicalize document subset and result is different from w3c.org examples. Do you know where is the problem? thanks Martin String xPath="(//. | //@* | //namespace::*)"; ...
0
by: Raffi Basmajian | last post by:
I am trying to understand the difference between signing ClickOnce manifests and signing shared assemblies. My company is building .Net 2005 WinForm applications for internal company use only....
6
by: raylopez99 | last post by:
Anybody use Strong Name Signing? I think this is used by default for Resource files, which is one reason perhaps I can't get my resource files to work (somehow the public key is messed up, perhaps...
1
by: BillE | last post by:
<extreme frustration> I have googled and read about this, but can't seem to get a grip on it. Apparently I am being coerced into digitally signing applications. Is this true? What if I don't...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.