用戶登錄相關安全 密碼加密


1

用戶登錄密碼加密https://blog.csdn.net/Cxx941112/article/details/86749827

/**
* 密碼加密
*
* @param pwd 原始密碼
* @param salt 鹽值
* @return
*/

public String encryptedPassword(String pwd, String salt) {
    String pwdSalt = new Md5Hash(pwd, salt, 3).toString();
    return pwdSalt;
}

//生成鹽
String salt = new SecureRandomNumberGenerator().nextBytes().toHex();
//最后生成加密后的密碼存入數據庫
String pwdSalt = this.encryptedPassword(pwd, salt);

在用戶登錄時,首先拿到數據庫的鹽值,再與用戶輸入的密碼進行加密處理,最后與數據庫的pwdSalt進行匹配實現登錄

2

http登錄模塊加密登錄安全登錄方法 https://blog.csdn.net/qq_37969433/article/details/82343804

http請求很容易被截獲,在寫登錄模塊時,直接使用明文密碼請求,很容易明文密碼泄露;若在js頁面對密碼進行一次加密后在傳輸,雖不是明文密碼,但也完全可以截獲加密后的暗文,偽造http請求進行登錄。為了防止密碼泄露,通過參考各種方案,找到了以下比較好實現的方法:
1、登錄請求分兩次進行,第一次僅傳用戶名
2、服務器收到用戶名后,生成一串隨機數,將隨機數響應給客戶端,並將用戶名和隨機數存到session
3、客戶端收到響應后,將密碼和隨機數安一定的規則組合起來,再md5加密,再http請求(此時保證了每一次登錄請求的密碼會隨隨機數的不同而不同,這個隨機數為服務器生成,相當於一個公鑰,與本次登錄操作唯一且一一對應,客戶端無法偽造)
4、服務器收到請求,取出session中的用戶名和隨機數串,核對用戶名,再取數據庫中的正確密碼,再按相同的規則與隨機數組合並md5加密,再比較請求的密碼暗文,返回登錄結果。
附一張更清晰的圖,可以看到就算在傳輸過程的所有信息都暴露出來,也無法根據這些偽造出http請求登錄成功。

3

用戶登錄對密碼進行加密 https://blog.csdn.net/chen_3010/article/details/71440754

Java后端

/**
     * 生成公鑰
     * @return  
     * @throws Exception
     */
	@ClearInterceptor(ClearLayer.ALL)
    public void Rdspwd() throws Exception{
    	HttpServletResponse response = getResponse();;
        PrintWriter writer = response.getWriter();
        String publicKey = RSAUtils.generateBase64PublicKey();
        writer.write(publicKey);        
        renderNull();
    }



public class RSAUtils {
	
	 //KeyPair is a simple holder for a key pair.
    private static final KeyPair keyPair = initKey();
    /**
     * 初始化方法,產生key pair,提供provider和random
     * @return KeyPair instance
     */
    private static KeyPair initKey() {
 
        try {
            //添加provider
            Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
            Security.addProvider(provider);
            //產生用於安全加密的隨機數
            SecureRandom random = new SecureRandom();
 
            KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", provider);
            generator.initialize(1024, random); 
            return generator.generateKeyPair();
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 產生public key
     * @return public key字符串
     */
    public static String generateBase64PublicKey() {
        PublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
 
        //encodeBase64(): Encodes binary data using the base64 
        //algorithm but does not chunk the output.
        //getEncoded():返回key的原始編碼形式
        return new String(Base64.encodeBase64(publicKey.getEncoded()));
    }
    /**
     * 解密數據
     * @param string 需要解密的字符串
     * @return  破解之后的字符串
     */
    public static String decryptBase64(String string) {
        //decodeBase64():將Base64數據解碼為"八位字節”數據
        return new String(decrypt(Base64.decodeBase64(string.getBytes())));
    }
 
    private static byte[] decrypt(byte[] byteArray) {
        try {
            Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
            Security.addProvider(provider);
            //Cipher: 提供加密和解密功能的實例
            //transformation: "algorithm/mode/padding"
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
            PrivateKey privateKey = keyPair.getPrivate();
            //初始化
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            //doFinal(): 加密或者解密數據
            byte[] plainText = cipher.doFinal(byteArray);
            return plainText;
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }
 
}


//解密帳號
username = RSAUtils.decryptBase64(username);
//解密密碼
password = RSAUtils.decryptBase64(password);

js 前端


<button type="button" id="login-btn" class="width-35 btn btn-sm btn-primary" οnclick="doLogin()">
	<i class="ace-icon fa fa-key"></i>
	<span class="bigger-110" >登錄</span>
</button>

//在頁面一加載的時候就Ajax請求生成公鑰的方法
//獲取public key
 var publicKey = null;
function getPublicKey(dologin){
  $.ajax({
	url: "/login/Rdspwd",
     	type: "post",
     	dataType: "text",
     	success: function(data) {
     		if(data) publicKey = data;
     		if(dologin==1){
     			if(publicKey==null){
     				$("#msg").html("獲取publicKey失敗,請聯系管理員!");
     				$("#login-btn").removeAttr("disabled");
     			}else{
     				doLogin(1);
     			}
     		}
     	}
  });
}


var ustring = $.trim($("#ustring").val());
var pstring = $.trim($("#pstring").val());

//根據公鑰進行加密:
var encrypt = new JSEncrypt();
  if(publicKey != null){
     encrypt.setPublicKey(publicKey);
    var password = encrypt.encrypt(pstring);
    var username = encrypt.encrypt(ustring);
   //提交之前,檢查是否已經加密。假設用戶的密碼不超過20位,加密后的密碼不小於20位
   if(password.length < 20) {
      //加密失敗提示
     alert("登錄失敗,請稍后重試...");
   }else{
	 $.ajax({
		url: "${contextPath}/dologin",
	        type: "post",
		data: {"usname": username,"pwd": password,"vcstring": vcstring},
		dataType: "json",
                ....
            )}
   }
}

// https://github.com/travist/jsencrypt JSEncrypt

4

如何正確對用戶密碼進行加密 https://www.infoq.cn/article/how-to-encrypt-the-user-password-correctly

5

Web 前端密碼加密是否有意義?https://www.zhihu.com/question/25539382

6 https

https 能使請求數據在傳輸過程中加密,傳輸過程相對安全,但有可能有惡意軟件在數據發出之前截獲數據(比如授權抓包)

https://www.cnblogs.com/javastack/p/13372660.html
https://www.zhihu.com/question/277749568
https://www.cnblogs.com/tester-xt/p/13174279.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM