我对XML文件进行数字签名,但需要签名标记包含名称空间前缀“ds”。我在谷歌上搜索了一下,发现了很多同样的问题,但没有令人满意的答案。
我尝试将“ds”手动放入文件中,但签名变得无效。标记“SignatureValue”对标记“SignedInfo”进行签名,因此签名无效。
谁能告诉我如何生成标记“signaturevalue”的值,以便在添加前缀“ds”后替换签名?
显然很多人都遇到了同样的问题。在调查了类签名的源代码后,我得出结论,微软的目的是帮助我们。方法LoadXml()中有硬编码的前缀“ds”。因此,可以生成签名,然后向其添加名称空间前缀“ds”,加载修改后的签名并重新计算“signaturevalue”。不幸的是,库中的bug使事情变得比需要的要难一些。下面是带有变通方法和注释的代码。
public static void SignXml(XmlDocument xmlDoc, X509Certificate2 cert)
{
// transformation cert -> key omitted
RSACryptoServiceProvider key;
// Create a SignedXml object.
SignedXml signedXml = new SignedXml(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "#foo";
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// Add an enveloped transformation to the reference.
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
signedXml.AddReference(reference);
KeyInfo keyInfo = new KeyInfo();
KeyInfoX509Data keyInfoData = new KeyInfoX509Data();
keyInfoData.AddIssuerSerial(cert.IssuerName.Format(false), cert.SerialNumber);
keyInfo.AddClause(keyInfoData);
signedXml.KeyInfo = keyInfo;
// Compute the signature.
signedXml.ComputeSignature();
// Add prefix "ds:" to signature
XmlElement signature = signedXml.GetXml();
SetPrefix("ds", signature);
// Load modified signature back
signedXml.LoadXml(signature);
// this is workaround for overcoming a bug in the library
signedXml.SignedInfo.References.Clear();
// Recompute the signature
signedXml.ComputeSignature();
string recomputedSignature = Convert.ToBase64String(signedXml.SignatureValue);
// Replace value of the signature with recomputed one
ReplaceSignature(signature, recomputedSignature);
// Append the signature to the XML document.
xmlDoc.DocumentElement.InsertAfter(xmlDoc.ImportNode(signature, true), xmlDoc.DocumentElement.FirstChild);
}
private static void SetPrefix(string prefix, XmlNode node)
{
node.Prefix = prefix;
foreach (XmlNode n in node.ChildNodes)
{
SetPrefix(prefix, n);
}
}
private static void ReplaceSignature(XmlElement signature, string newValue)
{
if (signature == null) throw new ArgumentNullException(nameof(signature));
if (signature.OwnerDocument == null) throw new ArgumentException("No owner document", nameof(signature));
XmlNamespaceManager nsm = new XmlNamespaceManager(signature.OwnerDocument.NameTable);
nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
XmlNode signatureValue = signature.SelectSingleNode("ds:SignatureValue", nsm);
if (signatureValue == null)
throw new Exception("Signature does not contain 'ds:SignatureValue'");
signatureValue.InnerXml = newValue;
}
我正在从jaxb模型生成rest响应(使用Jersey)。对于某些响应,生成的XML将名称空间前缀(ns2)添加到名称空间属性中,尽管它们都存在于同一个名称空间中。但对其他人来说,这完全没问题。 根据我的分析,我认为当一个复杂元素(另一个jaxb模型)在其中使用时会发生这种情况。但所有这些模型都在package-info.java中的相同名称空间中声明。 这是代码。 XYZModel.class
我正在尝试使用 JAXB 创建站点地图索引文件。按照创建站点地图的要求,我必须在根元素中添加命名空间属性: 我想有一个简单的方法来解决这个问题。因为这似乎是一个标准过程,所以我不想做复杂的解决方法,也不想在我的项目中添加更多的依赖项来解决这个问题 当前输出如下: 我的< code>SitemapIndex模型如下: 我还尝试手动添加名称空间字段,它可以生成文件,但是当我尝试读取文件时会出现异常。
我有一个有趣的情况,我的XML编辑器(Oxygen,使用Xerces XML处理器)需要根标签上的前缀,但是我的JAXB XML Marshaller(也是基于Xerces的)不需要根标签上的前缀。我正在试图理解这种情况。 首先是2个模式文件: ns1.xsd ns2。xsd 目前的氧气释放(16.1)需要我称之为“版本1”的东西 版本1 如果我像下面的示例(版本1)那样删除前缀: 版本2 氧气抱
我收到看起来像这样xml: 我想把它分解成对象。 我创建了以下bean: 解组后,我得到了一个对象,它被成功填充,除了blackListArray字段。该字段包含列表,其中只有一项。并且该项中的所有字段都为空。 似乎JAXB可以找到元素,但错过了其中的所有内部元素。 我使用MOXy作为JAXB实现。 附言 我试着把包裹信息放进去。java与我的bean在文件夹中,如该问题所示 但这对我没有帮助。
面临使用JAXB解组的问题。我需要使用多个名称空间。Java类是为第三方提供的XSD生成的。因此,我不想在Java类中的XMLRootElement指定名称空间,也不想手动更改多个类。 编组逻辑如下: xmlelement类TokenRequest.java BasicInRequestType.java 我在package-info.java中指定了前缀 TokenRequest元素实际上引用了
尝试基于两个唯一的字符串生成客户端Id。这应该与服务器中从相同的ID生成的UUID相同。 使用Javascript,它看起来像这样: 似乎找不到在Swift上生成这个的方法,NSUUID只能从无到有生成UUID 我正在寻找这样的东西: 编辑 例: