2

ECDSAを使用するSiganturesを検証するためにBouncyCastleを使用してXMLSignatureをチェックすることに問題があります。

関連するコード行は次のとおりです。

BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);   
//some unrelated code
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM", provider);

最後の行で、次の例外がスローされます。

javax.xml.crypto.NoSuchMechanismException: java.security.NoSuchAlgorithmException: no such algorithm: DOM for provider SC

行をに変更すると

XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");

私は得る

javax.xml.crypto.MarshalException: unsupported SignatureMethod algorithm: http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160

誰かがこれを引き起こす原因について何かアイデアを持っていますか?

4

2 に答える 2

3

最初のエラーでは、「そのようなアルゴリズムはありません:プロバイダーSCのDOM」というエラーの説明を読むことができます。「プロバイダーSC」(Sun PC / SCプロバイダー)と表示され、「プロバイダーBC」(BouncyCastleセキュリティプロバイダー)とは表示されないため、これは奇妙なことです。コードが(内部的に)Bouncycastleを希望どおりに使用していないようです。なぜこれが起こっているのかを知る必要があります。これは、BCライブラリとクラスパス(アプリケーションサーバーを使用している場合)またはプロバイダーの注文構成に関するものである可能性があります。

2番目のエラー。XMLSignatureFactoryを取得するアプローチを変更します。プロバイダーを指定しない場合は、次の理由から、これが優れています。

このメソッドは、標準のJCAプロバイダールックアップメカニズムを使用して、目的のメカニズムタイプのXMLSignatureFactory実装を見つけてインスタンス化します。登録されているセキュリティプロバイダーのリストを、最も優先されるプロバイダーから順にトラバースします。指定されたメカニズムをサポートする最初のプロバイダーからの新しいXMLSignatureFactoryオブジェクトが返されます。

しかし今、アルゴリズムはありません。なぜ?ここでは、BCは使用されていないと言えます。ありますか?クラスパスを確認します。

利用可能なすべてのプロバイダーを一覧表示すると役立つ場合があります。

for (Provider p : Security.getProviders()) {

    log.debug(p.getName());
    log.debug(p.getInfo());
}
于 2012-07-30T07:22:30.087 に答える
1

2番目の例外から推測すると、xml署名を検証するため、次のようなコードを使用している可能性があります。https://www.massapi.com/class/xm/XMLSignatureFactory-2.htmlのコード

// Step 1: Load an XMLSignatureFactory instance. This factory class will
// be responsible for constructing almost all the major objects we need
// in working with XML Signature in JSR-105 APIs, except those related
// to KeyInfo.
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

// Step 3 : Find all Xml Signature element into the provided XML
// document (here for sample use only the first)
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if (nl.getLength() == 0) {
    throw new Exception("Cannot find Signature element!");
}

// Step 4: Create a DOMValidateContext instance (extract public key from
// the "KeyInfo" bloc using overrided KeySelector impl.)
DOMValidateContext valContext = new DOMValidateContext(new KeyValueKeySelector(), nl.item(0));

// Step 5: Unmarshal the Signature node into an XMLSiganture object.
XMLSignature signature = fac.unmarshalXMLSignature(valContext);

// Step 6 : Validate signature
boolean isValid = signature.validate(valContext);
if (isValid) {
    System.out.println("OK");
}

しかし、xml表現には次のようなものがあります

<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>  
            <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>  
            <SignatureMethod Algorithm="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"/>  
            <Reference URI="">  
                <Transforms>  
                        <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>  
                </Transforms>  
                <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>  
                <DigestValue>bHS+6uf8KbJV4AGzoHNHLfnXvKM=</DigestValue>  
            </Reference>  
    </SignedInfo>
    ...
</Signature>

したがって、ファクトリはxml表現をXMLSignatureオブジェクトにアンマーシャリングできませんでした。実際にはプロバイダーからfac提供されたものです。確認してください。クラスのインスタンスです。unmarshallアクションはformオブジェクトを試行し、最初に、などの子オブジェクトを形成する必要があるため、コンストラクターで、最後に例外を発生させる呼び出しに到達します。org.jcp.xml.dsig.internal.dom.XMLDSigRI$JRE_HOME/lib/security/java.securityfacDOMXMLSignatureFactorySignatureCanonicalizationMethodSignatureMethodDOMSignedInfoDOMSignedInfo(Element var1, XMLCryptoContext var2, Provider var3) throws MarshalException

Element var5 = DOMUtils.getNextSiblingElement(var4, "SignatureMethod");
this.signatureMethod = DOMSignatureMethod.unmarshal(var5);

DOMSignatureMethod.unmarshal静的メソッドへのもう1つのステップでhttp://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160、デジタル署名アルゴリズムの検索に使用されますがDOMSignatureMethod、サポートされるのは次のアルゴリズムのみです。

rsa-sha1
rsa-sha256
rsa-sha384
rsa-sha512
dsa-sha1
dsa-sha256
hmac-sha1
hmac-sha256
hmac-sha384
hmac-sha512
ecdsa-sha1
ecdsa-sha256
ecdsa-sha384
ecdsa-sha512

および解決策:セキュリティにBCプロバイダーを追加し、org.apache.santuario-xmlsecプロジェクトのXMLSignatureを使用して検証します。

public boolean verify(String signedXML) throws Exception {
    Document doc = null;
    try (InputStream is = new ByteArrayInputStream(signedXML.getBytes(Charset.forName("utf-8")))) {
        doc = MyXMLUtils.read(is, false);
    }

    XPathFactory xpf = XPathFactory.newInstance();
    XPath xpath = xpf.newXPath();
    xpath.setNamespaceContext(new DSNamespaceContext());

    String expression = "//ds:Signature[1]";
    Element sigElement =
            (Element) xpath.evaluate(expression, doc, XPathConstants.NODE);

    XMLSignature signature = new XMLSignature(sigElement, "");
    KeyInfo ki = signature.getKeyInfo();

    if (ki == null) {
        throw new RuntimeException("No keyinfo");
    }
    PublicKey pk = signature.getKeyInfo().getPublicKey();

    if (pk == null) {
        throw new RuntimeException("No public key");
    }

    return signature.checkSignatureValue(pk);
}

リポジトリからのその他のデモ:https ://github.com/Honwhy/xml-sec

于 2018-08-31T16:55:17.200 に答える