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!
In the service provider configuration for Salesforce, Custom WS-Federation Service Provider or for Custom SAML Service Provider, go to Encryption Certificate. 2. Click the check box for Encrypt SAML assertion. The default encryption certificate is automatically selected.
Encrypting the SAML assertion is optional. In most situations it isn't encrypted and privacy is provided at the transport layer using HTTPS. 2. It's an extra level of security that's enabled if the SAML assertion contains particularly sensitive user information or the environment dictates the need.
In summary, when encrypting SAML v2. 0 messages, the sender uses the receiver's public key (exposed in the receiver's metadata) to encrypt the request. The receiver decrypts it with its private key. As with signing, providers also expose in their metadata the algorithms that they can use to encrypt assertion content.
Azure AD uses AES-256 to encrypt the SAML assertion data.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With