title: Spring Security: password don't match with stored one
body: <p>I have a problem with password hashing. I want to appply sha-256 with salt and 1024 iterations to authenticate my users using Spring Security. But somehow, my password in database dont match those from user input.</p>
  
  <p>Here is my code:</p>
  
  <p><strong>security-context.xml</strong></p>
  
  <pre><code>&lt;beans:bean
      id="passwordEncoder"
      class="org.springframework.security.authentication.encoding.ShaPasswordEncoder" &gt;
      &lt;beans:constructor-arg value="256" /&gt;
      &lt;beans:property
          name="iterations"
          value="1024" /&gt;
  &lt;/beans:bean&gt;
  
  &lt;beans:bean class="org.springframework.security.authentication.dao.ReflectionSaltSource" id="saltSource"&gt;
      &lt;beans:property name="userPropertyToUse" value="id"/&gt;
  &lt;/beans:bean&gt;
  
  &lt;authentication-manager&gt;
      &lt;authentication-provider user-service-ref="userLoginDetails" &gt;
          &lt;password-encoder ref="passwordEncoder" &gt;
               &lt;salt-source ref="saltSource"/&gt;
          &lt;/password-encoder&gt;
      &lt;/authentication-provider&gt;
  &lt;/authentication-manager&gt;
  </code></pre>
  
  <p><strong>userLoginDetails</strong></p>
  
  <pre><code>@Transactional(readOnly = true)
  public class UserLoginDetails implements UserDetailsService {
  
  private EregDaoFactory daoFactory;
  
  @Autowired
  public void setDaoFactory(EregDaoFactory daoFactory) {
      this.daoFactory = daoFactory;
  }
  
  /**
   * Retrieves a user record containing the user's credentials and access.
   */
  @Override
  public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException,
          DataAccessException {
      Logger logger = Logger.getLogger(getClass());
      logger.setLevel(Level.ALL);
  
      int userId = Integer.parseInt(username);
  
      UzytkownikDao dao = daoFactory.getUzytkownikDao();
  
      LoggedUser user = null;
      Uzytkownik dbUser = null;
  
      try {
  
          dbUser = (Uzytkownik) dao.findById(Integer.parseInt(username));
          List&lt;SimpleGrantedAuthority&gt; grants = new ArrayList&lt;SimpleGrantedAuthority&gt;();
          Collection&lt;Object&gt; userNames = new ArrayList&lt;Object&gt;();
  
          if (dbUser.getRola() == 'U') {
              grants.add(new SimpleGrantedAuthority("ROLE_STUDENT"));
              userNames = daoFactory.getUczenDao().getNameAndLastName(userId);
  
          } else if (dbUser.getRola() == 'N') {
              grants.add(new SimpleGrantedAuthority("ROLE_TEACHER"));
              userNames = daoFactory.getNauczycielDao().getNameAndLastName(userId);
          } else if (dbUser.getRola() == 'O') {
              grants.add(new SimpleGrantedAuthority("ROLE_PARENT"));
              userNames = daoFactory.getOpiekunDao().getNameAndLastName(userId);
          }
          grants.add(new SimpleGrantedAuthority("ROLE_USER"));
  
          Object[] names = userNames.toArray();
          user =
                  new LoggedUser(username, dbUser.getHaslo(), true, true, true, true, grants,
                          (String) names[0], (String) names[1], dbUser.getRola());
      } catch (Exception e) {
          logger.error(e.getLocalizedMessage());
          throw new UsernameNotFoundException("Error in retrieving user");
  
      }
  
      return user;
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>LoggedUser</strong></p>
  
  <pre><code>    package ereg.security.userdetails;
  
  public class LoggedUser extends User {
  
  private static final long serialVersionUID = 1L;
  private final String id;
  private final String imie;
  private final String nazwisko;
  private final char rola;
  private Date lastSuccessfulLogin;
  private String lastKnowIpAddress;
  
  public LoggedUser(String username, String password, boolean enabled, boolean accountNonExpired,
          boolean credentialsNonExpired, boolean accountNonLocked,
          Collection&lt;? extends GrantedAuthority&gt; authorities, String name, String lastName, char rola) {
      super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,
              authorities);
      this.imie = name;
      this.nazwisko = lastName;
      this.rola = rola;
      this.id = username;
  }
  
  public String getId() {
      return id;
  }
  
  public String getImie() {
      return imie;
  }
  
  public String getNazwisko() {
      return nazwisko;
  }
  
  public char getRola() {
      return rola;
  }
  
  public Date getLastSuccessfulLogin() {
      return lastSuccessfulLogin;
  }
  
  public String getFormattedDate() {
      if (lastSuccessfulLogin != null) {
          return new SimpleDateFormat("dd/MM/yyyy, HH:mm:ss").format(lastSuccessfulLogin);
      } else
          return null;
  }
  
  public String getLastKnowIpAddress() {
      return lastKnowIpAddress;
  }
  
  public void setLastSuccessfulLogin(Date lastSuccessfulLogin) {
      this.lastSuccessfulLogin = lastSuccessfulLogin;
  }
  
  public void setLastKnowIpAddress(String lastKnowIpAddress) {
      this.lastKnowIpAddress = lastKnowIpAddress;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>And here is the program that hashes passwords:</p>
  
  <p><strong>EncryptAllUsersPasswords</strong></p>
  
  <pre><code>private void encryptPasswords() throws Exception {
      OneWayEncryptor encryptor = OneWayEncryptor.getInstance();
  
      appContext =
              new FileSystemXmlApplicationContext(
                      "C:/EclipseWorkSpace/myereg/WebContent/WEB-INF/applicationContext.xml");
  
      ds = (DataSource) appContext.getBean("dataSource");
      JdbcTemplate jdbc = new JdbcTemplate(ds);
      BigDecimal userId = null;
      String password = "";
      String encrypted = "";
  
      Map&lt;?, ?&gt; row = new HashMap&lt;Object, Object&gt;();
  
      for (Iterator&lt;?&gt; it = jdbc.queryForList("SELECT id, haslo FROM UZYTKOWNIK").iterator(); it.hasNext();) {
          row = (Map&lt;?, ?&gt;) it.next();
  
          userId = (BigDecimal) row.get("ID");
          password = (String) row.get("HASLO");
          encrypted = encryptor.encrypt(password, userId.toString());
  
          System.out.println(userId.toString());
  
          jdbc.execute("UPDATE UZYTKOWNIK SET haslo = '" + encrypted + "'  WHERE id = " + userId);
  
      }
  }
  
  public static void main(String[] args) {
  
      EncryptAllUserPasswords encrypt = new EncryptAllUserPasswords();
      try {
          encrypt.encryptPasswords();
      } catch (Exception e) {
          e.printStackTrace();
      }
  
  }
  </code></pre>
  
  <p><strong>OneWayEncryptor</strong></p>
  
  <pre><code>public final class OneWayEncryptor {
  private static final OneWayEncryptor INSTANCE = new OneWayEncryptor();
  
  private static final int ITERATIONS = 1024;
  private static final String ALGORITHM = "SHA-256";
  
  private OneWayEncryptor() {
  }
  
  public static OneWayEncryptor getInstance() {
      return INSTANCE;
  
  }
  
  public String encrypt(String plaintext, String salt) throws NoSuchAlgorithmException,
          UnsupportedEncodingException {
      MessageDigest messageDigest = MessageDigest.getInstance(ALGORITHM);
  
      messageDigest.reset();
      messageDigest.update(salt.getBytes());
  
      byte[] btPass = messageDigest.digest(plaintext.getBytes("UTF-8"));
      for (int i = 0; i &lt; ITERATIONS; i++) {
          messageDigest.reset();
          btPass = messageDigest.digest(btPass);
      }
  
      String encodedPassword = byteToBase64(btPass);
  
      return encodedPassword;
  }
  
  private String byteToBase64(byte[] bt) throws UnsupportedEncodingException {
  
      return new String(Base64.encodeBase64(bt));
  
  }
  </code></pre>
  
  <p>}</p>
  
  <p>I believe that problem lies in the last one... Please help</p>