작업하고있는 다른 서비스로 SSO 트랜잭션을 수행하기 위해 SAML Payload 준비를위한 OpenSAML 지원을 사용하여 막 다른 골목에 섰습니다. SecurityHelper.prepareSignatureParams() 루틴을 사용하면 throw되는 NullPointerException이 발생합니다. 나는 Stacktrace를 가지고있다. 그러나 추가하기가 꽤 어렵다.java.lang.NullPointerException SecurityHelper.prepareSignatureParams() OpenSAML 호출 중 오류가 발생했습니다.
내가 먼저 내가 할 수 있었던 것을 가정 해 봅시다 ... 기술과 일하는 것이 있는지 확인하는 학습의 목적을 위해
, 나는 성공적하는 SAML 페이로드를 빌드를 사용하여 로그인 할 수 있었다 인증서 및 -genkeypair 옵션과 함께 Keytool 프로그램을 사용하여 워크 스테이션에서 로컬로 생성 한 Java 키 저장소 파일에 저장된 개인 키.
내가 아는 바로, JKS 파일에는 자체 서명 된 인증서와 개인 키가 있습니다. JKS 파일을 열고 인증서와 개인 키를 수집하여 서명 인증서를 만들 수있었습니다. 서명 인증서가 내가 작성한 SAML 페이로드에 서명하는 데 사용되었습니다. 내가 추가 할 코드 샘플을 보면 어떻게되었는지 확인할 수 있습니다. 작동하지 않는 무엇
...
나는 내가 GoDaddy를로부터받은 내 웹 사이트가 신뢰할 수있는 인증서를 사용하여 내 SAML 페이로드에 서명 같은 SAML 지원을 사용하고 싶습니다. 이를 위해 신뢰할 수있는 인증서를 웹 서버의 키 저장소 인 '\ Program Files \ Java \ jre1.8.0_102 \ lib \ security \ cacerts'에 설치했습니다. 저는 cacerts 파일이 웹 서버의 KeyStore라는 것을 알고 있습니다. Keytool -importcert 명령을 사용하여 신뢰할 수있는 인증서를 설치했습니다. 한 가지 큰 차이점은 신뢰할 수있는 인증서에 개인 키가 없다는 점입니다. 따라서 Open SAML 지원을 사용하여 서명 인증서를 준비 할 때 자격 증명 개체에 개인 키를 추가 할 수 없습니다 (권한 키가 없기 때문에).
신뢰할 수있는 인증서를 위와 같이 시도하면 Signature Parms (SecurityHelper.prepareSignatureParams())를 준비하는 부분으로 이동할 수 있습니다. 그것이 Null Pointer를 얻는 곳입니다.
내가 사용중인 코드를 살펴볼 수 있다면. 나는 서버 (두 경우 모두)에서 신뢰할 수있는 인증서를 사용하려고 할 때 로컬 JKS 파일 및 Null 포인터 예외를 가져 오는 코드에서 읽는 코드 (성공적으로 내 페이로드에 서명)를 포함합니다. 두 경우 사이에 큰 차이가 아니다 :
// Signing process using OpenSAML
// Get instance of an OpenSAML 'KeyStore' object...
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
// Read KeyStore as File Input Stream. This is either the local JKS
// file or the server's cacerts file.
File ksFile = new File(keyStoreFileName);
// Open an Input Stream with the Key Store File
FileInputStream ksfInputStream = new FileInputStream(ksFile);
// Load KeyStore. The keyStorePassord is the password assigned to the keystore, Usually 'changeit'
// before being changed.
keyStore.load(ksfInputStream, keyStorePassword);
// Close InputFileStream. No longer needed.
ksfInputStream.close();
// Used to get Entry objects from the Key Store
KeyStore.PrivateKeyEntry pkEntry = null;
KeyStore.TrustedCertificateEntry tcEntry = null;
PrivateKey pk = null;
X509Certificate x509Certificate = null;
BasicX509Credential credential = null;
// The Java Key Store specific code...
// Get Key Entry From the Key Store. CertificateAliasName identifies the
// Entry in the KeyStore. KeyPassword is assigned to the Private Key.
pkEntry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(certificateAliasName, new KeyStore.PasswordProtection(keyPassword));
// Get the Private Key from the Entry
pk = pkEntry.getPrivateKey();
// Get the Certificate from the Entry
x509Certificate = (X509Certificate) pkEntry.getCertificate();
// Create the Credential. Assign the X509Certificate and the Privatekey
credential = new BasicX509Credential();
credential.setEntityCertificate(x509Certificate);
credential.setPrivateKey(pk);
// The Trusted Certificate specific code...
// Accessing a Certificate that was issued from a trusted source - like GoDaddy.com
//
// Get Certificate Entry From the Key Store. CertificateAliasName identifies the Entry in the KeyStore.
// There is NO password as there is no Private Key associate with this Certificate
tcEntry = (TrustedCertificateEntry) keyStore.getEntry(certificateAliasName, null);
// Get the Certificate from the Entry
x509Certificate = (X509Certificate) tcEntry.getTrustedCertificate();
// Create the Credential. There is no Provate Ley to assign into the Credential
credential = new BasicX509Credential();
credential.setEntityCertificate(x509Certificate);
// Back to code that is not specific to either method...
//
// Assign the X509Credential object into a Credential Object. The BasicX509Credential object
// that has a Certificate and a Private Key OR just a Certificate added to it is now saved as a
// Cendential object.
Credential signingCredential = credential;
// Use the OpenSAML builder to create a signature object.
Signature signingSignature = (Signature) Configuration.getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME).build Object(Signature.DEFAULT_ELEMENT_NAME);
// Set the previously created signing credential
signingSignature.setSigningCredential(signingCredential);
// Get a Global Security Configuration object.
SecurityConfiguration secConfig = Configuration.getGlobalSecurityConfiguration();
// KeyInfoGenerator. Not sure what this is, but the example I am working from shows
// this being passed as null.
String keyInfoGeneratorProfile = "XMLSignature";
// Prepare the Signature Parameters.
//
// This works fine for the JKS version of the KeyStore, but gets a Null Pointer exception when I run to the cacerts file.
SecurityHelper.prepareSignatureParams(signingSignature, signingCredential, secConfig, keyInfoGeneratorProfile <or null>);
// I need to set into the SigningSignature object the signing algorithm. This is required when using the TrustedCertificate
signingSignature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
// This is my code that builds a SAML Response. The SAML Payload contains data
// about the SSO session that I will be creating...
Response samlResponse = createSamlResponse.buildSamlResponseMessage();
// Sign the Response using the Certificate that was created earlier
samlResponse.setSignature(signingSignature);
// Get the marshaller factory to marshall the SamlResponse
MarshallerFactory marshallerFactory = Configuration.getMarshallerFactory();
Marshaller responseMarshaller = marshallerFactory.getMarshaller(samlResponse);
// Marshall the Response
Element responseElement = responseElement = responseMarshaller.marshall(samlResponse);
// Sign the Object...
Signer.signObject(signingSignature);
참고 : https://narendrakadali.wordpress.com/2011/06/05/sign-assertion-using-opensaml/
누군가가 나에게의 오류를 보여줄 수 있다는 기대하십시오 SAML 페이로드에 서명 내 시도가 여기 발견되는 OPENSAML 예를 모델로했다 내 길이나 내가 놓친 것.
의견을 보내 주셔서 감사합니다.
EDIT (2016년 1월 26일)
나는 서명에 Params를 준비하는 동안 수신 된 NULL 포인터 과거를 얻을 수 있었다 (SecurityHelper.prepareSignatureParams()). 코드 변경에는 내 xmlsec.jar 파일을 2.0.8 (xmlsec-2.0.8.jar) 버전으로 업데이트하고 GoDaddy의 신뢰할 수있는 인증서를 사용할 때 서명 알고리즘을 SHA256으로 명시 적으로 설정하는 작업이 포함되었습니다. 의 사용에 대한 내 코드의 예를 참조하십시오
signingSignature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
위의 변화는 SAML 페이로드 구축하고 연결 엔드 포인트에 송신 할 수 있습니다.
그러나 아직 내 끝점에 SSO 연결을 설정하지 않았습니다. 처리하는 동안
는 SAML 페이로드가 구축되고 있으며, 구체적으로는 SAML 페이로드의 서명이 서명하는 동안 :
Signer.signObject(signature);
내가 SAML에서 오류 메시지가 여기에
내가 일어나고 참조 내용은 다음과 같습니다
ERROR: org.opensaml.xml.signature.Signer - An error occured computing the digital signature
스택 트레이스 (단지 끝 부분)
org.apache.xml.security.signature.XMLSignatureException: Sorry, you supplied the wrong key type for this operation! You supplied a null but a java.security.PrivateKey is needed.
at org.apache.xml.security.algorithms.implementations.SignatureBaseRSA.engineInitSign(SignatureBaseRSA.java:149)
at org.apache.xml.security.algorithms.implementations.SignatureBaseRSA.engineInitSign(SignatureBaseRSA.java:165)
at org.apache.xml.security.algorithms.SignatureAlgorithm.initSign(SignatureAlgorithm.java:238)
at org.apache.xml.security.signature.XMLSignature.sign(XMLSignature.java:631)
at org.opensaml.xml.signature.Signer.signObject(Signer.java:77)
오류 메시지를 검색했지만 많이 개선하지 않았습니다.
오류 메시지의 루트를 이해하지 못합니다. 잘못된 키 유형 (null)이 제공되었고 OpenSAML이 java.Security.PrivateKey를 기다리고있는 것 같습니다.
신뢰할 수있는 인증서를 사용할 때 개인 키가 없습니까? 맞나요? 개인 키를 어떻게 제공 할 수 있습니까? 신뢰할 수있는 인증서의 경우 KeyStore에서 신뢰할 수있는 인증서 (TrustedCertificateEntry)를 읽었습니다. TrustedCertificateEntry 개체를 사용하면 인증서에 액세스 할 수 있지만 비공개 키를 얻을 수있는 방법은 없습니다.
그러나 자체 서명 된 인증서를 사용하여 서명 작업을 수행 할 때 인증서 (공개 키)와 JKS 파일 (키 저장소)에 포함 된 개인 키가 모두 있다는 것을 알고 있습니다. 그 이유는 JKS 파일에서 읽을 때 공개 키 (인증서)와 개인 키 모두에 액세스하기위한 메서드가있는 개인 키 항목 (KeyStore.PrivateKeyEntry)을 읽을 수 있기 때문입니다.
신뢰할 수있는 인증서의 경우에는 무엇이 누락 되었습니까? OpenSAML 지원은 개인 키가 서명을 계산할 수있을 것으로 기대하는 것 같습니다.
신뢰할 수있는 인증서의 경우 신뢰할 수있는 인증서와 함께 원래의 개인 키를 키 저장소에 패키지하는 방법이 있습니까? 이것이 정상적으로 수행되는지 또는 가능한지 확실하지 않습니다.
내가 여기서 뭘하고 있는지에 대한 약간의 지침을 바랍니다.
EDIT (01/26/2017) - 2 자세한 내용을 제공합니다.
내가 보낸 가져옵니다 SAML 페이로드의 일부를 공유 할 ... 인증서 서명 자체의 경우
, 나는 SignatureValue를 태그와 X509Certificate에 태그를 참조하십시오. 둘 다 이진 데이터를 태그 시작과 끝 부분에 포함합니다.
<ds:SignatureValue/>
인증서 태그가 여전히 존재하고 인증서 바이트를 포함 : 신뢰할 수있는 인증서의 경우
, 나는처럼 보이는 빈 서명 값 태그를 가지고있다.OpenSAML에서 볼 수있는 오류를 보면 신뢰할 수있는 인증서에서 사용할 수있는 데이터를 사용하여 서명을 계산할 수 없다는 것이 더욱 분명합니다.
제 질문은 Null Pointer 예외를 처리하는 것이 아니라 Null Pointer가 나타나는 OpenSAML 패키지에서 무엇을하는지에 대한 질문이었습니다. 아마도이 질문의 제목을 더 정확하게 지정할 수 있습니까? 질문이 길어 졌음을 알고 있지만 OpenSAML 지원을 사용하는 다른 사람들에게 유용 할 수 있습니다. – SBParks