在使用goxmldsig时,在将XML编组后出现无效的xmlns值。

huangapple go评论81阅读模式
英文:

Invalid xmlns value after marshalling XML when using goxmldsig

问题

以下是翻译好的内容:

在将XML编组时,下面的代码在根元素上奇怪地添加了一个xmlns属性。根据我所读的,xmlns属性不应该被显式设置。但生成的XML包括xmlns属性:

<?xml version="1.0" encoding="UTF-8"?>
<ExampleElement xmlns="http://www.w3.org/XML/1998/namespace" ID="id1234">
...

当我尝试使用XMLSecTool验证XML签名时,我收到以下错误:

org.xml.sax.SAXParseException: 前缀“xml”不能绑定到除其常规命名空间之外的任何命名空间;“xml”的命名空间也不能绑定到除“xml”之外的任何前缀。

我是否可以使用有效的xmlns属性值,或者我是否错误地使用了库?

package main

import (
	"crypto/rsa"
	"crypto/tls"
	"io/ioutil"
	"log"

	"github.com/beevik/etree"
	"github.com/russellhaering/goxmldsig"
)

type X509KeyStore struct {
	PrivateKey *rsa.PrivateKey
	Cert       []byte
}

func (ks X509KeyStore) GetKeyPair() (*rsa.PrivateKey, []byte, error) {
	return ks.PrivateKey, ks.Cert, nil
}

func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

