signedxml icon indicating copy to clipboard operation
signedxml copied to clipboard

How to sign an XML choose some settings?

Open faelp22 opened this issue 10 months ago • 1 comments

Hello everyone, could anyone create an example of how to sign an XML using the following settings?

Hash http://www.w3.org/2000/09/xmldsig#sha1

Signature http://www.w3.org/2000/09/xmldsig#rsa-sha1

Canonicalization Methods/Transforms http://www.w3.org/TR/2001/REC-xml-c14n-20010315

I've tried to do it, but I can't understand it.

faelp22 avatar Apr 17 '24 01:04 faelp22

Your Signature element would have those settings included. The XML specifications have all of the values, but they're in code as well

Then you'll marshal and sign the xml. See tests in this repository for examples.

adamdecaf avatar Apr 17 '24 18:04 adamdecaf

I couldn't find any example on the tests folder :/

jsdaniell avatar Jun 11 '24 16:06 jsdaniell

You can specify those in the xml - https://github.com/moov-io/signedxml/blob/master/tests/testdata/issue55.xml

Then create a Signer and call .Sign - https://github.com/moov-io/signedxml/blob/master/tests/issue55_test.go#L22

adamdecaf avatar Jun 11 '24 21:06 adamdecaf

Can you help me to do this using the Signature struct that I created? @adamdecaf Here's my code:

func SignXML(xpath, canonicalizationAlgorithm, certificate, digestAlgorithm, publicKey, privateKey, xmlString string, transforms []string) error {
	if digestAlgorithm == "" {
		digestAlgorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
	}

	if len(transforms) == 0 {
		transforms = []string{
			"http://www.w3.org/2000/09/xmldsig#enveloped-signature",
			"http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments",
		}
	}

	if certificate == "" {
		certificate = models.GetX509Cert(publicKey)
	}

	if canonicalizationAlgorithm == "" {
		canonicalizationAlgorithm = dsig.CanonicalXML10WithCommentsAlgorithmId.String()
	}

	if publicKey == "" {
		p, err := GetPublicKeyFromFile()
		if err != nil {
			return err
		}

		publicKey = p
	}

	if privateKey == "" {
		p, err := GetPrivateKeyFromFile()
		if err != nil {
			return err
		}

		privateKey = p
	}

	if xpath == "" {
		return errors.New("xpath is required")
	}

	transformsTypes := xmldsig.TransformsType{Transform: make([]xmldsig.TransformType, len(transforms))}

	for i, t := range transforms {
		transformsTypes.Transform[i] = xmldsig.TransformType{
			Algorithm: t,
			XPath:     []*string{&xpath},
		}
	}

	sig := xmldsig.Signature{
		KeyInfo: &xmldsig.KeyInfoType{
			X509Data: []*xmldsig.X509DataType{
				{
					X509Certificate: &certificate,
				},
			},
		},
		SignedInfo: xmldsig.SignedInfoType{
			CanonicalizationMethod: xmldsig.CanonicalizationMethodType{
				Algorithm: canonicalizationAlgorithm,
			},
			Reference: []xmldsig.ReferenceType{
				{
					Transforms: &transformsTypes,
					DigestMethod: xmldsig.DigestMethodType{
						Algorithm: digestAlgorithm,
					},
				},
			},
		},
	}

	spew.Dump(sig)
	return nil
}

jsdaniell avatar Jun 14 '24 13:06 jsdaniell

What error are you getting?

adamdecaf avatar Jun 14 '24 22:06 adamdecaf