Java for Web Learning Notes (107): Using JPA (7) Passwords and Bcrypt__java in the spring framework

Source: Internet
Author: User
Tags md5
safe storage of passwords

Password security has two aspects: the security of a user's password pass, which can be protected by using HTTPS, or by hashing the password (for example, MD5) and passing it (a bit more complex, the password is involved in the hash, it contains some dynamic parameters, such as a timestamp, etc. for salt), or the combination of the two The security of the database password store, once the library is dragged, or otherwise hacked, can still safely protect the user's password.

At present, bcrypt encryption is generally used, we must not be in the plaintext of the password, or through a weak hash (such as MD5 and SHA) stored in the database. Bcrypt, as an industrial product, produces a different salt for each cipher, making it much more difficult to make dictionaries, while MD5 and Sha are much simpler to decipher.

Database Tables Bcrypt requires 60 bytes of storage after encryption, here is an example of a table:

CREATE TABLE Userprincipal (
  UserId BIGINT UNSIGNED not NULL auto_increment KEY,
  PRIMARY Username () NULL,
  Hashedpassword BINARY not NULL,
  UNIQUE KEY userprincipal_username (Username)
) ENGINE = InnoDB;

Bcrypt encrypted string like: $2a$10$vacuqbdw9i7rr6rrh8sbyuktozqtheqmfnk3xct2wlal7vt/3amby, where: $ is a separator, meaningless; 2a is bcrypt encrypted version number 10 is the value of the cost, then the first 22 is the salt value, then the string is the cipher ciphertext;

We will use Userprincipal as the entity code as follows:

/** considering storing principal in session, we will implement the principal interface and provide colonable interface * For principal, how do we judge the same (this example takes the user name), overrides the object's Hashcode (), Equals () and ToString ().
* * @Entity @Table (uniqueconstraints={@UniqueConstraint (name = "Userprincipal_username", columnnames= "Username")})
	public class Userprincipal implements principal,cloneable,serializable{private static final long serialversionuid = 1L;

	private static final String Session_attribute_key = "Cn.wei.flowingflying.customer_support.user.principal";
	Private long ID;
	Private String username;

	Private byte[] password;
	@Id @Column (name= "UserId") @GeneratedValue (strategy=generationtype.identity) public long getId () {return Id;
	public void SetId (long id) {this.id = ID;
	@Basic public String GetUserName () {return username;
	} public void Setusername (String username) {this.username = username;
	@Basic @Column (name = "Hashedpassword") public byte[] GetPassword () {return password;
	} public void SetPassword (byte[] password) {	This.password = password;
	@Override @Transient public String getName () {return this.username; }/* For Principal, it is important to compare the two, so the following methods for overriding object * * @Override @Transient public int hashcode () {return This.userna
	Me.hashcode (); @Override @Transient public boolean equals (Object obj) {return obj instanceof Userprincipal && (use
	Rprincipal) obj). Username.equals (This.username);
		@Override @Transient protected Userprincipal clone () {try {return (Userprincipal) Super.clone ();

	catch (Clonenotsupportedexception e) {throw new RuntimeException (e);//Convert to RuntimeException so transaction can roll back}}
	@Override @Transient public String toString () {return this.username; /* * To provide static methods for calls to store and retrieve Principal/public static Principal Getprincipal (HttpSession session) {return SES sion = null?
	Null: (Principal) Session.getattribute (Session_attribute_key); public static void Setprincipal (HttpSession session, Principal PrincIpal) {Session.setattribute (Session_attribute_key, principal); }	
}
Password Checksum introduction of Jbcrypt

Jbcrypt:openbsd-style Blowfish Password hashing for Java Industry-standard Jbcrypt Java Implementation of the Bcrypt hash Algorithm.

In the Pom.xml

<dependency>
    <groupId>org.mindrot</groupId>
    <artifactid>jbcrypt</artifactid >
    <version>0.4</version>
</dependency>
implementation of repository interfacePrior to introducing the implementation of the generic repository interface, we need to add the acquisition via the unique KEY (username) as follows:

Public interface Userrepository extends Genericrepository<long, userprincipal>{
    Userprincipal Getbyusername (String username);
 @Repository public class Defaultuserrepository extends Genericjparepository<long, Userprincipal > Implements userrepository{@Override public userprincipal getbyusername (String username) {//"mode 1" through JAV A persistence query, that is, JPQL//Return This.entityManager.createQuery (//) Select U from Userprincipal U WHERE u.username =: username ",//Userprincipal.class//). Setparameter (" username ", username). GetS

Ingleresult ();
         "Mode 2" through the JPA standard interface Criteriabuilder builder = This.entityManager.getCriteriaBuilder ();
         criteriaquery<userprincipal> query = Builder.createquery (This.entityclass);
         root<userprincipal> root = Query.from (This.entityclass); Return This.entityManager.createQuery (Query.select (Root). where (Builder.equal root.get ("Userna			
	Me "), username). Getsingleresult (); }
}
password Check related code
@Validated Public
interface AuthenticationService {
	Principal authenticate (the @NotBlank (message = "{ Validate.authenticate.username} ") String username, 
			@NotBlank (message =" {Validate.authenticate.password} ") String password);
	
	void Saveuser (@NotNull (message = "{Validate.authenticate.saveUser}") @Valid Userprincipal principal,
            String NewPassword
    );
}
@Service public class Defaultauthenticationservice implements authenticationservice{private static final Logger log =
    Logmanager.getlogger ();
    private static final SecureRandom RANDOM;
    private static final int hashing_rounds = 10;
        static {try {RANDOM = Securerandom.getinstancestrong ();
        catch (NoSuchAlgorithmException e) {throw new IllegalStateException (e);
	
    }} @Inject userrepository userrepository; @Override @Transactional public Principal Authenticate (@NotBlank (message = "{validate.authenticate.username}") Str 
        ing username, @NotBlank (message = "{Validate.authenticate.password}") String password) {
        Userprincipal principal = This.userRepository.getByUsername (username);
            if (principal = = null) {Log.warn ("Authentication failed for non-existent user {}.", username);
        return null; } if (! BCRYPT.CHECKPW (Password, new String (Principal.getpassword (), standardcharsets.utf_8)) {Log.warn ("Authentication failed for user {}.", User
            name);
        return null;
        } log.debug ("User {} successfully authenticated.", username);
    return principal;  @Override @Transactional public void Saveuser (@NotNull (message = "{Validate.authenticate.saveUser}") @Valid Userprincipal principal, String NewPassword) {if (NewPassword!= null && newpass
            Word.length () > 0) {String salt = Bcrypt.gensalt (hashing_rounds, RANDOM);
        Principal.setpassword (BCRYPT.HASHPW (newpassword, salt). GetBytes ());
        if (Principal.getid () < 1) This.userRepository.add (principal);		
    else This.userRepository.update (principal); }
}
RELATED links: My professional Java for WEB applications related articles

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.