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

时间:2012-02-23 22:39:15

标签: java cryptography rsa saml-2.0 opensaml

尝试使用SAML 2.0解密加密断言时遇到问题。我使用的库是OpenSAML Java库2.5.2。

加密断言如下所示:

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

我确实使用以下openssl命令将PEM格式的私钥转换为pkcs8格式:

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

然后我准备尝试解密加密的断言。这是我的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);
}
...

运行此代码总是导致无法解密断言。我确实收到以下错误:

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)

在这种情况下,我真的不知道我做错了什么。我将私钥转换为pkcs8,我加载了我的SAML XML数据并将其解组为有效类型(EncryptedAssertion),并根据我的私钥创建了解密。

它是否可能与RSA的oaep格式有关?我正在使用默认的java加密库。

谢谢!

2 个答案:

答案 0 :(得分:19)

对于那些会遇到此问题的人来说,这与Java Cryptography Extension(JCE)Unlimited Strength Jurisdiction Policy Files没有安装这一事实有关,并且它不允许我使用加密比AES-128更好。使用JCE策略文件替换策略文件,我能够成功解密加密的断言。

答案 1 :(得分:2)

同意@thwalrusnp。只是想添加下载政策罐的确切位置。

answerError while decrypting assertion sent from IDP

上找到它
  

这是由于默认情况下加密强度的限制而发生的   Java Runtime Environment的分发。

     
      
  1. 下载Java密码术扩展(JCE)无限强度管辖权政策文件(for Java 7)(for Java 8

  2.   
  3. 解压zip档案并找到local_policy.jarUS_export_policy.jar

  4.   
  5. 将$ JAVA_HOME / jre {version_number} / lib / security /下的这些文件的JRE版本替换为已下载的文件。

  6.   
  7. 重新启动JRE进程(如果有)。现在你可以使用更长的键。

  8.