PHP PBKDF2 密码hash代码

<?php

/*

* Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm).

* Copyright (c) 2013, Taylor Hornby

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

* this list of conditions and the following disclaimer.

*

* 2. Redistributions in binary form must reproduce the above copyright notice,

* this list of conditions and the following disclaimer in the documentation

* and/or other materials provided with the distribution.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGE.

*/

// These constants may be changed without breaking existing hashes.

define("PBKDF2_HASH_ALGORITHM", "sha256");

define("PBKDF2_ITERATIONS", 1000);

define("PBKDF2_SALT_BYTE_SIZE", 24);

define("PBKDF2_HASH_BYTE_SIZE", 24);

define("HASH_SECTIONS", 4);

define("HASH_ALGORITHM_INDEX", 0);

define("HASH_ITERATION_INDEX", 1);

define("HASH_SALT_INDEX", 2);

define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)

{

// format: algorithm:iterations:salt:hash

$salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTE_SIZE, MCRYPT_DEV_URANDOM));

return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" .

base64_encode(pbkdf2(

PBKDF2_HASH_ALGORITHM,

$password,

$salt,

PBKDF2_ITERATIONS,

PBKDF2_HASH_BYTE_SIZE,

true

));

}

function validate_password($password, $correct_hash)

{

$params = explode(":", $correct_hash);

if(count($params) < HASH_SECTIONS)

return false;

$pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);

return slow_equals(

$pbkdf2,

pbkdf2(

$params[HASH_ALGORITHM_INDEX],

$password,

$params[HASH_SALT_INDEX],

(int)$params[HASH_ITERATION_INDEX],

strlen($pbkdf2),

true

)

);

}

// Compares two strings $a and $b in length-constant time.

function slow_equals($a, $b)

{

$diff = strlen($a) ^ strlen($b);

for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)

{

$diff |= ord($a[$i]) ^ ord($b[$i]);

}

return $diff === 0;

}

/*

* PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt

* $algorithm - The hash algorithm to use. Recommended: SHA256

* $password - The password.

* $salt - A salt that is unique to the password.

* $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.

* $key_length - The length of the derived key in bytes.

* $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.

* Returns: A $key_length-byte key derived from the password and salt.

*

* Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt

*

* This implementation of PBKDF2 was originally created by https://defuse.ca

* With improvements by http://www.variations-of-shadow.com

*/

function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)

{

$algorithm = strtolower($algorithm);

if(!in_array($algorithm, hash_algos(), true))

trigger_error('PBKDF2 ERROR: Invalid hash algorithm.', E_USER_ERROR);

if($count <= 0 || $key_length <= 0)

trigger_error('PBKDF2 ERROR: Invalid parameters.', E_USER_ERROR);

if (function_exists("hash_pbkdf2")) {

// The output length is in NIBBLES (4-bits) if $raw_output is false!

if (!$raw_output) {

$key_length = $key_length * 2;

}

return hash_pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output);

}

$hash_length = strlen(hash($algorithm, "", true));

$block_count = ceil($key_length / $hash_length);

$output = "";

for($i = 1; $i <= $block_count; $i++) {

// $i encoded as 4 bytes, big endian.

$last = $salt . pack("N", $i);

// first iteration

$last = $xorsum = hash_hmac($algorithm, $last, $password, true);

// perform the other $count - 1 iterations

for ($j = 1; $j < $count; $j++) {

$xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));

}

$output .= $xorsum;

}

if($raw_output)

return substr($output, 0, $key_length);

else

return bin2hex(substr($output, 0, $key_length));

}

?>

java PBKDF2 密码hash代码

/*

* Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm).

* Copyright (c) 2013, Taylor Hornby

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

* this list of conditions and the following disclaimer.

*

* 2. Redistributions in binary form must reproduce the above copyright notice,

* this list of conditions and the following disclaimer in the documentation

* and/or other materials provided with the distribution.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGE.

*/

import java.security.SecureRandom;

import javax.crypto.spec.PBEKeySpec;

import javax.crypto.SecretKeyFactory;

import java.math.BigInteger;

import java.security.NoSuchAlgorithmException;

import java.security.spec.InvalidKeySpecException;

/*

* PBKDF2 salted password hashing.

* Author: havoc AT defuse.ca

* www: http://crackstation.net/hashing-security.htm

*/

public class PasswordHash

