Example of implementation with JAVA

Definition of the utility class SHA that will include the elements required to process the HMAC-SHA-256 algorithm

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.TreeMap;
	                
public class VadsSignatureExample {
 /**
  * Build signature (HMAC SHA-256 version) from provided parameters and secret key.
  * Parameters are provided as a TreeMap (with sorted keys).
  */
 public static String buildSignature(TreeMap<String, String> formParameters, String
  secretKey) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
   // Build message from parameters
   String message = String.join("+", formParameters.values());
   message += "+" + secretKey;
   // Sign
   return hmacSha256Base64(message, secretKey);
  }	                    
    /**
    * Actual signing operation.
    */
 public static String hmacSha256Base64(String message, String secretKey) throws
  NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
   // Prepare hmac sha256 cipher algorithm with provided secretKey
   Mac hmacSha256;
   try {
    hmacSha256 = Mac.getInstance("HmacSHA256");
   } catch (NoSuchAlgorithmException nsae) {
    hmacSha256 = Mac.getInstance("HMAC-SHA-256");
   }
   SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256");
   hmacSha256.init(secretKeySpec);
   // Build and return signature
   return Base64.getEncoder().encodeToString(hmacSha256.doFinal(message.getBytes("UTF-8")));
  }
}

Definition of the utility class SHA that will include the elements required to process the SHA-1 algorithm

import java.security.MessageDigest; 
import java.security.SecureRandom; 

public class Sha {
    static public final String SEPARATOR = "+" ;
    public static String encode(String src) {
        try { 
            MessageDigest md;
            md = MessageDigest.getInstance( "SHA-1" ); 
            byte bytes[] = src.getBytes( "UTF-8" ); 
            md.update(bytes, 0, bytes. length ); 
            byte[] sha1hash = md.digest(); 
            return convertToHex(sha1hash);
        }    
        catch(Exception e){ 
            throw new RuntimeException(e);
        } 
    } 
    private static String convertToHex(byte[] sha1hash) {
        StringBuilder builder = new StringBuilder(); 
            for (int i = 0; i < sha1hash. length ; i++) { 
               byte c = sha1hash[i]; 
               addHex(builder, (c >> 4) & 0xf); 
               addHex(builder, c & 0xf);
        } 
        return builder.toString();
    } 
    private static void addHex(StringBuilder builder, int c) { 
        if (c < 10) 
            builder.append((char) (c + '0' ));
        else 
            builder.append((char) (c + 'a' - 10));
    }
}

Function that computes the signature:

public ActionForward performCheck(ActionMapping actionMapping, Basivoirorm form,
    HttpServletRequest request, HttpServletResponse response){
        SortedSet<String> vadsFields = new TreeSet<String>();
        Enumeration<String> paramNames = request.getParameterNames(); 
       
        // retrieve and sort the fields starting with vads_* alphabetically
        while (paramNames.hasMoreElements()) {
            String paramName = paramNames.nextElement();
            if (paramName.startsWith( "vads_" )) {
                vadsFields.add(paramName);
            }
        }
// Compute the signature
String sep = Sha.SEPARATOR;
StringBuilder sb = new StringBuilder();
for (String vadsParamName : vadsFields) {
    String vadsParamValue = request.getParameter(vadsParamName);
    if (vadsParamValue != null) { 
        sb.append(vadsParamValue);
    }
    sb.append(sep);
} 
sb.append( shaKey );
String c_sign = Sha.encode(sb.toString());
return c_sign;}