func main() {
	certBytes := []byte(`-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIJAKMxnSbqmztEMA0GCSqGSIb3DQEBCwUAMIGEMQswCQYD
VQQGEwJHQjETMBEGA1UECAwKQmlybWluZ2hhbTETMBEGA1UEBwwKQmlybWluZ2hh
bTEOMAwGA1UECgwFVGFsaXMxDjAMBgNVBAsMBVRhbGlzMQ4wDAYDVQQDDAVUYWxp
czEbMBkGCSqGSIb3DQEJARYMbXdAdGFsaXMuY29tMB4XDTE3MDgwODIxNTA0NFoX
DTI3MDgwNjIxNTA0NFowgYQxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApCaXJtaW5n
aGFtMRMwEQYDVQQHDApCaXJtaW5naGFtMQ4wDAYDVQQKDAVUYWxpczEOMAwGA1UE
CwwFVGFsaXMxDjAMBgNVBAMMBVRhbGlzMRswGQYJKoZIhvcNAQkBFgxtd0B0YWxp
cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfyQiwTxAbc6HJ
6aB6NrmDYoVUBqWZ4njZyQqnhf0ZvpqGh8ppMiXjiuJjn72pJYHnOqRQNgJDNhAZ
X5KtJ/YI4XbOruJU3TWX/KnGn7l8TJ5FFmnJWHohJ0f9/+uVv0hivRkSVUwh+q2e
TpKNypNu2Kf8iiGW3dMOY1CYWxWnksM1xoaWKV3mWgMqRqcj4kyLT1t8UctOhKhg
m04HPNTeFCkcmH3IuIiVAi3uVU+zDKec8+cxSHHmnm0iphm8jpT0OjNSGWt7F7+N
NhIa2FOI+Lz6t+VU0WToWnB16qJIhMGcIGPZR7fp/di/0h9Huc+GJBNfbgdVEYiv
7DuF28zzAgMBAAGjUDBOMB0GA1UdDgQWBBRjnMEGZsZR+cSX5/UJcwAZULsKijAf
BgNVHSMEGDAWgBRjnMEGZsZR+cSX5/UJcwAZULsKijAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQBNrPOgLt1bZPO8283HddeASfzoVK40qqBP0HgLihja
VvABPRkE2046lka6MSDXJTpbg9rMT/JDplWea4gCroD+UX79W/r2WBEHgJ63piq+
wVFoxB4S8IgbQi2N5CEM/yLexWq9O2YDl7gemRc1EES01x64YBlBgHGpMvc6NyjD
ecMdTmUAXgNTTGKlpistVRtArQHaqw3FJE3LfoyEx9fP0joA7Q5U7Z6pvveYXEHl
fSoCeI4UUPOlAGBOR5VWnDYuS+FwB9RIcegycxB12Sd+RLxojpFg6VSk2SSiG9/4
u02uKxgXiZ7/41lHjoTHS9BOoPOT0ZD8C7Goeg8OAMgs
-----END CERTIFICATE-----`)

	keyBytes := []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAn8kIsE8QG3Ohyemgeja5g2KFVAalmeJ42ckKp4X9Gb6ahofK
aTIl44riY5+9qSWB5zqkUDYCQzYQGV+SrSf2COF2zq7iVN01l/ypxp+5fEyeRRZp
yVh6ISdH/f/rlb9IYr0ZElVMIfqtnk6SjcqTbtin/Iohlt3TDmNQmFsVp5LDNcaG
lild5loDKkanI+JMi09bfFHLToSoYJtOBzzU3hQpHJh9yLiIlQIt7lVPswynnPPn
MUhx5p5tIqYZvI6U9DozUhlrexe/jTYSGthTiPi8+rflVNFk6FpwdeqiSITBnCBj
2Ue36f3Yv9IfR7nPhiQTX24HVRGIr+w7hdvM8wIDAQABAoIBADrEjdWKvrnaBZ9l
tgg9KG4SRkdpSm8WxKwVLT4AId7eI6dnOiMGtrjB1BIgJnmXufd5sgVuV9awg6tR
Y3kcQXlys2fBGq1rztJfs3HCPU5iP7PZUn8jc4fOEsRw5AznlY/7TMVZae71a/XV
oEFWSHN0bBSOGVyLqZyZGoNuvMAsvZ7ObmfAddLQerPV0nOvv9X332wgo2a+8rnb
NHqcZOLdmGjJRkBbAd0IHFciynb1YlhHIEObmZzD8LVFV0UxhhPDHbRwmrj1T2+j
u9U3rBduJKG+mQxelLOLUB6CNbvcyNtj3wAnyq6IVA9qb/CLXJbEhTgnvNTLnYA3
FJxZysECgYEAzw67MVhQY1VZnN49NiXhhl6ypVIlp3fKOUMMZVgiUeSDPSs4Un9q
ABoFBHT9x/Rs6repl/Yr6V3o8uWz/7V7yArom9/yhErunW8bORfiGVUqibYIKi51
qNJMpamQGI/Uw2AbKCjKhpnCcRjt0YTfuTWXxAxOPYNJZqXEvUaUoNUCgYEAxY3P
H07aR2zTDfjvddG2eieaMLoaTWSuGTUH1P7KplQHEsoE135PyLayzYy5I2HX+JDn
fUDDWXWeI4+NdGdUnRrXOedr/Rewu8RZFxxqBV0TJhmTJzGpoun08YXkj7CBCs60
faohJS5iSpi39XNf2k5/RJHGm2FePfPYQR7sWqcCgYEAx6LYcZdIyr18DXdpZU/Y
xgmADU3K6FDjNZqj1QLI9FRzBQMq5r/aoAZ2V/nExomwig5TAiVj6TmWZLt8dUux
8QozhDbESTFGJ5z8jmusn+gxf113OdRZtVAufnuiZ0wmQ8nh5TKPMoAFra3vfley
rYwyq9+BgGWY29NwgV4P55ECgYB5ThRqkw6xYP9PyxWu8PDtnTeux/eyoinNTKTc
gv+Ilnwpa2cBs4vmIVk1oj1knoXxGXkrjgLmAbTy/QjM+04Xkg2qfpHuvQdGpNBX
wpjPZlGFyZp0LKiPYr2HOMIaATWbn0VxDHCB1jOAvrnmu8uVzzGStziO3IDz5bFa
e1SCbQKBgGNUKKppH7BYDMrb+dqRsB6YI5mFlHZoDhVWkPgDba8klp/NvhTI8ACu
URVaPLlgTRdiG2Q5NVDYPpTrhsCbKwE6HeshNKqhL/VsrK77/oSpSQHeLf88oBV2
rDFpN/In31Wp6c+C4crPQNSWZ9jMohHQkCFOUAyBc6UzcqCa4vqd
-----END RSA PRIVATE KEY-----`)

	keyPair, err := tls.X509KeyPair(certBytes, keyBytes)
	if err != nil {
		failOnError(err, "无法加载密钥对")
	}
	keyStore := dsig.TLSCertKeyStore(keyPair)

	signingContext := dsig.NewDefaultSigningContext(keyStore)
	signingContext.Canonicalizer = dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList("xml")
	if err = signingContext.SetSignatureMethod(dsig.RSASHA256SignatureMethod); err != nil {
		failOnError(err, "设置签名方法失败")
	}

	elementToSign := &etree.Element{
		Tag: "ExampleElement",
	}
	elementToSign.CreateAttr("ID", "id1234")

	signedAssertionEl, err := signingContext.SignEnveloped(elementToSign)
	if err != nil {
		failOnError(err, "签名失败")
	}

	var signedAssertionBuf []byte
	{
		doc := etree.NewDocument()
		doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`)
		doc.SetRoot(signedAssertionEl)
		signedAssertionBuf, err = doc.WriteToBytes()
		if err != nil {
			failOnError(err, "将文档转换为字节失败")
		}
	}

	ioutil.WriteFile("/tmp/test/example.xml", signedAssertionBuf, 0775)
}
英文:

