简体   繁体   English

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

[英]Decrypting encrypted assertion using SAML 2.0 in java using OpenSAML

I have a problem while trying to decrypt encrypted assertion using SAML 2.0. 尝试使用SAML 2.0解密加密断言时遇到问题。 The library I am using is OpenSAML Java libraries 2.5.2. 我使用的库是OpenSAML Java库2.5.2。

The encrypted assertion looks like this: 加密的断言如下所示:

<EncryptedAssertion xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<enc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" 
    xmlns:enc="http://www.w3.org/2001/04/xmlenc#">
  <enc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
  <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
    <e:EncryptedKey xmlns:e="http://www.w3.org/2001/04/xmlenc#">
      <e:EncryptionMethod 
       Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      </e:EncryptionMethod>
      <KeyInfo>
        <o:SecurityTokenReference 
           xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-
                    1.0.xsd">
          <o:KeyIdentifier 
            ValueType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-
                      1.1#ThumbprintSHA1"
            EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-
                      message-security-1.0#Base64Binary">
          1H3mV/pJAlVZAst/Dt0rqbBd67g=
          </o:KeyIdentifier>
        </o:SecurityTokenReference>
      </KeyInfo>
      <e:CipherData>
        <e:CipherValue>
   ... ENCRYPTED KEY HERE ...
        </e:CipherValue>
      </e:CipherData>
    </e:EncryptedKey>
  </KeyInfo>
  <enc:CipherData>
    <enc:CipherValue>
    ... ENCRYPTED ASSERTIONS HERE ...
    </enc:CipherValue>
  </enc:CipherData>
</enc:EncryptedData>
</EncryptedAssertion>

I did convert my private key that is in PEM format to pkcs8 format using the following openssl command: 我确实使用以下openssl命令将PEM格式的私钥转换为pkcs8格式:

openssl pkcs8 -topk8 -nocrypt -inform PEM -in rsa_private_key.key -outform DER -out rsa_private_key.pk8

I am then ready to try to decrypt the encrypted assertion. 然后我准备尝试解密加密的断言。 Here is my Java code: 这是我的Java代码:

...
// Load the XML file and parse it.
File xmlFile = new File("data\\token.xml");
InputStream inputStream = new FileInputStream(xmlFile);
Document document = parserPoolManager.parse(inputStream);
Element metadataRoot = document.getDocumentElement();

// Unmarshall
UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
EncryptedAssertion encryptedAssertion = (EncryptedAssertion)unmarshaller.unmarshall(metadataRoot);

// Load the private key file.
File privateKeyFile = new File("data\\rsa_private_key.pk8");
FileInputStream inputStreamPrivateKey = new FileInputStream(privateKeyFile);
byte[] encodedPrivateKey = new byte[(int)privateKeyFile.length()];
inputStreamPrivateKey.read(encodedPrivateKey);
inputStreamPrivateKey.close();

// Create the private key.
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
RSAPrivateKey privateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);

// Create the credentials.
BasicX509Credential decryptionCredential = new BasicX509Credential();
decryptionCredential.setPrivateKey(privateKey);

// Create a decrypter.
Decrypter decrypter = new Decrypter(null, new StaticKeyInfoCredentialResolver(decryptionCredential), new InlineEncryptedKeyResolver());

// Decrypt the assertion.
Assertion decryptedAssertion;

try
{
    decryptedAssertion = decrypter.decrypt(encryptedAssertion);
}
...

Running this code always results as being unable to decrypt the assertion. 运行此代码总是导致无法解密断言。 I do get the following errors: 我确实收到以下错误:

5473 [main] ERROR org.opensaml.xml.encryption.Decrypter - Error decrypting encrypted key
org.apache.xml.security.encryption.XMLEncryptionException: Key is too long for unwrapping
Original Exception was java.security.InvalidKeyException: Key is too long for unwrapping
    at org.apache.xml.security.encryption.XMLCipher.decryptKey(Unknown Source)
    at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:681)
    at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:612)
    at org.opensaml.xml.encryption.Decrypter.decryptUsingResolvedEncryptedKey(Decrypter.java:762)
    at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:513)
    at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:440)
    at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:401)
    at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
    at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)
    at DecrypterTool.main(DecrypterTool.java:121)
java.security.InvalidKeyException: Key is too long for unwrapping
    at com.sun.crypto.provider.RSACipher.engineUnwrap(DashoA13*..)
    at javax.crypto.Cipher.unwrap(DashoA13*..)
    at org.apache.xml.security.encryption.XMLCipher.decryptKey(Unknown Source)
    at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:681)
    at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:612)
    at org.opensaml.xml.encryption.Decrypter.decryptUsingResolvedEncryptedKey(Decrypter.java:762)
    at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:513)
    at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:440)
    at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:401)
    at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
    at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)
    at DecrypterTool.main(DecrypterTool.java:121)
5477 [main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedKey, valid decryption key could not be resolved
5477 [main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedData using either EncryptedData KeyInfoCredentialResolver or EncryptedKeyResolver + EncryptedKey KeyInfoCredentialResolver
5478 [main] ERROR org.opensaml.saml2.encryption.Decrypter - SAML Decrypter encountered an error decrypting element content
org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData
    at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:524)
    at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:440)
    at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:401)
    at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141)
    at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69)
    at DecrypterTool.main(DecrypterTool.java:121)

I really don't know what I'm doing wrong in this case. 在这种情况下,我真的不知道我做错了什么。 I converted my private key to pkcs8, I loaded my SAML XML data and unmarshalled it into the valid type (EncryptedAssertion) and I created a decrypted based on my private key. 我将我的私钥转换为pkcs8,我加载了我的SAML XML数据并将其解组为有效类型(EncryptedAssertion),并根据我的私钥创建了一个解密。

Is it possible that it is related to the oaep format for RSA? 是否可能与RSA的oaep格式有关? I'm using the default java cryptography library. 我正在使用默认的java加密库。

Thanks! 谢谢!

For those of you who will get this problem, it was related to the fact that the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files was not installed and it was not letting me use encryption better than AES-128. 对于那些会遇到这个问题的人来说,这与Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files没有安装这一事实有关,并且它不允许我使用加密比AES-128更好。 Replacing the policy files with the JCE policy files, I was able to successfully decrypt my encrypted assertion. 使用JCE策略文件替换策略文件,我能够成功解密我的加密断言。

Agree with @thwalrusnp. 同意@thwalrusnp。 Just wanted to add the exact location from where you can download the policy jars. 只是想添加下载策略jar的确切位置。

Found it on the answer to Error while decrypting assertion sent from IDP 在解密IDP发送的断言时找到了Error答案

This happens due to limitation of cryptography strength in default distribution of Java Runtime Environment. 这是由于Java Runtime Environment的默认分发中的加密强度限制而发生的。

  1. Download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files ( for Java 7 ) ( for Java 8 ) 下载Java密码术扩展(JCE)无限强度管辖权政策文件( 适用于Java 7 )( 适用于Java 8

  2. Extract zip archive and find there local_policy.jar and US_export_policy.jar . 提取zip存档并找到local_policy.jarUS_export_policy.jar

  3. Replace your JRE version of these files under $JAVA_HOME/jre{version_number}/lib/security/ with downloaded ones. 将$ JAVA_HOME / jre {version_number} / lib / security /下的这些文件的JRE版本替换为已下载的文件。

  4. Restart JRE process, if any running. 重启JRE进程,如果有的话。 Now you can use longer keys. 现在你可以使用更长的键。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM