Last active
November 21, 2020 07:24
-
-
Save VergilGao/141aa238623111b7c4d74371d7e08f54 to your computer and use it in GitHub Desktop.
一个帮助类,实现将密码加盐加密保存,简单修改即可用于生产环境。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Security.Cryptography; | |
using System.Text; | |
namespace Demo | |
{ | |
/// <summary> | |
/// 密码加密帮助类 | |
/// 使用特定算法(SHA256或SHA512和盐值对密码进行加密) | |
/// 将密码以{hash,salt,algorithm}的形式储存以避免明文储存机密带来的安全风险 | |
/// 此算法能保护在数据泄露事件发生后密码原文不被窃取,同时能一定程度上应对彩虹表的攻击 | |
/// 加密后的密码将永远不可读,只能用于验证 | |
/// </summary> | |
public static class SecretEncryptor | |
{ | |
/// <summary> | |
/// 默认的加密算法,当前为 SHA256 | |
/// </summary> | |
public const string DEFAULT_ALGORITHM = SHA256; | |
/// <summary> | |
/// SHA245加密算法 | |
/// </summary> | |
public const string SHA256 = "SHA256"; | |
/// <summary> | |
/// SHA512加密算法 | |
/// </summary> | |
public const string SHA512 = "SHA512"; | |
/// <summary> | |
/// 加密密码 | |
/// </summary> | |
/// <param name="rawSecret">原始密码</param> | |
/// <param name="salt">盐值,请在加密新的密码时使用新的盐值</param> | |
/// <param name="algorithm">加密算法</param> | |
/// <returns>加密后的字符串</returns> | |
public static byte[] Encode(string rawSecret, string salt, string algorithm) | |
{ | |
return algorithm switch | |
{ | |
SHA256 => Sha256(Mix(rawSecret, salt)), | |
SHA512 => Sha512(Mix(rawSecret, salt)), | |
_ => throw new NotImplementedException($"未知的加密算法:{algorithm}"), | |
}; | |
} | |
private static byte[] Mix(string rawSecret, string salt) => Encoding.UTF8.GetBytes($"{rawSecret}{{{salt}}}"); | |
private static byte[] Sha256(byte[] content) => new SHA256Managed().ComputeHash(content); | |
private static byte[] Sha512(byte[] content) => new SHA512Managed().ComputeHash(content); | |
/// <summary> | |
/// 校验密码 | |
/// </summary> | |
/// <param name="storedHash">存储的密码hash</param> | |
/// <param name="computedHash">计算出来的密码hash</param> | |
/// <returns>密码是否匹配</returns> | |
public static bool Verify(byte[] storedHash, byte[] computedHash) | |
{ | |
var diff = storedHash.Length ^ computedHash.Length; | |
for (int i = 0; i < storedHash.Length && i < computedHash.Length; i++) | |
{ | |
diff |= storedHash[i] ^ computedHash[i]; | |
} | |
return diff == 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment