org.apache.ws.security.message.WSSecEncrypt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of wss4j Show documentation
Show all versions of wss4j Show documentation
The Apache WSS4J project provides a Java implementation of the primary security standards
for Web Services, namely the OASIS Web Services Security (WS-Security) specifications
from the OASIS Web Services Security TC.
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ws.security.message;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.util.Base64;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.algorithms.JCEMapper;
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.xml.security.encryption.XMLEncryptionException;
import org.apache.xml.security.keys.KeyInfo;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.Vector;
/**
* Encrypts a parts of a message according to WS Specification, X509 profile,
* and adds the encryption data.
*
* @author Davanum Srinivas ([email protected]).
* @author Werner Dittmann ([email protected]).
*/
public class WSSecEncrypt extends WSSecEncryptedKey {
private static Log log = LogFactory.getLog(WSSecEncrypt.class.getName());
protected String symEncAlgo = WSConstants.AES_128;
protected String encCanonAlgo = null;
protected byte[] embeddedKey = null;
protected String embeddedKeyName = null;
protected boolean useKeyIdentifier;
/**
* Symmetric key used in the EncrytpedKey.
*/
protected SecretKey symmetricKey = null;
/**
* SecurityTokenReference to be inserted into EncryptedData/keyInfo element.
*/
protected SecurityTokenReference securityTokenReference = null;
/**
* Indicates whether to encrypt the symmetric key into an EncryptedKey
* or not.
*/
private boolean encryptSymmKey = true;
/**
* Custom reference value
*/
private String customReferenceValue;
/**
* ValueType for the encrypted key reference
*/
private String encKeyValueType;
/**
* True if the encKeyId is a direct reference to a key identifier instead of a URI to a key
*/
private boolean encKeyIdDirectId;
/**
* Constructor.
*/
public WSSecEncrypt() {
}
/**
* Sets the key to use during embedded encryption.
*
* @param key to use during encryption. The key must fit the selected
* symmetrical encryption algorithm
*/
public void setKey(byte[] key) {
this.embeddedKey = key;
}
/**
* Sets the algorithm to encode the symmetric key.
*
* Default is the WSConstants.KEYTRANSPORT_RSA15
algorithm.
*
* @param keyEnc specifies the key encoding algorithm.
* @see WSConstants#KEYTRANSPORT_RSA15
* @see WSConstants#KEYTRANSPORT_RSAOEP
*/
public void setKeyEnc(String keyEnc) {
keyEncAlgo = keyEnc;
}
/**
* Set the key name for EMBEDDED_KEYNAME
*
* @param embeddedKeyName
*/
public void setEmbeddedKeyName(String embeddedKeyName) {
this.embeddedKeyName = embeddedKeyName;
}
/**
* Set this true if a key identifier must be used in the KeyInfo
*
* @param useKeyIdentifier
*/
public void setUseKeyIdentifier(boolean useKeyIdentifier) {
this.useKeyIdentifier = useKeyIdentifier;
}
/**
* Set the name of the symmetric encryption algorithm to use.
*
* This encryption algorithm is used to encrypt the data. If the algorithm
* is not set then AES128 is used. Refer to WSConstants which algorithms are
* supported.
*
* @param algo Is the name of the encryption algorithm
* @see WSConstants#TRIPLE_DES
* @see WSConstants#AES_128
* @see WSConstants#AES_192
* @see WSConstants#AES_256
*/
public void setSymmetricEncAlgorithm(String algo) {
symEncAlgo = algo;
}
/**
* Set the name of an optional canonicalization algorithm to use before
* encryption.
*
* This c14n algorithm is used to serialize the data before encryption. If
* the algorithm is not set then a standard serialization is used (provided
* by XMLCipher, usually a XMLSerializer according to DOM 3 specification).
*
* @param algo Is the name of the canonicalization algorithm
*/
public void setEncCanonicalization(String algo) {
encCanonAlgo = algo;
}
/**
* Get the name of symmetric encryption algorithm to use.
*
* The name of the encryption algorithm to encrypt the data, i.e. the SOAP
* Body. Refer to WSConstants which algorithms are supported.
*
* @return the name of the currently selected symmetric encryption algorithm
* @see WSConstants#TRIPLE_DES
* @see WSConstants#AES_128
* @see WSConstants#AES_192
* @see WSConstants#AES_256
*/
public String getSymmetricEncAlgorithm() {
return symEncAlgo;
}
/**
* Returns if Key Identifiers should be used in KeyInfo
* @return if Key Identifiers should be used in KeyInfo
*/
public boolean getUseKeyIdentifier() {
return useKeyIdentifier;
}
/**
* Initialize a WSSec Encrypt.
*
* The method prepares and initializes a WSSec Encrypt structure after the
* relevant information was set. After preparation of the token references
* can be added and encrypted.
*
* This method does not add any element to the security header. This must be
* done explicitly.
*
* @param doc The SOAP envelope as Document
* @param crypto An instance of the Crypto API to handle keystore and certificates
* @throws WSSecurityException
*/
public void prepare(Document doc, Crypto crypto) throws WSSecurityException {
document = doc;
//
// If no external key (symmetricalKey) was set generate an encryption
// key (session key) for this Encrypt element. This key will be
// encrypted using the public key of the receiver
//
if (this.ephemeralKey == null) {
if (symmetricKey == null) {
KeyGenerator keyGen = getKeyGenerator();
this.symmetricKey = keyGen.generateKey();
}
this.ephemeralKey = this.symmetricKey.getEncoded();
}
if (this.symmetricKey == null) {
this.symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, this.ephemeralKey);
}
//
// Get the certificate that contains the public key for the public key
// algorithm that will encrypt the generated symmetric (session) key.
//
if (this.encryptSymmKey) {
X509Certificate remoteCert = null;
if (useThisCert != null) {
remoteCert = useThisCert;
} else {
X509Certificate[] certs = crypto.getCertificates(user);
if (certs == null || certs.length <= 0) {
throw new WSSecurityException(
WSSecurityException.FAILURE,
"noUserCertsFound",
new Object[] { user, "encryption" }
);
}
remoteCert = certs[0];
}
prepareInternal(this.ephemeralKey, remoteCert, crypto);
} else {
encryptedEphemeralKey = ephemeralKey;
}
}
/**
* Builds the SOAP envelope with encrypted Body and adds encrypted key.
*
* This is a convenience method and for backward compatibility. The method
* calls the single function methods in order to perform a one shot
* encryption. This method is compatible with the build method of the
* previous version with the exception of the additional WSSecHeader
* parameter.
*
* @param doc the SOAP envelope as Document
with plain text Body
* @param crypto an instance of the Crypto API to handle keystore and Certificates
* @param secHeader the security header element to hold the encrypted key element.
* @return the SOAP envelope with encrypted Body as Document
* @throws WSSecurityException
*/
public Document build(Document doc, Crypto crypto, WSSecHeader secHeader)
throws WSSecurityException {
doDebug = log.isDebugEnabled();
if (keyIdentifierType == WSConstants.EMBEDDED_KEYNAME
|| keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) {
return buildEmbedded(doc, secHeader);
}
if (doDebug) {
log.debug("Beginning Encryption...");
}
prepare(doc, crypto);
if (envelope == null) {
envelope = document.getDocumentElement();
}
if (parts == null) {
parts = new Vector();
SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
WSEncryptionPart encP =
new WSEncryptionPart(
soapConstants.getBodyQName().getLocalPart(),
soapConstants.getEnvelopeURI(),
"Content"
);
parts.add(encP);
}
Element refs = encryptForInternalRef(null, parts);
if (encryptedKeyElement != null) {
addInternalRefElement(refs);
prependToHeader(secHeader);
} else {
WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(), refs);
}
if (bstToken != null) {
prependBSTElementToHeader(secHeader);
}
log.debug("Encryption complete.");
return doc;
}
/**
* Encrypt one or more parts or elements of the message (internal).
*
* This method takes a vector of WSEncryptionPart
object that
* contain information about the elements to encrypt. The method call the
* encryption method, takes the reference information generated during
* encryption and add this to the xenc:Reference
element.
* This method can be called after prepare()
and can be
* called multiple times to encrypt a number of parts or elements.
*
* The method generates a xenc:Reference
element that must
* be added to this token. See addInternalRefElement()
.
*
* If the dataRef
parameter is null
the method
* creates and initializes a new Reference element.
*
* @param dataRef A xenc:Reference
element or null
* @param references A vector containing WSEncryptionPart objects
* @return Returns the updated xenc:Reference
element
* @throws WSSecurityException
*/
public Element encryptForInternalRef(Element dataRef, Vector references)
throws WSSecurityException {
Vector encDataRefs =
doEncryption(document, this.symmetricKey, references);
Element referenceList = dataRef;
if (referenceList == null) {
referenceList =
document.createElementNS(
WSConstants.ENC_NS,
WSConstants.ENC_PREFIX + ":ReferenceList"
);
}
createDataRefList(document, referenceList, encDataRefs);
return referenceList;
}
/**
* Encrypt one or more parts or elements of the message (external).
*
* This method takes a vector of WSEncryptionPart
object that
* contain information about the elements to encrypt. The method call the
* encryption method, takes the reference information generated during
* encryption and add this to the xenc:Reference
element.
* This method can be called after prepare()
and can be
* called multiple times to encrypt a number of parts or elements.
*
* The method generates a xenc:Reference
element that must
* be added to the SecurityHeader. See addExternalRefElement()
.
*
* If the dataRef
parameter is null
the method
* creates and initializes a new Reference element.
*
* @param dataRef A xenc:Reference
element or null
* @param references A vector containing WSEncryptionPart objects
* @return Returns the updated xenc:Reference
element
* @throws WSSecurityException
*/
public Element encryptForExternalRef(Element dataRef, Vector references)
throws WSSecurityException {
Vector encDataRefs =
doEncryption(document, this.symmetricKey, references);
Element referenceList = dataRef;
if (referenceList == null) {
referenceList =
document.createElementNS(
WSConstants.ENC_NS,
WSConstants.ENC_PREFIX + ":ReferenceList"
);
//
// If we're not placing the ReferenceList in an EncryptedKey structure,
// then add the ENC namespace
//
if (!encryptSymmKey) {
WSSecurityUtil.setNamespace(
referenceList, WSConstants.ENC_NS, WSConstants.ENC_PREFIX
);
}
}
createDataRefList(document, referenceList, encDataRefs);
return referenceList;
}
/**
* Adds the internal Reference element to this Encrypt data.
*
* The reference element must be created by the
* encryptForInternalRef()
method. The reference element is
* added to the EncryptedKey
element of this encrypt block.
*
* @param dataRef The internal enc:Reference
element
*/
public void addInternalRefElement(Element dataRef) {
encryptedKeyElement.appendChild(dataRef);
}
/**
* Adds (prepends) the external Reference element to the Security header.
*
* The reference element must be created by the
* encryptForExternalRef()
method. The method prepends the
* reference element in the SecurityHeader.
*
* @param dataRef The external enc:Reference
element
* @param secHeader The security header.
*/
public void addExternalRefElement(Element dataRef, WSSecHeader secHeader) {
WSSecurityUtil.prependChildElement(secHeader.getSecurityHeader(), dataRef);
}
private Vector doEncryption(Document doc, SecretKey secretKey, Vector references)
throws WSSecurityException {
KeyInfo keyInfo = null;
// Prepare KeyInfo if useKeyIdentifier is set
if (useKeyIdentifier &&
keyIdentifierType == WSConstants.ENCRYPTED_KEY_SHA1_IDENTIFIER) {
keyInfo = new KeyInfo(document);
SecurityTokenReference secToken = new SecurityTokenReference(document);
if (this.customReferenceValue != null) {
secToken.setKeyIdentifierEncKeySHA1(this.customReferenceValue);
} else {
secToken.setKeyIdentifierEncKeySHA1(getSHA1(encryptedEphemeralKey));
}
keyInfo.addUnknownElement(secToken.getElement());
Element keyInfoElement = keyInfo.getElement();
keyInfoElement.setAttributeNS(
WSConstants.XMLNS_NS, "xmlns:"+ WSConstants.SIG_PREFIX, WSConstants.SIG_NS
);
}
return doEncryption(doc, secretKey, keyInfo, references);
}
private Vector doEncryption(
Document doc,
SecretKey secretKey,
KeyInfo keyInfo,
Vector references
) throws WSSecurityException {
XMLCipher xmlCipher = null;
try {
xmlCipher = XMLCipher.getInstance(symEncAlgo);
} catch (XMLEncryptionException e3) {
throw new WSSecurityException(
WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e3
);
}
Vector encDataRef = new Vector();
boolean cloneKeyInfo = false;
for (int part = 0; part < references.size(); part++) {
WSEncryptionPart encPart = (WSEncryptionPart) references.get(part);
String idToEnc = encPart.getId();
String elemName = encPart.getName();
String nmSpace = encPart.getNamespace();
String modifier = encPart.getEncModifier();
//
// Third step: get the data to encrypt.
//
Element body = null;
if (idToEnc != null) {
body =
WSSecurityUtil.findElementById(
document.getDocumentElement(), idToEnc, WSConstants.WSU_NS
);
if (body == null) {
body =
WSSecurityUtil.findElementById(document.getDocumentElement(), idToEnc, null);
}
} else {
body = (Element) WSSecurityUtil.findElement(document, elemName, nmSpace);
}
if (body == null) {
throw new WSSecurityException(
WSSecurityException.FAILURE,
"noEncElement",
new Object[] {"{" + nmSpace + "}" + elemName}
);
}
boolean content = modifier.equals("Content") ? true : false;
String xencEncryptedDataId = wssConfig.getIdAllocator().createId("EncDataId-", body);
encPart.setEncId(xencEncryptedDataId);
cloneKeyInfo = true;
if (keyInfo == null) {
keyInfo = new KeyInfo(document);
SecurityTokenReference secToken = new SecurityTokenReference(document);
Reference ref = new Reference(document);
if (encKeyIdDirectId) {
ref.setURI(encKeyId);
} else {
ref.setURI("#" + encKeyId);
}
if (encKeyValueType != null) {
ref.setValueType(encKeyValueType);
}
secToken.setReference(ref);
keyInfo.addUnknownElement(secToken.getElement());
Element keyInfoElement = keyInfo.getElement();
keyInfoElement.setAttributeNS(
WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
);
}
//
// Fourth step: encrypt data, and set necessary attributes in
// xenc:EncryptedData
//
try {
if (modifier.equals("Header")) {
Element elem =
doc.createElementNS(
WSConstants.WSSE11_NS, "wsse11:" + WSConstants.ENCRYPTED_HEADER
);
WSSecurityUtil.setNamespace(elem, WSConstants.WSSE11_NS, WSConstants.WSSE11_PREFIX);
String wsuPrefix =
WSSecurityUtil.setNamespace(elem, WSConstants.WSU_NS, WSConstants.WSU_PREFIX);
elem.setAttributeNS(
WSConstants.WSU_NS, wsuPrefix + ":Id",
wssConfig.getIdAllocator().createId("EncHeader-", body)
);
NamedNodeMap map = body.getAttributes();
for (int i = 0 ; i < map.getLength() ; i++) {
Attr attr = (Attr)map.item(i);
if (attr.getNamespaceURI().equals(WSConstants.URI_SOAP11_ENV)
|| attr.getNamespaceURI().equals(WSConstants.URI_SOAP12_ENV)) {
String soapEnvPrefix =
WSSecurityUtil.setNamespace(
elem, attr.getNamespaceURI(), WSConstants.DEFAULT_SOAP_PREFIX
);
elem.setAttributeNS(
attr.getNamespaceURI(),
soapEnvPrefix + ":" + attr.getLocalName(),
attr.getValue()
);
}
}
xmlCipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
EncryptedData encData = xmlCipher.getEncryptedData();
encData.setId(xencEncryptedDataId);
encData.setKeyInfo(keyInfo);
xmlCipher.doFinal(doc, body, content);
Element encDataElem =
WSSecurityUtil.findElementById(
document.getDocumentElement(), xencEncryptedDataId, null
);
Node clone = encDataElem.cloneNode(true);
elem.appendChild(clone);
encDataElem.getParentNode().appendChild(elem);
encDataElem.getParentNode().removeChild(encDataElem);
} else {
xmlCipher.init(XMLCipher.ENCRYPT_MODE, secretKey);
EncryptedData encData = xmlCipher.getEncryptedData();
encData.setId(xencEncryptedDataId);
encData.setKeyInfo(keyInfo);
xmlCipher.doFinal(doc, body, content);
}
if (cloneKeyInfo) {
keyInfo = new KeyInfo((Element) keyInfo.getElement().cloneNode(true), null);
}
} catch (Exception e2) {
throw new WSSecurityException(
WSSecurityException.FAILED_ENCRYPTION, null, null, e2
);
}
encDataRef.add("#" + xencEncryptedDataId);
}
return encDataRef;
}
private Document buildEmbedded(Document doc, WSSecHeader secHeader)
throws WSSecurityException {
doDebug = log.isDebugEnabled();
if (doDebug) {
log.debug("Beginning Encryption embedded...");
}
envelope = doc.getDocumentElement();
envelope.setAttributeNS(
WSConstants.XMLNS_NS, "xmlns:" + WSConstants.ENC_PREFIX, WSConstants.ENC_NS
);
//
// Second step: generate a symmetric key from the specified key
// (password) for this algorithm, and set the cipher into encryption
// mode.
//
if (this.symmetricKey == null) {
if (embeddedKey == null) {
throw new WSSecurityException(WSSecurityException.FAILURE, "noKeySupplied");
}
this.symmetricKey = WSSecurityUtil.prepareSecretKey(symEncAlgo, embeddedKey);
}
KeyInfo keyInfo = null;
if (this.keyIdentifierType == WSConstants.EMBEDDED_KEYNAME) {
keyInfo = new KeyInfo(doc);
keyInfo.addKeyName(embeddedKeyName == null ? user : embeddedKeyName);
} else if (this.keyIdentifierType == WSConstants.EMBED_SECURITY_TOKEN_REF) {
//
// This means that we want to embed a
// into keyInfo element. If we need this functionality, this.secRef
// MUST be set before calling the build(doc, crypto) method. So if
// secRef is null then throw an exception.
//
if (this.securityTokenReference == null) {
throw new WSSecurityException(
WSSecurityException.SECURITY_TOKEN_UNAVAILABLE,
"You must set keyInfo element, if the keyIdentifier == EMBED_SECURITY_TOKEN_REF"
);
} else {
keyInfo = new KeyInfo(doc);
Element tmpE = securityTokenReference.getElement();
tmpE.setAttributeNS(
WSConstants.XMLNS_NS, "xmlns:" + tmpE.getPrefix(), tmpE.getNamespaceURI()
);
keyInfo.addUnknownElement(securityTokenReference.getElement());
}
}
Element keyInfoElement = keyInfo.getElement();
keyInfoElement.setAttributeNS(
WSConstants.XMLNS_NS, "xmlns:" + WSConstants.SIG_PREFIX, WSConstants.SIG_NS
);
SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(envelope);
if (parts == null) {
parts = new Vector();
WSEncryptionPart encP =
new WSEncryptionPart(
soapConstants.getBodyQName().getLocalPart(),
soapConstants.getEnvelopeURI(),
"Content"
);
parts.add(encP);
}
Vector encDataRefs = doEncryption(doc, this.symmetricKey, keyInfo, parts);
//
// At this point data is encrypted with the symmetric key and can be
// referenced via the above Id
//
//
// Now we need to setup the wsse:Security header block 1) get (or
// create) the wsse:Security header block 2) The last step sets up the
// reference list that pints to the encrypted data
//
Element wsseSecurity = secHeader.getSecurityHeader();
Element referenceList =
doc.createElementNS(WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":ReferenceList");
referenceList = createDataRefList(doc, referenceList, encDataRefs);
WSSecurityUtil.prependChildElement(wsseSecurity, referenceList);
return doc;
}
private KeyGenerator getKeyGenerator() throws WSSecurityException {
try {
//
// Assume AES as default, so initialize it
//
String keyAlgorithm = JCEMapper.getJCEKeyAlgorithmFromURI(symEncAlgo);
KeyGenerator keyGen = KeyGenerator.getInstance(keyAlgorithm);
if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_128)) {
keyGen.init(128);
} else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_192)) {
keyGen.init(192);
} else if (symEncAlgo.equalsIgnoreCase(WSConstants.AES_256)) {
keyGen.init(256);
}
return keyGen;
} catch (NoSuchAlgorithmException e) {
throw new WSSecurityException(
WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e
);
}
}
/**
* Create DOM subtree for xenc:EncryptedKey
*
* @param doc the SOAP envelope parent document
* @param referenceList
* @param encDataRefs
* @return an xenc:EncryptedKey
element
*/
public static Element createDataRefList(
Document doc,
Element referenceList,
Vector encDataRefs
) {
for (int i = 0; i < encDataRefs.size(); i++) {
String dataReferenceUri = (String) encDataRefs.get(i);
Element dataReference =
doc.createElementNS(
WSConstants.ENC_NS, WSConstants.ENC_PREFIX + ":DataReference"
);
dataReference.setAttributeNS(null, "URI", dataReferenceUri);
referenceList.appendChild(dataReference);
}
return referenceList;
}
/**
* @return The symmetric key
*/
public SecretKey getSymmetricKey() {
return symmetricKey;
}
/**
* Set the symmetric key to be used for encryption
*
* @param key
*/
public void setSymmetricKey(SecretKey key) {
this.symmetricKey = key;
}
/**
* @return Return the SecurityTokenRefernce
*/
public SecurityTokenReference getSecurityTokenReference() {
return securityTokenReference;
}
/**
* @param reference
*/
public void setSecurityTokenReference(SecurityTokenReference reference) {
securityTokenReference = reference;
}
public boolean isEncryptSymmKey() {
return encryptSymmKey;
}
public void setEncryptSymmKey(boolean encryptSymmKey) {
this.encryptSymmKey = encryptSymmKey;
}
private String getSHA1(byte[] input) throws WSSecurityException {
try {
MessageDigest sha = null;
sha = MessageDigest.getInstance("SHA-1");
sha.reset();
sha.update(input);
byte[] data = sha.digest();
return Base64.encode(data);
} catch (NoSuchAlgorithmException e) {
throw new WSSecurityException(
WSSecurityException.UNSUPPORTED_ALGORITHM, null, null, e
);
}
}
public void setCustomReferenceValue(String customReferenceValue) {
this.customReferenceValue = customReferenceValue;
}
public void setEncKeyValueType(String e) {
encKeyValueType = e;
}
public void setEncKeyIdDirectId(boolean b) {
encKeyIdDirectId = b;
}
}