SAML EncryptedAssertion解密失败

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SAML EncryptedAssertion解密失败相关的知识,希望对你有一定的参考价值。

我正在使用SAML实现SP。当我尝试解密EncryptedAssertion时,我收到以下错误。

org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData
at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:546)
at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:453)
at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:414)
at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)

我找了这个错误而且找不到多少。我也更新了我的JCE罐子。我正在使用opensaml

我能够获得SAML响应并能够验证/验证签名。在解密断言时我遇到了错误。

代码细节

//迭代加密断言

List<EncryptedAssertion> encryptedAssertions = response.getEncryptedAssertions();
    if (encryptedAssertions.size() > 0) {
        for (EncryptedAssertion encryptedAssertion : encryptedAssertions) {
            Assertion assertion = decryptAssertion(encryptedAssertion);
            ... 
        }
    }

该方法解密断言。在此方法中出错

private Assertion decryptAssertion(EncryptedAssertion assertion) throws 
 CertificateException, KeyException
        {
    Assertion ast = null;
    Decrypter decrypter = buildAssertionDecrypter();
 try{
    ast = decrypter.decrypt(assertion);  // <-- Getting ERROR Here  
    }catch (DecryptionException e) {
        e.printStackTrace();
    }
   return ast;
}

下面的方法构建解密器

    private  Decrypter buildAssertionDecrypter() throws CertificateException, KeyException {

    List<EncryptedKeyResolver> list = new ArrayList<>();
    list.add(new InlineEncryptedKeyResolver());
    list.add(new EncryptedElementTypeEncryptedKeyResolver());
    list.add(new SimpleRetrievalMethodEncryptedKeyResolver());
    final ChainingEncryptedKeyResolver encryptedKeyResolver = new ChainingEncryptedKeyResolver();
    encryptedKeyResolver.getResolverChain().addAll(list);
    final KeyInfoCredentialResolver resolver = new StaticKeyInfoCredentialResolver(buildCredentials());       
    Decrypter decrypter = new Decrypter(null, resolver, encryptedKeyResolver);
    return decrypter;
}

构建凭证方法

public Credential buildCredentials() throws CertificateException, KeyException {
    X509Certificate cert = getPublicCert();
    PrivateKey privateKey = getPrivateKey();
    BasicX509Credential decryptionCredential = SecurityHelper.getSimpleCredential(cert, privateKey);
     return decryptionCredential;       
}

加载公钥/私钥

public X509Certificate getPublicCert(){
    X509Certificate cer = null;
    try{
        CertificateFactory fact = CertificateFactory.getInstance("X.509");
        FileInputStream is = new FileInputStream ("pubkey.cer");
        cer = (X509Certificate) fact.generateCertificate(is);

    } catch (Exception e) {
        e.printStackTrace();
    } 
    return cer;
}

public RSAPrivateKey getPrivateKey(){
    Key key = null;
    RSAPrivateKey privateKey = null;
    try {
        KeyStore ks = KeyStore.getInstance("pkcs12", "SunJSSE");         
        ks.load(new FileInputStream("prvkey.pfx"),"".toCharArray());
         Enumeration<String> aliases = ks.aliases();
         while(aliases.hasMoreElements()){
             String alias = aliases.nextElement();
             key  = ks.getKey(alias, "".toCharArray());
        }
         privateKey = (RSAPrivateKey)key;
} catch (Exception e) {
    e.printStackTrace();
} 
    return privateKey;
}

我已经验证了公钥和私钥。我拿了示例SAML并使用PUBLIC密钥加密,然后使用加密的SAML令牌并使用私钥解密。我得到了相同的样本SAML。我使用在线saml工具来做到这一点。

EncryptedAssertion SAML

<saml:EncryptedAssertion>
<xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" Type="http://www.w3.org/2001/04/xmlenc#Element">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<dsig:KeyInfo xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedKey>
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
<xenc:CipherData>
<xenc:CipherValue>Some Value</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
</dsig:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>Value</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</saml:EncryptedAssertion>
答案

我尝试了不同的方法,并手动实现了解密逻辑。这是我的帖子 - Decryption of EncryptedAssertion manually的链接

另一答案

对我来说,当我的未加密的SAMPL响应无效时,我遇到了类似的问题。这是因为<saml:Assertion>没有有效的命名空间定义。我不得不插入命名空间声明<saml:Assertion xmlns =“urn:oasis:names:tc:SAML:2.0:assertion”> ....使其工作。参见问题2 HERE。我不确定你是否有同样的问题。但这对我来说是个问题。

以上是关于SAML EncryptedAssertion解密失败的主要内容,如果未能解决你的问题,请参考以下文章

解密 Saml 令牌时出错

无法解密 EncryptedData (SAML2)

使用 OpenSAML 在 Java 中使用 SAML 2.0 解密加密断言

Spring SAML:解密加密密钥时出错,没有安装的提供程序支持此密钥

在 MVC 的 Idp 发起的 SSO 环境中使用 WIF

Spring-SAML:传入的 SAML 消息无效