{

public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";

// The following constants may be changed without breaking existing hashes.

public static final int SALT_BYTE_SIZE = 24;

public static final int HASH_BYTE_SIZE = 24;

public static final int PBKDF2_ITERATIONS = 1000;

public static final int ITERATION_INDEX = 0;

public static final int SALT_INDEX = 1;

public static final int PBKDF2_INDEX = 2;

/**

* Returns a salted PBKDF2 hash of the password.

*

* @param   password    the password to hash

* @return              a salted PBKDF2 hash of the password

*/

public static String createHash(String password)

throws NoSuchAlgorithmException, InvalidKeySpecException

{

return createHash(password.toCharArray());

}

/**

* Returns a salted PBKDF2 hash of the password.

*

* @param   password    the password to hash

* @return              a salted PBKDF2 hash of the password

*/

public static String createHash(char[] password)

throws NoSuchAlgorithmException, InvalidKeySpecException

{

// Generate a random salt

SecureRandom random = new SecureRandom();

byte[] salt = new byte[SALT_BYTE_SIZE];

random.nextBytes(salt);

// Hash the password

byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);

// format iterations:salt:hash

return PBKDF2_ITERATIONS + ":" + toHex(salt) + ":" +  toHex(hash);

}

/**

* Validates a password using a hash.

*

* @param   password        the password to check

* @param   correctHash     the hash of the valid password

* @return                  true if the password is correct, false if not

*/

public static boolean validatePassword(String password, String correctHash)

throws NoSuchAlgorithmException, InvalidKeySpecException

{

return validatePassword(password.toCharArray(), correctHash);

}

/**

* Validates a password using a hash.

*

* @param   password        the password to check

* @param   correctHash     the hash of the valid password

* @return                  true if the password is correct, false if not

*/

public static boolean validatePassword(char[] password, String correctHash)

throws NoSuchAlgorithmException, InvalidKeySpecException

{

// Decode the hash into its parameters

String[] params = correctHash.split(":");

int iterations = Integer.parseInt(params[ITERATION_INDEX]);

byte[] salt = fromHex(params[SALT_INDEX]);

byte[] hash = fromHex(params[PBKDF2_INDEX]);

// Compute the hash of the provided password, using the same salt,

// iteration count, and hash length

byte[] testHash = pbkdf2(password, salt, iterations, hash.length);

// Compare the hashes in constant time. The password is correct if

// both hashes match.

return slowEquals(hash, testHash);

}

/**

* Compares two byte arrays in length-constant time. This comparison method

* is used so that password hashes cannot be extracted from an on-line

* system using a timing attack and then attacked off-line.

*

* @param   a       the first byte array

* @param   b       the second byte array

* @return          true if both byte arrays are the same, false if not

*/

private static boolean slowEquals(byte[] a, byte[] b)

{

int diff = a.length ^ b.length;

for(int i = 0; i < a.length && i < b.length; i++)

diff |= a[i] ^ b[i];

return diff == 0;

}

/**

*  Computes the PBKDF2 hash of a password.

*

* @param   password    the password to hash.

* @param   salt        the salt

* @param   iterations  the iteration count (slowness factor)

* @param   bytes       the length of the hash to compute in bytes

* @return              the PBDKF2 hash of the password

*/

private static byte[] pbkdf2(char[] password, byte[] salt, int iterations, int bytes)

throws NoSuchAlgorithmException, InvalidKeySpecException

{

PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, bytes * 8);

SecretKeyFactory skf = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);

return skf.generateSecret(spec).getEncoded();

}

/**

* Converts a string of hexadecimal characters into a byte array.

*

* @param   hex         the hex string

* @return              the hex string decoded into a byte array

*/

private static byte[] fromHex(String hex)

{

byte[] binary = new byte[hex.length() / 2];

for(int i = 0; i < binary.length; i++)

{

binary[i] = (byte)Integer.parseInt(hex.substring(2*i, 2*i+2), 16);

}

return binary;

}

/**

* Converts a byte array into a hexadecimal string.

*

* @param   array       the byte array to convert

* @return              a length*2 character string encoding the byte array

*/

private static String toHex(byte[] array)

{

BigInteger bi = new BigInteger(1, array);

String hex = bi.toString(16);

int paddingLength = (array.length * 2) - hex.length();

if(paddingLength > 0)

return String.format("%0" + paddingLength + "d", 0) + hex;

else

return hex;

}

/**

* Tests the basic functionality of the PasswordHash class

*

* @param   args        ignored

*/

public static void main(String[] args)

