11package com .cybersource .ws .client ;
22
3-
4-
53import org .apache .ws .security .WSConstants ;
64import org .apache .ws .security .WSEncryptionPart ;
75import org .apache .ws .security .WSSecurityException ;
8- import org .apache .ws .security .conversation .ConversationException ;
9- import org .apache .ws .security .message .WSSecDKEncrypt ;
10- import org .apache .ws .security .message .WSSecEncryptedKey ;
6+ import org .apache .ws .security .message .WSSecEncrypt ;
117import org .apache .ws .security .message .WSSecHeader ;
128import org .apache .ws .security .message .WSSecSignature ;
13- import org .apache .xml .security .signature .XMLSignature ;
149import org .bouncycastle .jce .provider .BouncyCastleProvider ;
1510import org .w3c .dom .Document ;
1611
2722import java .util .Collections ;
2823import java .util .Enumeration ;
2924import java .util .List ;
30- import java . util . Vector ;
25+
3126
3227/**
3328 * Created by jeaton on 3/1/2016.
@@ -42,6 +37,11 @@ public class SignedAndEncryptedMessageHandler extends BaseMessageHandler {
4237
4338 private static final String SERVER_ALIAS = "CyberSource_SJC_US" ;
4439
40+ // By default signature algorithm is set to null and during WSSecSignature build() Signature algorithm will set to "http://www.w3.org/2000/09/xmldsig#rsa-sha1" .
41+ public static final String SIGNATURE_ALGORITHM = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" ;
42+ // By default digest algorithm is set to "http://www.w3.org/2000/09/xmldsig#sha1"
43+ public static final String DIGEST_ALGORITHM = "http://www.w3.org/2001/04/xmlenc#sha256" ;
44+
4545 // This is loaded by WSS4J but since we use it lets make sure its here
4646 static {
4747 Security .addProvider (new BouncyCastleProvider ());
@@ -54,7 +54,6 @@ private SignedAndEncryptedMessageHandler(MerchantConfig merchantConfig, Logger l
5454 for (int pos =0 ;pos <identities .size ();pos ++) {
5555 localKeyStoreHandler .addIdentityToKeyStore (identities .get (pos ));
5656 }
57-
5857 }
5958
6059 static SignedAndEncryptedMessageHandler getInstance (MerchantConfig merchantConfig , Logger logger )
@@ -114,7 +113,6 @@ private static void readAndStoreCertificateAndPrivateKey(
114113
115114 // our p12 files do not contain an alias as a normal name, its the common name and serial number
116115 String merchantKeyAlias = null ;
117- int certIndex = 0 ;
118116 try {
119117 Enumeration enumKeyStore = merchantKeyStore .aliases ();
120118 while (enumKeyStore .hasMoreElements ()) {
@@ -150,73 +148,82 @@ private static void readAndStoreCertificateAndPrivateKey(
150148 throw new SignException (e );
151149 }
152150 }
153-
154- public Document handleMessageCreation (Document workingDocument , String senderAlias ) throws SignException , SignEncryptException {
151+
152+ public Document handleMessageCreation (Document workingDocument , String senderAlias , String password ) throws SignEncryptException , SignException {
155153 if (senderAlias == null )
156154 throw new SignEncryptException ("SignedAndEncryptedMessageHandler - handleMessageCreation," +
157- " specified identity is null" );
158-
159- WSSecHeader secHeader = new WSSecHeader ();
160- secHeader .insertSecurityHeader (workingDocument );
161-
162- //EncryptedKey
163- WSSecEncryptedKey encrKeyBuilder = new WSSecEncryptedKey ();
164- encrKeyBuilder .setUserInfo (SERVER_ALIAS );
165- encrKeyBuilder .setKeyIdentifierType (WSConstants .X509_KEY_IDENTIFIER );
155+ " senderAlias is null" );
156+
157+ WSSecHeader secHeader = new WSSecHeader ();
158+ try {
159+ secHeader .insertSecurityHeader (workingDocument );
160+ } catch (WSSecurityException e ) {
161+ logger .log (Logger .LT_EXCEPTION , "Exception while adding docuemnt in soap securiy header for MLE" );
162+ throw new SignException (e );
163+ }
164+
165+ WSSecEncrypt encrBuilder = new WSSecEncrypt ();
166+ //Set the user name to get the encryption certificate.
167+ //The public key of this certificate is used, thus no password necessary. The user name is a keystore alias usually.
168+ encrBuilder .setUserInfo (SERVER_ALIAS );
166169
167- try {
168- encrKeyBuilder .prepare (workingDocument , localKeyStoreHandler );
169- } catch (WSSecurityException e ) {
170- logger .log (Logger .LT_EXCEPTION , "Key builder failed to create keys for , '" + senderAlias + "'" + " with " + SERVER_ALIAS );
171- throw new SignEncryptException (e .getMessage (), e );
172- }
173-
174- byte [] ek = encrKeyBuilder .getEphemeralKey ();
175- String tokenIdentifier = encrKeyBuilder .getId ();
176-
177- //Create signed document
178- Document signedDoc = createSignedDoc (workingDocument ,senderAlias ,secHeader );
170+ /*This is to reference a public key or certificate when signing or encrypting a SOAP message.
171+ *The following valid values for these configuration items are:
172+ *IssuerSerial (default),DirectReference[BST],X509KeyIdentifier,Thumbprint,SKIKeyIdentifier,KeyValue (signature only),EncryptedKeySHA1 (encryption only)
173+ */
174+ encrBuilder .setKeyIdentifierType (WSConstants .X509_KEY_IDENTIFIER );
179175
180- WSSecDKEncrypt encrBuilder = new WSSecDKEncrypt ();
176+ //This encryption algorithm is used to encrypt the data.
181177 encrBuilder .setSymmetricEncAlgorithm (WSConstants .AES_256 );
182- encrBuilder .setExternalKey (ek , tokenIdentifier );
183- Document signedEncryptedDoc = null ;
178+
179+ //Sets the algorithm to encode the symmetric key. Default is the WSConstants.KEYTRANSPORT_RSAOEP algorithm.
180+ //encrBuilder.setKeyEnc(WSConstants.KEYTRANSPORT_RSAOEP);
184181
185- try {
186- signedEncryptedDoc = encrBuilder .build (signedDoc ,localKeyStoreHandler , secHeader );
187- } catch (WSSecurityException e ) {
188- logger .log (Logger .LT_EXCEPTION , "Failed while encrypting signed requeest for , '" + senderAlias + "'" + " with " + SERVER_ALIAS );
189- throw new SignEncryptException (e .getMessage (), e );
190- }
182+
183+ //Create signed document
184+ Document signedDoc = createSignedDoc (workingDocument ,senderAlias ,password ,secHeader );
191185
192- encrKeyBuilder .prependToHeader (secHeader );
193- encrKeyBuilder .prependBSTElementToHeader (secHeader );
194- return signedEncryptedDoc ;
186+ Document signedEncryptedDoc ;
187+ try {
188+ //Builds the SOAP envelope with encrypted Body and adds encrypted key.
189+ // If no external key (symmetricalKey) was set ,generate an encryption
190+ // key (session key) for this Encrypt element. This key will be
191+ // encrypted using the public key of the receiver
192+ signedEncryptedDoc = encrBuilder .build (signedDoc , localKeyStoreHandler , secHeader );
193+ } catch (WSSecurityException e ) {
194+ logger .log (Logger .LT_EXCEPTION , "Failed while encrypting signed requeest for , '" + senderAlias + "'" + " with " + SERVER_ALIAS );
195+ throw new SignEncryptException (e .getMessage (), e );
196+ }
197+ encrBuilder .prependToHeader (secHeader );
198+ return signedEncryptedDoc ;
195199 }
196-
197- public Document createSignedDoc (Document workingDocument ,String senderAlias , WSSecHeader secHeader ) throws SignException {
200+
201+ public Document createSignedDoc (Document workingDocument ,String senderAlias , String password , WSSecHeader secHeader ) throws SignException {
198202
199203 if (secHeader ==null ){
204+ try {
200205 secHeader = new WSSecHeader ();
201206 secHeader .insertSecurityHeader (workingDocument );
207+ } catch (WSSecurityException e ) {
208+ logger .log (Logger .LT_EXCEPTION , "Exception while signing XML document" );
209+ throw new SignException (e );
210+ }
202211 }
203-
204212 WSSecSignature sign = new WSSecSignature ();
205- sign .setUserInfo (senderAlias , senderAlias );
206- sign .setSignatureAlgorithm (XMLSignature .ALGO_ID_SIGNATURE_RSA_SHA256 );
213+ sign .setUserInfo (senderAlias , password );
214+ sign .setDigestAlgo (DIGEST_ALGORITHM );
215+ sign .setSignatureAlgorithm (SIGNATURE_ALGORITHM );
207216 sign .setKeyIdentifierType (WSConstants .BST_DIRECT_REFERENCE );
208217 sign .setUseSingleCertificate (true );
209218
210219 //Set which parts of the message to encrypt/sign.
211220 WSEncryptionPart msgBodyPart = new WSEncryptionPart (WSConstants .ELEM_BODY , WSConstants .URI_SOAP11_ENV , "" );
212- sign .setParts (new Vector ( Collections .singletonList (msgBodyPart ) ));
221+ sign .setParts (Collections .singletonList (msgBodyPart ));
213222 try {
214223 return sign .build (workingDocument , localKeyStoreHandler , secHeader );
215224 } catch (WSSecurityException e ) {
216225 logger .log (Logger .LT_EXCEPTION , "Failed while signing requeest for , '" + senderAlias + "'" );
217226 throw new SignException (e .getMessage ());
218227 }
219228 }
220-
221-
222229}
0 commit comments