java - 如何在签名的xml中将<keyvalue>附加到<x509data>之前

时间:2017-10-02 09:34:46

标签: java digital-signature signed signedxml

现在我正在使用数字签名进行编程,当我生成签名时我遇到了问题。我首先添加了KeyValue,然后添加X509Data,但标签只是先附加。 我有一个用于创建signinfo的代码:

private KeyInfo createKeyInfo(PublicKey publicKey, X509Certificate x509Certificate) throws KeyException {
    KeyInfoFactory keyInfoFactory = factory.getKeyInfoFactory();
    KeyInfo keyInfo = null;
    KeyValue keyValue = null;
    List items = null;
    //Just with public key
    if(publicKey != null){
        keyValue = keyInfoFactory.newKeyValue(publicKey);
        keyInfo = keyInfoFactory.newKeyInfo(singletonList(keyValue));
    }

    if(x509Certificate != null){
        List x509list = new ArrayList();

        x509list.add(x509Certificate.getSubjectX500Principal().getName());
        x509list.add(x509Certificate);
        X509Data x509Data = keyInfoFactory.newX509Data(x509list);
        items = new ArrayList();

        items.add(x509Data);
        if(keyValue != null){
            items.add(keyValue);
        }
        keyInfo = keyInfoFactory.newKeyInfo(items);
    }

    return keyInfo;
}

结果是:

<KeyInfo>
          <X509Data>
            <X509SubjectName>name</X509SubjectName>
            <X509Certificate>
              base 64 encode
            </X509Certificate>
          </X509Data>
          <KeyValue>
            <RSAKeyValue>
              <Modulus>
               base 64 encode key
              </Modulus>
              <Exponent>AQAB</Exponent>
            </RSAKeyValue>
          </KeyValue>
        </KeyInfo>

我希望结果是:

<KeyInfo>
          <KeyValue>
            <RSAKeyValue>
              <Modulus>
                base 64 encode
              </Modulus>
              <Exponent>AQAB</Exponent>
            </RSAKeyValue>
          </KeyValue>
          <X509Data>
            <X509SubjectName>Name</X509SubjectName>
            <X509Certificate>
              base 64 endcode
            </X509Certificate>
          </X509Data>
        </KeyInfo>

谁能帮助我。非常感谢你!

2 个答案:

答案 0 :(得分:0)

您不应该考虑<X509Data><KeyValue>之间的顺序。 XSD坚持它们可以按任何顺序出现

https://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#

<element name="KeyInfo" type="ds:KeyInfoType"/>
<complexType name="KeyInfoType" mixed="true">
   <choice maxOccurs="unbounded">
      <element ref="ds:KeyName"/>
      <element ref="ds:KeyValue"/>
      <element ref="ds:RetrievalMethod"/>
      <element ref="ds:X509Data"/>
      <element ref="ds:PGPData"/>
      <element ref="ds:SPKIData"/>
      <element ref="ds:MgmtData"/>
      <any processContents="lax" namespace="##other"/>
      <!--  (1,1) elements from (0,unbounded) namespaces  -->
    </choice>
    <attribute name="Id" type="ID" use="optional"/>
</complexType>

答案 1 :(得分:0)

在智利,内部税务服务也存在同样的问题。当KeyValue在x509证书之后时,验证失败。虽然它不应该根据XSD进行排序,但可以使用另一个列表实现来解决,使用有序列表。

您需要更改

List x509list = new ArrayList();

LinkedList x509list = new LinkedList();

并在添加元素时反转顺序

 if(keyValue != null){
       items.add(keyValue);
 }
 items.add(x509Data);