The code below weirdly adds an xmlns attribute to the root element when marshalling the XML. From what I have read the xmlns attribute should not be explicitly set. But the resulting XML includes the xmlns attribute:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ExampleElement xmlns=&quot;http://www.w3.org/XML/1998/namespace&quot; ID=&quot;id1234&quot;&gt;
...

When attempting to validate the XML signature with XMLSecTool I receive the following error:

> org.xml.sax.SAXParseException: The prefix "xml" cannot be bound to any
> namespace other than its usual namespace; neither can the namespace
> for "xml" be bound to any prefix other than "xml".

Is there a valid xmlns attribute value I can use or am I using the libraries incorrectly?

package main
import (
&quot;crypto/rsa&quot;
&quot;crypto/tls&quot;
&quot;io/ioutil&quot;
&quot;log&quot;
&quot;github.com/beevik/etree&quot;
&quot;github.com/russellhaering/goxmldsig&quot;
)
type X509KeyStore struct {
PrivateKey *rsa.PrivateKey
Cert       []byte
}
func (ks X509KeyStore) GetKeyPair() (*rsa.PrivateKey, []byte, error) {
return ks.PrivateKey, ks.Cert, nil
}
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf(&quot;%s: %s&quot;, msg, err)
}
}
func main() {
certBytes := []byte(`-----BEGIN CERTIFICATE-----
MIID3TCCAsWgAwIBAgIJAKMxnSbqmztEMA0GCSqGSIb3DQEBCwUAMIGEMQswCQYD
VQQGEwJHQjETMBEGA1UECAwKQmlybWluZ2hhbTETMBEGA1UEBwwKQmlybWluZ2hh
bTEOMAwGA1UECgwFVGFsaXMxDjAMBgNVBAsMBVRhbGlzMQ4wDAYDVQQDDAVUYWxp
czEbMBkGCSqGSIb3DQEJARYMbXdAdGFsaXMuY29tMB4XDTE3MDgwODIxNTA0NFoX
DTI3MDgwNjIxNTA0NFowgYQxCzAJBgNVBAYTAkdCMRMwEQYDVQQIDApCaXJtaW5n
aGFtMRMwEQYDVQQHDApCaXJtaW5naGFtMQ4wDAYDVQQKDAVUYWxpczEOMAwGA1UE
CwwFVGFsaXMxDjAMBgNVBAMMBVRhbGlzMRswGQYJKoZIhvcNAQkBFgxtd0B0YWxp
cy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCfyQiwTxAbc6HJ
6aB6NrmDYoVUBqWZ4njZyQqnhf0ZvpqGh8ppMiXjiuJjn72pJYHnOqRQNgJDNhAZ
X5KtJ/YI4XbOruJU3TWX/KnGn7l8TJ5FFmnJWHohJ0f9/+uVv0hivRkSVUwh+q2e
TpKNypNu2Kf8iiGW3dMOY1CYWxWnksM1xoaWKV3mWgMqRqcj4kyLT1t8UctOhKhg
m04HPNTeFCkcmH3IuIiVAi3uVU+zDKec8+cxSHHmnm0iphm8jpT0OjNSGWt7F7+N
NhIa2FOI+Lz6t+VU0WToWnB16qJIhMGcIGPZR7fp/di/0h9Huc+GJBNfbgdVEYiv
7DuF28zzAgMBAAGjUDBOMB0GA1UdDgQWBBRjnMEGZsZR+cSX5/UJcwAZULsKijAf
BgNVHSMEGDAWgBRjnMEGZsZR+cSX5/UJcwAZULsKijAMBgNVHRMEBTADAQH/MA0G
CSqGSIb3DQEBCwUAA4IBAQBNrPOgLt1bZPO8283HddeASfzoVK40qqBP0HgLihja
VvABPRkE2046lka6MSDXJTpbg9rMT/JDplWea4gCroD+UX79W/r2WBEHgJ63piq+
wVFoxB4S8IgbQi2N5CEM/yLexWq9O2YDl7gemRc1EES01x64YBlBgHGpMvc6NyjD
ecMdTmUAXgNTTGKlpistVRtArQHaqw3FJE3LfoyEx9fP0joA7Q5U7Z6pvveYXEHl
fSoCeI4UUPOlAGBOR5VWnDYuS+FwB9RIcegycxB12Sd+RLxojpFg6VSk2SSiG9/4
u02uKxgXiZ7/41lHjoTHS9BOoPOT0ZD8C7Goeg8OAMgs
-----END CERTIFICATE-----`)
keyBytes := []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAn8kIsE8QG3Ohyemgeja5g2KFVAalmeJ42ckKp4X9Gb6ahofK
aTIl44riY5+9qSWB5zqkUDYCQzYQGV+SrSf2COF2zq7iVN01l/ypxp+5fEyeRRZp
yVh6ISdH/f/rlb9IYr0ZElVMIfqtnk6SjcqTbtin/Iohlt3TDmNQmFsVp5LDNcaG
lild5loDKkanI+JMi09bfFHLToSoYJtOBzzU3hQpHJh9yLiIlQIt7lVPswynnPPn
MUhx5p5tIqYZvI6U9DozUhlrexe/jTYSGthTiPi8+rflVNFk6FpwdeqiSITBnCBj
2Ue36f3Yv9IfR7nPhiQTX24HVRGIr+w7hdvM8wIDAQABAoIBADrEjdWKvrnaBZ9l
tgg9KG4SRkdpSm8WxKwVLT4AId7eI6dnOiMGtrjB1BIgJnmXufd5sgVuV9awg6tR
Y3kcQXlys2fBGq1rztJfs3HCPU5iP7PZUn8jc4fOEsRw5AznlY/7TMVZae71a/XV
oEFWSHN0bBSOGVyLqZyZGoNuvMAsvZ7ObmfAddLQerPV0nOvv9X332wgo2a+8rnb
NHqcZOLdmGjJRkBbAd0IHFciynb1YlhHIEObmZzD8LVFV0UxhhPDHbRwmrj1T2+j
u9U3rBduJKG+mQxelLOLUB6CNbvcyNtj3wAnyq6IVA9qb/CLXJbEhTgnvNTLnYA3
FJxZysECgYEAzw67MVhQY1VZnN49NiXhhl6ypVIlp3fKOUMMZVgiUeSDPSs4Un9q
ABoFBHT9x/Rs6repl/Yr6V3o8uWz/7V7yArom9/yhErunW8bORfiGVUqibYIKi51
qNJMpamQGI/Uw2AbKCjKhpnCcRjt0YTfuTWXxAxOPYNJZqXEvUaUoNUCgYEAxY3P
H07aR2zTDfjvddG2eieaMLoaTWSuGTUH1P7KplQHEsoE135PyLayzYy5I2HX+JDn
fUDDWXWeI4+NdGdUnRrXOedr/Rewu8RZFxxqBV0TJhmTJzGpoun08YXkj7CBCs60
faohJS5iSpi39XNf2k5/RJHGm2FePfPYQR7sWqcCgYEAx6LYcZdIyr18DXdpZU/Y
xgmADU3K6FDjNZqj1QLI9FRzBQMq5r/aoAZ2V/nExomwig5TAiVj6TmWZLt8dUux
8QozhDbESTFGJ5z8jmusn+gxf113OdRZtVAufnuiZ0wmQ8nh5TKPMoAFra3vfley
rYwyq9+BgGWY29NwgV4P55ECgYB5ThRqkw6xYP9PyxWu8PDtnTeux/eyoinNTKTc
gv+Ilnwpa2cBs4vmIVk1oj1knoXxGXkrjgLmAbTy/QjM+04Xkg2qfpHuvQdGpNBX
wpjPZlGFyZp0LKiPYr2HOMIaATWbn0VxDHCB1jOAvrnmu8uVzzGStziO3IDz5bFa
e1SCbQKBgGNUKKppH7BYDMrb+dqRsB6YI5mFlHZoDhVWkPgDba8klp/NvhTI8ACu
URVaPLlgTRdiG2Q5NVDYPpTrhsCbKwE6HeshNKqhL/VsrK77/oSpSQHeLf88oBV2
rDFpN/In31Wp6c+C4crPQNSWZ9jMohHQkCFOUAyBc6UzcqCa4vqd
-----END RSA PRIVATE KEY-----`)
keyPair, err := tls.X509KeyPair(certBytes, keyBytes)
if err != nil {
failOnError(err, &quot;invalided to load keypair&quot;)
}
keyStore := dsig.TLSCertKeyStore(keyPair)
signingContext := dsig.NewDefaultSigningContext(keyStore)
signingContext.Canonicalizer = dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList(&quot;xml&quot;)
if err = signingContext.SetSignatureMethod(dsig.RSASHA256SignatureMethod); err != nil {
failOnError(err, &quot;failed to set signature method&quot;)
}
elementToSign := &amp;etree.Element{
Tag: &quot;ExampleElement&quot;,
}
elementToSign.CreateAttr(&quot;ID&quot;, &quot;id1234&quot;)
signedAssertionEl, err := signingContext.SignEnveloped(elementToSign)
if err != nil {
failOnError(err, &quot;failed to sign envelop&quot;)
}
var signedAssertionBuf []byte
{
doc := etree.NewDocument()
doc.CreateProcInst(&quot;xml&quot;, `version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;`)
doc.SetRoot(signedAssertionEl)
signedAssertionBuf, err = doc.WriteToBytes()
if err != nil {
failOnError(err, &quot;failed to convert doc to bytes&quot;)
}
}
ioutil.WriteFile(&quot;/tmp/test/example.xml&quot;, signedAssertionBuf, 0775)
}

答案1

得分: 3

您的命名空间设置不正确。请参考xml命名空间

在这里添加命名空间:

elementToSign := &amp;etree.Element{
Tag: &quot;ExampleElement&quot;,
Space: &quot;xml&quot;,
}
elementToSign.CreateAttr(&quot;ID&quot;, &quot;id1234&quot;)

添加了这一行后,它将通过验证。使用XML验证器进行测试。

英文:

Your namespace is not correctly set. See also xml namespace

Add the namespace here:

elementToSign := &amp;etree.Element{
Tag: &quot;ExampleElement&quot;,
Space: &quot;xml&quot;,
}
elementToSign.CreateAttr(&quot;ID&quot;, &quot;id1234&quot;)

With the added line it will pass validation. Tested with XML Validator

huangapple
  • 本文由 发表于 2017年8月13日 03:56:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/45654383.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定