Я пытаюсь написать приложение Java вместе с OpenSAML2 (2.6.6) для расшифровки зашифрованного утверждения, но получаю:
[main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedKey, valid decryption key could not be resolved
[main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedData using either EncryptedData KeyInfoCredentialResolver or EncryptedKeyResolver + EncryptedKey KeyInfoCredentialResolver
[main] ERROR org.opensaml.saml2.encryption.Decrypter - SAML Decrypter encountered an error decrypting element content
Вот мой код Java (извините, он все еще содержит многовыходные данные отладки):
/*
* ****************************************************************************************************
* Original source from: /5056585/rasshifrovka-zashifrovannogo-utverzhdeniya-s-ispolzovaniem-saml-2-0-v-java-s-ispolzovaniem-opensaml
* And hint about needed to add DefaultBootstrap.bootstrap() for OpenSAML 2.x: https://stackoverflow.com/questions/25066183/opensaml-error-receiving-correct-unmarshaller
* And hing about chain resolvers: https://www.programcreek.com/java-api-examples/index.php?api=org.opensaml.saml2.encryption.Decrypter
* ****************************************************************************************************
* ****************************************************************************************************
* ****************************************************************************************************
* ****************************************************************************************************
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.List;
import org.opensaml.DefaultBootstrap;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.EncryptedAssertion;
import org.opensaml.saml2.encryption.Decrypter;
import org.opensaml.saml2.encryption.EncryptedElementTypeEncryptedKeyResolver;
import org.opensaml.xml.Configuration;
import org.opensaml.xml.encryption.ChainingEncryptedKeyResolver;
import org.opensaml.xml.encryption.EncryptedKeyResolver;
import org.opensaml.xml.encryption.InlineEncryptedKeyResolver;
import org.opensaml.xml.encryption.SimpleRetrievalMethodEncryptedKeyResolver;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.parse.BasicParserPool;
import org.opensaml.xml.security.keyinfo.StaticKeyInfoCredentialResolver;
import org.opensaml.xml.security.x509.BasicX509Credential;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class test_opensaml {
public static void main(String[] args) {
String PROGVERSION = "V1.00";
String xmlFileName = "";
String privateKeyFileName = "";
System.out.println("test_opensaml " + PROGVERSION);
if(args.length < 2) {
System.out.println("Command line is: java test_opensaml <signed_samlassertion_xml> <private_key_der>");
System.exit(0);
}
xmlFileName = args[0];
privateKeyFileName = args[1];
Logger logger = LoggerFactory.getLogger(test_opensaml.class);
logger.info("xmlFileName=[" + xmlFileName + "]");
logger.info("privateKeyFileName=[" + privateKeyFileName + "]\n");
try {
// Initialize the library
DefaultBootstrap.bootstrap();
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE Executing DefaultBootstrap.bootstrap() - e=[" + e + "]");
System.exit(-1);
}
InputStream inputStream = null;
// Load the XML file and parse it.
File xmlFile = new File(xmlFileName);
try {
inputStream = new FileInputStream(xmlFile);
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE LOADING ASSERTION XML FILE - e=[" + e + "]");
System.exit(-1);
}
BasicParserPool parserPoolManager = new BasicParserPool();
Document document = null;
Element metadataRoot = null;
try {
document = parserPoolManager.parse(inputStream);
metadataRoot = document.getDocumentElement();
System.out.println("metadataRoot.getNodeName()=[" + metadataRoot.getNodeName() + "]");
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE CREATING DOCUMENT FROM XML FILE - e=[" + e + "]");
System.exit(-1);
}
UnmarshallerFactory unmarshallerFactory = null;
Unmarshaller unmarshaller = null;
EncryptedAssertion encryptedAssertion = null;
try {
// Unmarshall
unmarshallerFactory = Configuration.getUnmarshallerFactory();
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE CREATING UNMARSHALLFACTORY - e=[" + e + "]");
System.exit(-1);
}
if (unmarshallerFactory == null) {
System.out.println("unmarshallerFactory is null");
} else {
System.out.println("unmarshallerFactory is OK/NOT-null");
}
try {
// Unmarshall
unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
if (unmarshaller == null) {
System.out.println("unmarshaller is null");
} else {
System.out.println("unmarshaller is OK/NOT-null");
}
System.out.println("unmarshaller.getClass().getname=[" + unmarshaller.getClass().getName() + "]");
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE CREATING UNMARSHALLER - e=[" + e + "]");
System.exit(-1);
}
try {
// Unmarshall
encryptedAssertion = (EncryptedAssertion)unmarshaller.unmarshall(metadataRoot);
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR CREATING ENCRYPTEDASSERTION BY UNMARSHALLING - e=[" + e + "]");
e.printStackTrace();
System.exit(-1);
}
System.out.println("SUCCESS - CREATED ENCRYPTEDASSERTION BY UNMARSHALLING!!");
System.out.println("Will now try to load the PRIVATE KEY FILE...");
// Load the private key file.
File privateKeyFile = new File(privateKeyFileName);
FileInputStream inputStreamPrivateKey = null;
byte[] encodedPrivateKey = null;
try {
inputStreamPrivateKey = new FileInputStream(privateKeyFile);
encodedPrivateKey = new byte[(int)privateKeyFile.length()];
inputStreamPrivateKey.read(encodedPrivateKey);
inputStreamPrivateKey.close();
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE READING PRIVATE KEY FROM FILE - e=[" + e + "]");
System.exit(-1);
}
System.out.println("SUCCESS - READ/INPUT THE PRIVATE KEY FILE!!");
PKCS8EncodedKeySpec privateKeySpec = null;
RSAPrivateKey privateKey = null;
try {
// Create the private key.
privateKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
privateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE CREATING PRIVATE KEY - e=[" + e + "]");
System.exit(-1);
}
System.out.println("SUCCESS - CREATING THE PRIVATE KEY INSTANCE!!");
ChainingEncryptedKeyResolver keyResolver = new ChainingEncryptedKeyResolver();
keyResolver.getResolverChain().add(new InlineEncryptedKeyResolver());
keyResolver.getResolverChain().add(new EncryptedElementTypeEncryptedKeyResolver());
keyResolver.getResolverChain().add(new SimpleRetrievalMethodEncryptedKeyResolver());
System.out.println("Built a list of encrypted key resolvers...");
boolean successfulDecryption = false;
// Create the credentials.
BasicX509Credential decryptionCredential = new BasicX509Credential();
decryptionCredential.setPrivateKey(privateKey);
StaticKeyInfoCredentialResolver resolver = new StaticKeyInfoCredentialResolver(decryptionCredential);
// Create a decrypter.
Decrypter decrypter = new Decrypter(null, resolver, keyResolver);
decrypter.setRootInNewDocument(true);
// Decrypt the assertion.
Assertion decryptedAssertion = null;
System.out.println("WILL NOW TRY TO DECRYPT THE ENCRYPTED ASSERTION...");
try
{
decryptedAssertion = decrypter.decrypt(encryptedAssertion);
} catch (Exception e) {
System.out.println("** ERROR ** - ERROR WHILE DECRYPTING THE ASSERTION - e=[" + e + "]");
System.exit(-1);
}
System.out.println("SUCCESS - DECRYPTED THE ENCRYPTED ASSERTION - will now dump out the decrypted assertion...!!");
System.out.println("decryptedAssertion.toString=[" + decryptedAssertion.toString() + "]");
System.out.println("Finished...");
System.exit(0);
} // end main()
}
Когда я запускаю это с проверенным подписанным утверждением (XML) и закрытым ключом, я получаю следующий вывод.Он запускается в Eclipse и использует Java 1.8 build 201:
test_opensaml V1.00
[main] INFO test_opensaml - xmlFileName=[E:\ECLIPSE-WORKSPACES\opensaml\opensaml\data\encrypted_assertion.xml]
[main] INFO test_opensaml - privateKeyFileName=[E:\ECLIPSE-WORKSPACES\opensaml\opensaml\data\geoaxis-gxaccess.com.private-key.der]
metadataRoot.getNodeName()=[saml:EncryptedAssertion]
unmarshallerFactory is OK/NOT-null
unmarshaller is OK/NOT-null
unmarshaller.getClass().getname=[org.opensaml.saml2.core.impl.EncryptedAssertionUnmarshaller]
SUCCESS - CREATED ENCRYPTEDASSERTION BY UNMARSHALLING!!
Will now try to load the PRIVATE KEY FILE...
SUCCESS - READ/INPUT THE PRIVATE KEY FILE!!
SUCCESS - CREATING THE PRIVATE KEY INSTANCE!!
Built a list of encrypted key resolvers...
WILL NOW TRY TO DECRYPT THE ENCRYPTED ASSERTION...
[main] ERROR org.opensaml.xml.encryption.Decrypter - Error decrypting encrypted key
org.apache.xml.security.encryption.XMLEncryptionException: Unwrapping failed
Original Exception was java.security.InvalidKeyException: Unwrapping failed
at org.apache.xml.security.encryption.XMLCipher.decryptKey(XMLCipher.java:1539)
at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:708)
at org.opensaml.xml.encryption.Decrypter.decryptKey(Decrypter.java:639)
at org.opensaml.xml.encryption.Decrypter.decryptUsingResolvedEncryptedKey(Decrypter.java:794)
at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:535)
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)
at test_opensaml.main(test_opensaml.java:193)
Caused by: java.security.InvalidKeyException: Unwrapping failed
at com.sun.crypto.provider.RSACipher.engineUnwrap(RSACipher.java:445)
at javax.crypto.Cipher.unwrap(Cipher.java:2549)
at org.apache.xml.security.encryption.XMLCipher.decryptKey(XMLCipher.java:1537)
... 9 more
Caused by: javax.crypto.BadPaddingException: Decryption error
at sun.security.rsa.RSAPadding.unpadOAEP(Unknown Source)
at sun.security.rsa.RSAPadding.unpad(Unknown Source)
at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
at com.sun.crypto.provider.RSACipher.engineUnwrap(RSACipher.java:440)
... 11 more
[main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedKey, valid decryption key could not be resolved
[main] ERROR org.opensaml.xml.encryption.Decrypter - Failed to decrypt EncryptedData using either EncryptedData KeyInfoCredentialResolver or EncryptedKeyResolver + EncryptedKey KeyInfoCredentialResolver
[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: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)
at test_opensaml.main(test_opensaml.java:193)
** ERROR ** - ERROR WHILE DECRYPTING THE ASSERTION - e=[org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData]
Поскольку это (по крайней мере, для меня) новый и непроверенный код, мне было интересно, как я могу диагностировать эту проблему дальше?
Существуют ли какие-либо дополнительные записи в журнале или что-то, что может помочь выяснить, что не так или определить проблему?
Я знаю, что это будет звучать немного необычно, но, к вашему сведению,Мне дали подписанное утверждение и закрытый ключ, который я использую для тестирования прямо сейчас, третьей стороной, так что я на самом деле не на 100% уверен, что они хороши, поэтому мне было интересно, может быть, где-нибудь я мог бы получить / скачатьПример зашифрованного подтверждения с заведомо достоверным подтверждением и соответствующим закрытым ключом, чтобы я мог попытаться проверить приведенный выше код с заведомо достоверными данными?
Спасибо, Джим
РЕДАКТИРОВАТЬ: Извините, я забылвключить фрагмент зашифрованного утверждения, которое я использовал для проверки:
<?xml version="1.0"?>
<saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">
<xenc:EncryptedData Type="http://www.w3.org/2001/04/xmlenc#Element" Id="_332ec9de74ee4a8b97b84694edb58ba9" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<xenc:EncryptedKey Type="http://www.w3.org/2001/04/xmlenc#Element" Id="_d32f036453ed438b84783a21a2e2cca7">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
<xenc:CipherData>
<xenc:CipherValue>Rfn5PDApVSF3wTBgsiQsFn5rybj...EZoHpGvxDPv5kAhVw==</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedKey>
</ds:KeyInfo>
<xenc:CipherData>
<xenc:CipherValue>FTk8D8nGOTuZsunGifMEHtj...xiAvwSQ=</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</saml:EncryptedAssertion>
РЕДАКТИРОВАТЬ 2: Для кого-то, кто знаком с OpenSAML и SAML: Есть ли что-то не так с подписанным утверждением выше?Я провел дополнительное тестирование, и похоже, что ни один из распознавателей не может найти ключ шифрования, и я заметил, что ds: Keyinfo встроена в xenc: EncryptedData, на том же уровне, что и xenc: CipherData.Это нормальная структура, и какой из цепочек определителей должен найти ds: Keyinfo?