Decrypting encrypted assertion using SAML 2.0 in java using OpenSAML

23,734

Solution 1

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. Replacing the policy files with the JCE policy files, I was able to successfully decrypt my encrypted assertion.

Solution 2

Agree with @thwalrusnp. Just wanted to add the exact location from where you can download the policy jars.

Found it on the answer to Error while decrypting assertion sent from IDP

This happens due to limitation of cryptography strength in default distribution of Java Runtime Environment.

  1. Download Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files (for Java 7) (for Java 8)

  2. Extract zip archive and find there local_policy.jar and US_export_policy.jar.

  3. Replace your JRE version of these files under $JAVA_HOME/jre{version_number}/lib/security/ with downloaded ones.

  4. Restart JRE process, if any running. Now you can use longer keys.

Share:
23,734
thewalrusnp
Author by

thewalrusnp

Updated on July 05, 2022

Comments

  • thewalrusnp
    thewalrusnp almost 2 years

    I have a problem while trying to decrypt encrypted assertion using SAML 2.0. The library I am using is OpenSAML Java libraries 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 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:

    ...
    // 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.

    Is it possible that it is related to the oaep format for RSA? I'm using the default java cryptography library.

    Thanks!