{

try

{

// Print out 10 hashes

for(int i = 0; i < 10; i++)

System.out.println(PasswordHash.createHash("p\r\nassw0Rd!"));

// Test password validation

boolean failure = false;

System.out.println("Running tests...");

for(int i = 0; i < 100; i++)

{

String password = ""+i;

String hash = createHash(password);

String secondHash = createHash(password);

if(hash.equals(secondHash)) {

System.out.println("FAILURE: TWO HASHES ARE EQUAL!");

failure = true;

}

String wrongPassword = ""+(i+1);

if(validatePassword(wrongPassword, hash)) {

System.out.println("FAILURE: WRONG PASSWORD ACCEPTED!");

failure = true;

}

if(!validatePassword(password, hash)) {

System.out.println("FAILURE: GOOD PASSWORD NOT ACCEPTED!");

failure = true;

}

}

if(failure)

System.out.println("TESTS FAILED!");

else

System.out.println("TESTS PASSED!");

}

catch(Exception ex)

{

System.out.println("ERROR: " + ex);

}

}

}

ASP.NET (C#)密码hash代码

/*

* Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm).

* Copyright (c) 2013, Taylor Hornby

* All rights reserved.

*

* Redistribution and use in source and binary forms, with or without

* modification, are permitted provided that the following conditions are met:

*

* 1. Redistributions of source code must retain the above copyright notice,

* this list of conditions and the following disclaimer.

*

* 2. Redistributions in binary form must reproduce the above copyright notice,

* this list of conditions and the following disclaimer in the documentation

* and/or other materials provided with the distribution.

*

* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

* POSSIBILITY OF SUCH DAMAGE.

*/

using System;

using System.Text;

using System.Security.Cryptography;

namespace PasswordHash

{

/// <summary>

/// Salted password hashing with PBKDF2-SHA1.

/// Author: havoc AT defuse.ca

/// www: http://crackstation.net/hashing-security.htm

/// Compatibility: .NET 3.0 and later.

/// </summary>

public class PasswordHash

{

// The following constants may be changed without breaking existing hashes.

public const int SALT_BYTE_SIZE = 24;

public const int HASH_BYTE_SIZE = 24;

public const int PBKDF2_ITERATIONS = 1000;

public const int ITERATION_INDEX = 0;

public const int SALT_INDEX = 1;

public const int PBKDF2_INDEX = 2;

/// <summary>

/// Creates a salted PBKDF2 hash of the password.

/// </summary>

/// <param name="password">The password to hash.</param>

/// <returns>The hash of the password.</returns>

public static string CreateHash(string password)

{

// Generate a random salt

RNGCryptoServiceProvider csprng = new RNGCryptoServiceProvider();

byte[] salt = new byte[SALT_BYTE_SIZE];

csprng.GetBytes(salt);

// Hash the password and encode the parameters

byte[] hash = PBKDF2(password, salt, PBKDF2_ITERATIONS, HASH_BYTE_SIZE);

return PBKDF2_ITERATIONS + ":" +

Convert.ToBase64String(salt) + ":" +

Convert.ToBase64String(hash);

}

/// <summary>

/// Validates a password given a hash of the correct one.

/// </summary>

/// <param name="password">The password to check.</param>

/// <param name="correctHash">A hash of the correct password.</param>

/// <returns>True if the password is correct. False otherwise.</returns>

public static bool ValidatePassword(string password, string correctHash)

{

// Extract the parameters from the hash

char[] delimiter = { ':' };

string[] split = correctHash.Split(delimiter);

int iterations = Int32.Parse(split[ITERATION_INDEX]);

byte[] salt = Convert.FromBase64String(split[SALT_INDEX]);

byte[] hash = Convert.FromBase64String(split[PBKDF2_INDEX]);

byte[] testHash = PBKDF2(password, salt, iterations, hash.Length);

return SlowEquals(hash, testHash);

}

/// <summary>

/// Compares two byte arrays in length-constant time. This comparison

/// method is used so that password hashes cannot be extracted from

/// on-line systems using a timing attack and then attacked off-line.

/// </summary>

/// <param name="a">The first byte array.</param>

/// <param name="b">The second byte array.</param>

/// <returns>True if both byte arrays are equal. False otherwise.</returns>

private static bool SlowEquals(byte[] a, byte[] b)

{

uint diff = (uint)a.Length ^ (uint)b.Length;

for (int i = 0; i < a.Length && i < b.Length; i++)

diff |= (uint)(a[i] ^ b[i]);

return diff == 0;

}

/// <summary>

/// Computes the PBKDF2-SHA1 hash of a password.

/// </summary>

/// <param name="password">The password to hash.</param>

/// <param name="salt">The salt.</param>

/// <param name="iterations">The PBKDF2 iteration count.</param>

/// <param name="outputBytes">The length of the hash to generate, in bytes.</param>

/// <returns>A hash of the password.</returns>

private static byte[] PBKDF2(string password, byte[] salt, int iterations, int outputBytes)

{

Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, salt);

pbkdf2.IterationCount = iterations;

return pbkdf2.GetBytes(outputBytes);

}

}

}

