code: public static byte[] hmacMD5(byte[] data, byte[] key) throws Exception {
          byte[] ipad = new byte[64];
          byte[] opad = new byte[64];
  
          // Stores key in pads and XOR it with ipad and opad values
          for (int i = 0; i < 64; i++) {
              if (i < key.length) {
                  ipad[i] = (byte) (key[i] ^ 0x36);
                  opad[i] = (byte) (key[i] ^ 0x5c);
              } else {
                  ipad[i] = 0x36;
                  opad[i] = 0x5c;
              }
          }
  
          byte[] content = new byte[data.length + 64];
          System.arraycopy(ipad, 0, content, 0, 64);
          System.arraycopy(data, 0, content, 64, data.length);
          MessageDigest md5 = MessageDigest.getInstance("MD5");
          data = md5.digest(content);
          content = new byte[data.length + 64];
          System.arraycopy(opad, 0, content, 0, 64);
          System.arraycopy(data, 0, content, 64, data.length);
          return md5.digest(content);
      }
docs: Calculates the HMAC-MD5 hash of the given data using the specified
  hashing key.
  
  @param data The data for which the hash will be calculated.
  @param key The hashing key.
  
  @return The HMAC-MD5 hash of the given data.