【问题标题】:How to sign an saml 2.0 assertion using the openssl (.PCKS8) file如何使用 openssl (.PCKS8) 文件签署 saml 2.0 断言
【发布时间】:2013-05-06 13:35:16
【问题描述】:

您好,我需要一些有关 saml 2.0 Authn Request 的信息。我想用 openssl 创建的 *.pkcs8 文件签署我的 authn 请求。我可以使用 java keytool 处理密钥库文件。但是我想使用 openssl 生成的 *.PKCS8 文件来实现相同的目的。我已经为此苦苦挣扎了一段时间。我可以用它生成 xml。

// 验证请求 ...

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" AssertionConsumerServiceURL="http://localhost:8080/sp/AssertionConsumerService" Destination="http://localhost:8080/idp/SingleSignOnService" ID="95cc3943-67dd-43ef-809b-2ccd8bd3e4e9" IssueInstant="2013-04-26T12:18:48.799Z" Version="2.0">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">sp</saml:Issuer>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <ds:Reference URI="#95cc3943-67dd-43ef-809b-2ccd8bd3e4e9">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
          <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
            <ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" 
              PrefixList="ds saml samlp"/>
           </ds:Transform>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <ds:DigestValue>2HkVe/KnVzcMgneRUItjq2V/FEA=</ds:DigestValue>
       </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>
           NjCxy8R3NjkN8B932FJolGTqtYTBBTLboHUo7ZqEXxICUW/ZhOV2Pwe+c4R0/TrPqBPVZBItlXyv
           at3edIMrr7RlEFGy3rt7pPVRXUcmF6jtDZajCpwwaEKKD--REMOVED SOME CODE------------
           egb8dua65WhY1KkugNPG4FWTVhtzul/CBo9a8vN/ZuXRbZQ6sUWbq1BFgC6Zmw8kr1aUNBwqRi7r
           ZNPXcGVhXuFQTTV4Kuc1eiI1lgANKLTrkCBRSw==
   </ds:SignatureValue>
  </ds:Signature>
</samlp:AuthnRequest>

// 结束

我无法获得使用 java keytool 获得的 keyInfo 和 x509data 以及证书值。

    <ds:KeyInfo>
      <ds:X509Data>
        <ds:X509Certificate>hZB2kOYypWs33Bs2BTaKZOKGig0CAwEAATANBgkqhkiG9w0BAQUFAAOB
         gQB3Cfe0iTfrXY9E22TFy5b87kwpDKjLopNLtX3kqSUlfjnbN5tYN4zr91H5dZUkuFF83z7ztzKi
         zkcxiMgVVQkU2X1bn5SdErvmS7aEcG8+5TdlO5bf+8as04u5qug+oQun5s1t9mSvaF7Ol5CX/gkp
         EUTjXx28kldbY7ETgDUrSw==</ds:X509Certificate>
      </ds:X509Data>
     </ds:KeyInfo>
   </ds:Signature>

还告诉我我的 Authn Request complete 。 Artifact 和 POST(Assertion) saml 消息的 Authn 请求也相同

请帮忙!!!

【问题讨论】:

    标签: java saml opensaml


    【解决方案1】:

    你是如何构建你的org.opensaml.xml.security.credential.Credential 对象的? 您只能从 PKCS8 文件加载 private-key。您仍然需要公钥来完全构造 Credential 对象。如果您的公钥存储在 DER 编码字节中,您可以使用以下代码创建 Credential 并使用它来签署请求

    /**
     * Load privateKeyDerBytes from PKCS8 file and publicKeyDerBytes from .cer, .crt, .der files
     */
    private static Credential getCredential(byte[] privateKeyDerBytes , byte[] publicKeyDerBytes) throws IOException
    {
        PrivateKey privateKey = PKCS8Key.parse(new DerValue( privateKeyDerBytes ));
        PublicKey publicKey = X509Key.parse(new DerValue(publicKeyDerBytes));
        BasicCredential basicCredential = new BasicCredential();
        basicCredential.setUsageType(UsageType.SIGNING);
        basicCredential.setPrivateKey(privateKey);
        basicCredential.setPublicKey(publicKey);
        return basicCredential;
    }
    
    public static void signAssertion(Assertion assertion , byte[] privateKeyDerBytes , byte[] publicKeyDerBytes) throws IOException, SecurityException
    {
        // get Credential 
        Credential credential = getCredential(privateKeyDerBytes, publicKeyDerBytes);
        // create Signature
        Signature signature = (Signature) Configuration.getBuilderFactory().getBuilder(
                Signature.DEFAULT_ELEMENT_NAME).buildObject(
                Signature.DEFAULT_ELEMENT_NAME);
    
        signature.setSigningCredential(credential);
        signature
                .setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
        signature
                .setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);
        signature.setKeyInfo(getKeyInfo(credential));
    
        assertion.setSignature(signature);
    
    }
    
    public static KeyInfo getKeyInfo(Credential credential)
            throws SecurityException {
        SecurityConfiguration secConfiguration = Configuration
                .getGlobalSecurityConfiguration();
        NamedKeyInfoGeneratorManager namedKeyInfoGeneratorManager = secConfiguration
                .getKeyInfoGeneratorManager();
        KeyInfoGeneratorManager keyInfoGeneratorManager = namedKeyInfoGeneratorManager
                .getDefaultManager();
        KeyInfoGeneratorFactory factory = keyInfoGeneratorManager
                .getFactory(credential);
        KeyInfoGenerator generator = factory.newInstance();
        return generator.generate(credential);
    
    }
    

    【讨论】:

    • 谢谢 nadirsaghar 。我会检查您的建议并回复您。
    【解决方案2】:

    你可以用它来输出keyinfo

    X509KeyInfoGeneratorFactory fact = new X509KeyInfoGeneratorFactory();
    fact.setEmitEntityCertificate(true);
    signature.setKeyInfo(fact.newInstance().generate(cred));
    

    【讨论】:

    • 只是为了确认我是这样做的。 '签名签名 = (Signature) Configuration.getBuilderFactory() .getBuilder(Signature.DEFAULT_ELEMENT_NAME) .buildObject(Signature.DEFAULT_ELEMENT_NAME); X509KeyInfoGeneratorFactory 事实 = 新 X509KeyInfoGeneratorFactory(); fact.setEmitEntityCertificate(true);尝试 { signature.setKeyInfo(fact.newInstance().generate(signingCredential)); } catch (SecurityException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } samlMessage.setSignature(签名);'
    • 你以前也是这么做的吗?
    • 没有。我只是拿了你的代码并试图以这种方式添加它。但它没有生成所需的密钥信息(使用 x506cert)。实际上需要将 Keyinfo 设置为 credential 。我不确定是否可行
    • 一旦我获得了签名证书。这是我的代码来编码和发送授权请求。
    • HttpServletResponseAdapter outTransport = new HttpServletResponseAdapter(response, false); BasicSAMLMessageContext messageContext = new BasicSAMLMessageContext(); messageContext.setOutboundMessageTransport(outTransport); messageContext.setPeerEntityEndpoint(端点); messageContext.setOutboundSAMLMessage(samlMessage); messageContext.setOutboundMessageIssuer(发布实体名称); messageContext.setRelayState(clientId); messageContext.setOutboundSAMLMessageSigningCredential(signingCredential);encoder.encode(messageContext);
    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多