Ruby (on Rails) 密码hash代码

# Password Hashing With PBKDF2 (http://crackstation.net/hashing-security.htm).

# Copyright (c) 2013, Taylor Hornby

# All rights reserved.

#

# Redistribution and use in source and binary forms, with or without

# modification, are permitted provided that the following conditions are met:

#

# 1. Redistributions of source code must retain the above copyright notice,

# this list of conditions and the following disclaimer.

#

# 2. Redistributions in binary form must reproduce the above copyright notice,

# this list of conditions and the following disclaimer in the documentation

# and/or other materials provided with the distribution.

#

# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE

# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE

# POSSIBILITY OF SUCH DAMAGE.

require 'securerandom'

require 'openssl'

require 'base64'

# Salted password hashing with PBKDF2-SHA1.

# Authors: @RedragonX (dicesoft.net), havoc AT defuse.ca

# www: http://crackstation.net/hashing-security.htm

module PasswordHash

# The following constants can be changed without breaking existing hashes.

PBKDF2_ITERATIONS = 1000

SALT_BYTE_SIZE = 24

HASH_BYTE_SIZE = 24

HASH_SECTIONS = 4

SECTION_DELIMITER = ':'

ITERATIONS_INDEX = 1

SALT_INDEX = 2

HASH_INDEX = 3

# Returns a salted PBKDF2 hash of the password.

def self.createHash( password )

salt = SecureRandom.base64( SALT_BYTE_SIZE )

pbkdf2 = OpenSSL::PKCS5::pbkdf2_hmac_sha1(

password,

salt,

PBKDF2_ITERATIONS,

HASH_BYTE_SIZE

)

return ["sha1", PBKDF2_ITERATIONS, salt, Base64.encode64( pbkdf2 )].join( SECTION_DELIMITER )

end

# Checks if a password is correct given a hash of the correct one.

# correctHash must be a hash string generated with createHash.

def self.validatePassword( password, correctHash )

params = correctHash.split( SECTION_DELIMITER )

return false if params.length != HASH_SECTIONS

pbkdf2 = Base64.decode64( params[HASH_INDEX] )

testHash = OpenSSL::PKCS5::pbkdf2_hmac_sha1(

password,

params[SALT_INDEX],

params[ITERATIONS_INDEX].to_i,

pbkdf2.length

)

return pbkdf2 == testHash

end

# Run tests to ensure the module is functioning properly.

# Returns true if all tests succeed, false if not.

def self.runSelfTests

puts "Sample hashes:"

3.times { puts createHash("password") }

puts "\nRunning self tests..."

@@allPass = true

correctPassword = 'aaaaaaaaaa'

wrongPassword = 'aaaaaaaaab'

hash = createHash(correctPassword)

assert( validatePassword( correctPassword, hash ) == true, "correct password" )

assert( validatePassword( wrongPassword, hash ) == false, "wrong password" )

h1 = hash.split( SECTION_DELIMITER )

h2 = createHash( correctPassword ).split( SECTION_DELIMITER )

assert( h1[HASH_INDEX] != h2[HASH_INDEX], "different hashes" )

assert( h1[SALT_INDEX] != h2[SALT_INDEX], "different salt" )

if @@allPass

puts "*** ALL TESTS PASS ***"

else

puts "*** FAILURES ***"

end

return @@allPass

end

def self.assert( truth, msg )

if truth

puts "PASS [#{msg}]"

else

puts "FAIL [#{msg}]"

@@allPass = false

end

end

end

PasswordHash.runSelfTests

原文出自:http://www.freebuf.com/articles/web/28527.html或http://netsecurity.51cto.com/art/201403/432090.htm

