Я пытаюсь выполнить проверку подписи на ответе SAML2, который получен от поставщика удостоверений с использованием OpenSAML. Я пытаюсь прочитать ответ из локальной файловой системы.
Вот мой код:
DefaultBootstrap.bootstrap();
BasicParserPool ppMgr = new BasicParserPool();
ppMgr.setNamespaceAware(true);
//Read file from the filesystem
File file1=new File("F:/Softwares/Assertion.xml");
InputStream inCommonSaml=new FileInputStream(file1);
// Parse file
Document inCommonSamlDoc = ppMgr.parse(inCommonSaml);
Element metadataRoot = inCommonSamlDoc.getDocumentElement();
UnmarshallerFactory unmarshallerFactory=configuration.getUnmarshallerFactory();
Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
Response inCommonSamlRes = (Response) unmarshaller.unmarshall(metadataRoot);
//Get certificate
SignatureValidator signatureValidator = new SignatureValidator(cert);
Signature signature=inCommonSamlRes.getSignature();
signatureValidator.validate(signature);
try {
BasicX509Credential credential = new BasicX509Credential();
File file2=new File("F:/Softwares/publicKey.crt");
InputStream samlCertificate=new FileInputStream(file2);
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//
@SuppressWarnings("deprecation")
java.security.cert.X509Certificate certificate = (java.security.cert.X509Certificate) certificateFactory.generateCertificate(samlCertificate);
//
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec((certificate).getPublicKey().getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(publicKeySpec);
credential.setPublicKey(key);
Object obj = (credential).getPublicKey();
if (obj instanceof RSAPublicKey) {
BigInteger modulus = ((RSAPublicKey) obj).getModulus();
BigInteger exponent = ((RSAPublicKey) obj).getPublicExponent();
System.out.println("modulus");
System.out.println (org.apache.commons.codec.binary.Base64.encodeBase64String(modulus.toByteArray()));
System.out.println("public exponent:");
System.out.println (org.apache.commons.codec.binary.Base64.encodeBase64String(exponent.toByteArray()));
}
// System.out.println ("public key is: //n//r"+ credential.getPublicKey());
return credential;
} catch (Exception e) {
throw e; //Throws a 'Signature did not validate against the credential key' exception
}
Примечание. Я также использую тот же сертификат (publicKey.crt), чтобы подписать это утверждение.
Я получаю следующую ошибку: криптографическая проверка подписи не прошла успешно.
Пожалуйста, дайте мне знать, где я ошибаюсь? Что означает ошибка? Говорит ли он, что общедоступные и закрытые ключи одинаковы?
Спасибо, aswini J
Этот ответ предназначен для входящих пользователей, которые получают эту ошибку и ищут в Google.
В моем случае я столкнулся с такой же ошибкой: " ошибка: криптографическая проверка подписи не увенчалась успехом ", с немного другим случаем. Я проверяю SimpleSamlPHP как SP и CAS как IDP.
Проблема заключалась в том, что мой SP использует один (самоподписанный) сертификат для проверки SP для IDP и другой сертификат для SP в Apache, чтобы разрешить SSL (чтобы я мог иметь https)
Использование двух отдельных сертификатов может работать отлично для большого количества процессов, таких как проверка имени входа и метаданных, но с переходом, таким как выход из системы, эта ошибка будет выполнена.
Решение состоит в том, чтобы использовать только один сертификат для обоих процессов, и моя ошибка исчезла.
Я думаю, вам нужно получить файл.jks с сервера IdP (Identity Provider). Также, когда вы получаете SAMLResponse для вашего POST из IDP, этот SAMLResponse должен содержать подпись (FYI - будет кодированной строкой, вы можете декодировать и читать с использованием библиотеки Open SAML, доступной в центральном репозитории Maven). Как только вы получите подпись, вы можете подтвердить, что с помощью OpenSAML
sigValidator.validate(response.getSignature());
Этот метод даст вам возможность, если все будет в порядке. Сообщение для справки "Подпись, подтвержденная ключом из предоставленных credentia",
Вы можете перейти по этой ссылке: http://sureshatt.blogspot.in/2012/11/how-to-read-saml-20-response-with.html, чтобы получить Подпись и
(IMP): ваш IDP (поставщик удостоверений) должен быть отправлен (может быть через HTTP POST), так что вы можете получить, у которого может быть NameID, то есть ClinetId