Community articlevalidateHMACWithHashedSecret method
Added by IBM contributorIBM on May 2, 2012
Rate this article 1 starsRate this article 2 starsRate this article 3 starsRate this article 4 starsRate this article 5 stars

No abstract provided.


This method determines whether an HMAC signature is valid. HMAC signatures include both Authenticated Clickwrap and Signature Pad signatures.
For Authenticated Clickwrap signatures, you must know the hash of the signer's shared secret to use this method. For Signature Pad signatures, you may use this method without the shared secret if the signature was created without one. In any case, the shared secret should be available from a corporate database or other system.
This method will also notarize (that is, digitally sign) a valid HMAC signature if you provide a digital certificate. However, notarization will not occur if the signature does not include a shared secret. Once notarized, you must use the verifySignature method to validate the signature.


   public short validateHMACWithHashedSecret(
      byte  [] hashedSecret,
      Certificate theServerCert,
      IntHolder theStatus,
      ) throws UWIException;


Table 1. Method parameters
hashedSecretbyte[]The hash of the shared secret that identifies the user. This should be available from a corporate database or other system.
If there is more than one shared secret, you must concatenate the strings with no separating characters and then hash the combined secret. For example, if the secrets were "blue" and "red", you would pass the hash of "bluered" to the method.
If there is no shared secret, pass an empty string.
You must encode the byte array as follows:
Authenticated Clickwrap (HMAC) UTF-8
Signature Pad UTF-16LE
You can use the getBytes method to do this. For example:

theCertificateCertificateThe server certificate.
If you pass null, the method will verify the HMAC signature but will not sign it.
If you pass in a certificate and if the HMAC signature is valid, the method will use the private key of the certificate to digitally sign the HMAC signature. This signature is appended to the signature item, and can be verified using UFLVerifySignature.
theStatusIntHolderThis is a status flag that reports whether the operation was successful. Possible values are:
SecurityUserStatusType.SUSTATUS_OK — the operation was successful.
SecurityUserStatusType.SUSTATUS_ CANCELLED — the operation was cancelled by the user.
SecurityUserStatusType.SUSTATUS_INPUT_ REQUIRED — the operation required user input, but could not receive it (for example, it was run on a server with no user).


A constant if the verification is successful, or throws a generic exception (UWIException) if an error occurs. The following table lists the possible return values:
Table 2. return codes
CodeNumeric ValueStatus
FormNodeP.UFL_DS_OK0The signature is verified.
FormNodeP.UFL_DS_ALGORITHM UNAVAILABLE13590The appropriate verification engine for the signature is not available.
FormNodeP.UFL_DS_F2MATCHSIGNER13529The certificate does not match the signer's name.
FormNodeP.UFL_DS_FAILED AUTHENTICATION1272The signature is invalid or the secret used is incorrect.
FormNodeP.UFL_DS_HASHCOMPFAILED13527The document has been tampered with.
FormNodeP.UFL_DS_NOSIGNATURE13526There is no signature.
FormNodeP.UFL_DS_NOT AUTHENTICATED1240The signer cannot be authenticated.
FormNodeP.UFL_DS_UNEXPECTED13589An unexpected error occurred.
FormNodeP.UFL_DS_UNVERIFIABLE859The signature cannot be verified.


The following example uses getSignature to get a signature object, and uses getDataByPath to get the signer's identity from the signature object. Next, it calls validateHMACWithHashedSecret to validate the signature.
   public short checkSignature(FormNodeP theSignatureNode, Certificate theServerCert)
   Signature theSignatureObject;
   byte  [] hashedSecret;
   String signerCommonName;
   BooleanHolder encodedData;
   IntHolder theStatus;
   short validation;
      theSignatureObject = theSignatureNode.getSignature();
      encodedData = new BooleanHolder();
      if ((signerCommonName = theSignatureObject.getDataByPath(
         "SigningCert: Subject: CN", false, encodedData)) == null)
         throw new UWIException("Could not determine signer's name.");
      /* Include external code that matches the signer's identity to a hashed 
         shared secret, sets hashedSecret to match.  This is most likely a 
         database lookup. */
         theStatus = new IntHolder();
      validation = theSignatureNode.validateHMACWithHashedSecret(
         hashedSecret, theServerCert, theStatus);
      /* Check the status in case the process required user input. */
      if (theStatus.value != SecurityUserStatusType.SUSTATUS_OK)
         throw new UWIException("Validation required user input.");

Parent topic:
FormNodeP class