如何安全的存储用户密码?(中)代码篇相关推荐

  1. 程序员必备基础:如何安全传输存储用户密码?

    前言 我们开发网站或者APP的时候,首先要解决的问题,就是「如何安全传输和存储用户的密码」.一些大公司的用户数据库泄露事件也时有发生,带来非常大的负面影响.因此,如何安全传输存储用户密码,是每位程序员 ...

  2. mysql登录密码特殊字符_MySQL用户密码中的特殊字符叹号(!)的妙用

    MySQL用户密码中的特殊字符叹号(!)的妙用 使用叹号(!)禁止用户终端进入的一个方法. 复制代码 代码如下: mysql> grant all privileges on wubx.* to ...

  3. 如何安全的存储用户密码

    文章目录 1.明文存储(极不推荐) 2.使用MD5或其它算法哈希后存储(较不推荐) 3.加盐后哈希存储(较推荐) 4.使用BCrypt算法加密后存储(非常推荐) 5.Spring Boot中使用jbc ...

  4. 获取令牌密码_如何真正存储用户密码和api令牌(即密码)

    获取令牌密码 A cliché in posts detailing password storage schemes is to finish by telling the syadmins and ...

  5. golang pbkdf2加密存储用户密码

    概述 PBKDF2(Password-Based Key Derivation Function) 是一个用来导出密钥的函数,常用于生成加密的密码.原理是通过 password 和 salt 进行 h ...

  6. 如何安全存储用户密码/数据库安全存储密码的方式

    总的来讲,目前公认比较安全的存储密码方式是PBKDF2, BCrypt 或 SCrypt 算法产生的密码. 历史上密码加密存储经历了如下几个阶段: 1. 单向hash(MD5) 做单向的hash加密, ...

  7. 存储用户密码应该使用什么加密算法?比较合适

    概述 编程开发中,像用户登录注册这种功能很常见,那么对于用户密码处理,我们该选择什么样的加密算法呢?在这种场景下,算法需要满足下面两个条件: 算法需不可逆,这样才能有效防止密码泄露. 算法需相对慢,可 ...

  8. java修改用户密码全代码

    java实现修改密码 前段时间一直在写东西,本来不想把用户这块的东西放出来,想了想,还是弄一个修改密码功能实现一下,首先介绍一下我这个项目,他有session等验证,所以搞起来得和正式的项目一样得实现 ...

  9. druid加密mysql_Druid 数据库用户密码加密 代码实现

    标签: druid-1.0.16.jar 阿里巴巴的开源数据连接池 jar包 明文密码+私钥(privateKey)加密=加密密码 加密密码+公钥(publicKey)解密=明文密码 程序代码如下: ...

最新文章

  1. matlab绘制横向柱状图
  2. 简便的chrome插件安装
  3. Typora——恢复未保存文件解决方案
  4. 搞多媒体开发?吴威麒:先拉个书单看看
  5. 编写高质量代码:改善Java程序的151个建议(第3章:类、对象及方法___建议36~40)
  6. SQL char字段类型排序
  7. leetcode 4
  8. zxing qr区域判断_如何在Java中使用Zxing和JFreeSVG创建QR Code SVG?
  9. 多态的两种用法 形参与返回值 java
  10. 四川大学计算机组成原理实验报告_20092014年计算机组成原理考研真题与解析
  11. oracle排序去重,Oracle中去重复+排序
  12. 神通数据库知识点整理
  13. 用iscsi和DHCP搭建一个windows无盘系统站【笔记】
  14. excel 分组统计
  15. 东北大学计算机考研专业842包括什么,东北大学2019年计算机考研842计算机专业基础考试大纲...
  16. [转]如何实现按键精灵的简单路点行走
  17. CdS纳米微粒/聚苯乙烯核壳微球/聚苯乙烯包裹CdSe MSQDs荧光量子点微球的内容
  18. 好书分享--生命3.0 人工智能时代人类的进化与重生
  19. WIN7系统 提示缺少msvcr120.DLL,msvcr110.DLL的 请戳这里。
  20. CLion2020调整字体大小

热门文章

  1. Java初学者推荐学习书籍free下载
  2. Java中获取 List中最后一个元素
  3. MyBatisPlus的ActiveRecord(活动记录)简介以及怎样使用
  4. SpringBoot 报错Field XXX required a bean of type XXX that could not be found.
  5. go 指针变量和普通变量的转化_7.8 C++指针变量的引用
  6. 进大厂必须掌握的50个微服务面试问题!
  7. 喜茶获美团点评旗下基金4亿元投资!它离行业独角兽还差多远?
  8. python爬虫入门(六) Scrapy框架之原理介绍
  9. Intellij IDEA 的使用
  10. JDBC基础教程:tutorialspoint-jdbc