(improvement)(login) encrypt password (#1081) (#1116)

This commit is contained in:
zhaodongsheng
2024-06-09 08:16:45 +08:00
committed by GitHub
parent dcb7f21241
commit 5bc88b78a9
15 changed files with 289 additions and 95 deletions

View File

@@ -9,6 +9,7 @@ import com.tencent.supersonic.auth.api.authentication.pojo.UserWithPassword;
import com.tencent.supersonic.auth.api.authentication.request.UserReq;
import com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO;
import com.tencent.supersonic.auth.authentication.persistence.repository.UserRepository;
import com.tencent.supersonic.auth.authentication.utils.AESEncryptionUtil;
import com.tencent.supersonic.auth.authentication.utils.UserTokenUtils;
import com.tencent.supersonic.common.util.ContextUtils;
import org.springframework.beans.BeanUtils;
@@ -72,6 +73,14 @@ public class DefaultUserAdaptor implements UserAdaptor {
}
UserDO userDO = new UserDO();
BeanUtils.copyProperties(userReq, userDO);
try {
byte[] salt = AESEncryptionUtil.generateSalt(userDO.getName());
userDO.setSalt(AESEncryptionUtil.getStringFromBytes(salt));
System.out.println("salt: " + userDO.getSalt());
userDO.setPassword(AESEncryptionUtil.encrypt(userReq.getPassword(), salt));
} catch (Exception e) {
throw new RuntimeException("password encrypt error, please try again");
}
userRepository.addUser(userDO);
}
@@ -82,12 +91,24 @@ public class DefaultUserAdaptor implements UserAdaptor {
if (userDO == null) {
throw new RuntimeException("user not exist,please register");
}
if (userDO.getPassword().equals(userReq.getPassword())) {
UserWithPassword user = UserWithPassword.get(userDO.getId(), userDO.getName(), userDO.getDisplayName(),
userDO.getEmail(), userDO.getPassword(), userDO.getIsAdmin());
return userTokenUtils.generateToken(user);
try {
String password = AESEncryptionUtil.encrypt(userReq.getPassword(),
AESEncryptionUtil.getBytesFromString(userDO.getSalt()));
System.out.println("userReq.getPassword(): " + userReq.getPassword());
System.out.println("password: " + password);
System.out.println("userDO.getPassword(): " + userDO.getPassword());
if (userDO.getPassword().equals(password)) {
UserWithPassword user = UserWithPassword.get(userDO.getId(), userDO.getName(), userDO.getDisplayName(),
userDO.getEmail(), userDO.getPassword(), userDO.getIsAdmin());
return userTokenUtils.generateToken(user);
} else {
throw new RuntimeException("password not correct, please try again");
}
} catch (Exception e) {
throw new RuntimeException("password encrypt error, please try again");
}
throw new RuntimeException("password not correct, please try again");
}
@Override

View File

@@ -16,6 +16,8 @@ public class UserDO {
*/
private String password;
private String salt;
/**
*
*/
@@ -79,6 +81,14 @@ public class UserDO {
this.password = password == null ? null : password.trim();
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt == null ? null : salt.trim();
}
/**
*
* @return display_name

View File

@@ -0,0 +1,59 @@
package com.tencent.supersonic.auth.authentication.utils;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.MessageDigest;
import java.security.spec.KeySpec;
import java.util.Base64;
public class AESEncryptionUtil {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String ENCODE = "UTF-8";
private static final String SECRET_KEY_ALGORITHM = "PBKDF2WithHmacSHA256";
private static final int ITERATIONS = 65536;
private static final int KEY_LENGTH = 256;
public static byte[] generateSalt(String username) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(username.getBytes(ENCODE));
byte[] hash = md.digest();
// 通常只需要使用盐的一部分作为盐值例如16字节
byte[] salt = new byte[16];
System.arraycopy(hash, 0, salt, 0, salt.length);
return salt;
}
public static String encrypt(String password, byte[] salt) throws Exception {
// TODO 固定IV确保每次加密时使用相同的IV,该值应该安全保管
byte[] iv = "supersonic@bicom".getBytes(ENCODE);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, ITERATIONS, KEY_LENGTH);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(SECRET_KEY_ALGORITHM);
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(password.getBytes(ENCODE));
byte[] combined = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, combined, 0, iv.length);
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length);
return Base64.getEncoder().encodeToString(combined);
}
public static String getStringFromBytes(byte[] salt) {
return Base64.getEncoder().encodeToString(salt);
}
public static byte[] getBytesFromString(String encodeSalt) {
return Base64.getDecoder().decode(encodeSalt);
}
}

View File

@@ -5,6 +5,7 @@
<result column="id" jdbcType="BIGINT" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="password" jdbcType="VARCHAR" property="password" />
<result column="salt" jdbcType="VARCHAR" property="salt" />
<result column="display_name" jdbcType="VARCHAR" property="displayName" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="is_admin" jdbcType="INTEGER" property="isAdmin" />
@@ -39,7 +40,7 @@
</where>
</sql>
<sql id="Base_Column_List">
id, name, password, display_name, email, is_admin
id, name, password, salt, display_name, email, is_admin
</sql>
<select id="selectByExample" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDOExample" resultMap="BaseResultMap">
select
@@ -59,10 +60,10 @@
</if>
</select>
<insert id="insert" parameterType="com.tencent.supersonic.auth.authentication.persistence.dataobject.UserDO">
insert into s2_user (id, name, password,
insert into s2_user (id, name, password, salt,
display_name, email, is_admin
)
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR},
values (#{id,jdbcType=BIGINT}, #{name,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, #{salt,jdbcType=VARCHAR},
#{displayName,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{isAdmin,jdbcType=INTEGER}
)
</insert>
@@ -78,6 +79,9 @@
<if test="password != null">
password,
</if>
<if test="password != null">
salt,
</if>
<if test="displayName != null">
display_name,
</if>
@@ -98,6 +102,9 @@
<if test="password != null">
#{password,jdbcType=VARCHAR},
</if>
<if test="salt != null">
#{salt,jdbcType=VARCHAR},
</if>
<if test="displayName != null">
#{displayName,jdbcType=VARCHAR},
</if>