code: /*
   * This file is part of WebGoat, an Open Web Application Security Project utility. For details, please see http://www.owasp.org/
   *
   * Copyright (c) 2002 - 2019 Bruce Mayhew
   *
   * This program is free software; you can redistribute it and/or modify it under the terms of the
   * GNU General Public License as published by the Free Software Foundation; either version 2 of the
   * License, or (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
   * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License along with this program; if
   * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   * 02111-1307, USA.
   *
   * Getting Source ==============
   *
   * Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository for free software projects.
   */
  
  package org.owasp.webgoat.crypto;
  
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  import java.util.Random;
  
  import javax.servlet.http.HttpServletRequest;
  import javax.xml.bind.DatatypeConverter;
  
  import org.owasp.webgoat.assignments.AssignmentEndpoint;
  import org.owasp.webgoat.assignments.AssignmentHints;
  import org.owasp.webgoat.assignments.AttackResult;
  import org.springframework.http.MediaType;
  import org.springframework.web.bind.annotation.PostMapping;
  import org.springframework.web.bind.annotation.RequestMapping;
  import org.springframework.web.bind.annotation.RequestParam;
  import org.springframework.web.bind.annotation.ResponseBody;
  import org.springframework.web.bind.annotation.RestController;
  
  @RestController
  @AssignmentHints({"crypto-hashing.hints.1","crypto-hashing.hints.2"})
  public class HashingAssignment extends AssignmentEndpoint {
  	
  	public static final String[] SECRETS = {"secret","admin","password", "123456", "passw0rd"};
  
  	@RequestMapping(path="/crypto/hashing/md5",produces=MediaType.TEXT_HTML_VALUE)
      @ResponseBody
      public String getMd5(HttpServletRequest request) throws NoSuchAlgorithmException {
  		
  		String md5Hash = (String) request.getSession().getAttribute("md5Hash");
  		if (md5Hash == null) {
  			
  			String secret = SECRETS[new Random().nextInt(SECRETS.length)];
  	         
  		    MessageDigest md = MessageDigest.getInstance("MD5");
  		    md.update(secret.getBytes());
  		    byte[] digest = md.digest();
  		    md5Hash = DatatypeConverter
  		      .printHexBinary(digest).toUpperCase();
  			request.getSession().setAttribute("md5Hash", md5Hash);
  			request.getSession().setAttribute("md5Secret", secret);
  		}
  		return md5Hash;
      }
  	
  	@RequestMapping(path="/crypto/hashing/sha256",produces=MediaType.TEXT_HTML_VALUE)
      @ResponseBody
      public String getSha256(HttpServletRequest request) throws NoSuchAlgorithmException {
  		
  		String sha256 = (String) request.getSession().getAttribute("sha256");
  		if (sha256 == null) {
  			String secret = SECRETS[new Random().nextInt(SECRETS.length)];
  		    sha256 = getHash(secret, "SHA-256");
  			request.getSession().setAttribute("sha256Hash", sha256);
  			request.getSession().setAttribute("sha256Secret", secret);
  		}
  		return sha256;
      }
  	
      @PostMapping("/crypto/hashing")
      @ResponseBody
      public AttackResult completed(HttpServletRequest request, @RequestParam String answer_pwd1, @RequestParam String answer_pwd2) {
          
      	String md5Secret = (String) request.getSession().getAttribute("md5Secret");
      	String sha256Secret = (String) request.getSession().getAttribute("sha256Secret");
      	
      	if (answer_pwd1!=null && answer_pwd2 !=null) {
          	if (answer_pwd1.equals(md5Secret)
          		&& answer_pwd2.equals(sha256Secret)) {
          		return success(this)
          				.feedback("crypto-hashing.success")
          				.build();
          	} else if (answer_pwd1.equals(md5Secret)
              		|| answer_pwd2.equals(sha256Secret)) {
          		return failed(this).feedback("crypto-hashing.oneok").build();
          	} 
          } 
          return failed(this).feedback("crypto-hashing.empty").build(); 
      }
      
      public static String getHash(String secret, String algorithm) throws NoSuchAlgorithmException {
      	MessageDigest md = MessageDigest.getInstance(algorithm);
  	    md.update(secret.getBytes());
  	    byte[] digest = md.digest();
  	    return DatatypeConverter
  	      .printHexBinary(digest).toUpperCase();
      }
      
  }
  