SAML - 如何正确签署响应(消息)和断言

问题描述 投票:0回答:0

我正在使用 Java8,我尝试了 OpenSAML(v3) 和 OneLogin,但都没有用。

  • 验证检查工具:https://samltool.io/
  • 仅签署断言:有效
  • 仅限签名回复:有效
  • 同时签名:响应签名无效

使用这个网站我试过

  • 两者都签名:有效
  • Sign Assertion > Copy then Sign Response : Valid
  • 通过代码签署断言 > 签署响应:响应签名无效

Response Signature Inavlid Message looks like this“XMLJS0013: Cryptographic error: Invalid digest for uri '$REFERENCE_URI'. Calculated digest is $CALCULATED_DIGESTVALUE but the xml to validate supply digest $MY_DIGESTVALUE”

当我用 $CALCULATED_DIGESTVALUE 手动替换 $MY_DIGESTVALUE 时,错误消息变为 “计算出的签名与消息的签名不匹配。”

/* Methods */
// For OneLogin
private Object stringTOobject(String samlStr) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new ByteArrayInputStream(samlStr.getBytes("UTF-8")));  
    Element samlElement = document.getDocumentElement();
    Unmarshaller unmarshaller = XMLObjectProviderRegistrySupport.getUnmarshallerFactory().getUnmarshaller(samlElement);
    return unmarshaller.unmarshall(samlElement);
}
// For OpenSAML
private <T> T createObject(Class<T> clazz) throws Exception {
    QName defaultElementName = (QName) clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
    Object object = SAMLutil.getSAMLBuilder().getBuilder(defaultElementName).buildObject(defaultElementName);
    return clazz.cast(object);
}
private KeyInfo getKeyInfo(BasicX509Credential basicCredential, HashMap reqMap) throws Exception {
    KeyInfo result = null;
    KeyName keyName = createObject(KeyName.class);
    keyName.setValue($KeyID);
    X509KeyInfoGeneratorFactory kiFactory = new X509KeyInfoGeneratorFactory();
    kiFactory.setEmitEntityCertificate(true);
    result = kiFactory.newInstance().generate(basicCredential);
    result.getKeyNames().add(keyName);
    // To remove linebreaks in Certificate
    result.getX509Datas().get(0).getX509Certificates().get(0).setValue($X509CertificateString);
    return result;
}
private Signature getSig(HashMap reqMap) throws Exception {
    Signature result = createObject(Signature.class);
    BasicX509Credential basicCredential = getBasicX509Credential($X509CertificateString);
    basicCredential.setPrivateKey($PrivateKey);
    KeyInfo keyInfo = getKeyInfo(basicCredential, reqMap);
    result.setKeyInfo(keyInfo);
    result.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
    result.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
    result.setSigningCredential(basicCredential);
    return result;
}

/* OneLogin */
// 1. Sign Assertion > Turn signed string back to Assertion
AssertionMarshaller aMarshaller = new AssertionMarshaller();
String astStr = Util.addSign(aMarshaller.marshall(assertion), privateKey, cert, Constants.RSA_SHA1);
assertion = (Assertion) stringTOobject(astStr);
// 2. Add Assertion into Response
response.getAssertions().add(assertion);
// 3. Sign Response > Turn signed string back to Response
ResponseMarshaller marshaller = new ResponseMarshaller();
String resStr = Util.addSign(marshaller.marshall(response), privateKey, cert, Constants.RSA_SHA1);
response = (Response) stringTOobject(resStr);
// 4. To XMLString
String samlStr = SerializeSupport.nodeToString(marshaller.marshall(response));

/* OpenSAML */
// 1. Sign Assertion
Signature signature = getSig(reqMap);
assertion.setSignature(signature);
((SAMLObjectContentReference)signature.getContentReferences().get(0)).setDigestAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA1);
AssertionMarshaller aMarshaller = new AssertionMarshaller();
aMarshaller.marshall(assertion);
Signer.signObject(signature);
// 2. Add Assertion into Response
response.getAssertions().add(assertion);
// 3. Sign Response
Signature signature = getSig(reqMap);
response.setSignature(signature);
((SAMLObjectContentReference)signature.getContentReferences().get(0)).setDigestAlgorithm(SignatureConstants.ALGO_ID_DIGEST_SHA1);
ResponseMarshaller marshaller = new ResponseMarshaller();
marshaller.marshall(response);
Signer.signObject(signature);
// 4. To XMLString
String samlStr = SerializeSupport.nodeToString(marshaller.marshall(response));

我错过了什么?

任何帮助将不胜感激。

java saml onelogin opensaml
© www.soinside.com 2019 - 2024. All rights reserved.