zoukankan      html  css  js  c++  java
  • 字符串加密案例

      今天介绍一种MD5的加密方法,代码中写了比较详细的注释,直接上例子了。

    前台代码
    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Encrypt.aspx.cs" Inherits="Encrypt" %>

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <title></title>
    </head>
    <body>
    <form id="form1" runat="server">
    <div>
    原始密码:
    &nbsp;&nbsp;&nbsp; <asp:TextBox ID="txtOriginal" runat="server" Width="260px"></asp:TextBox>
    <asp:Button ID="btnEncrypt" runat="server" Text="加密"
    onclick
    ="btnEncrypt_Click" />
    <asp:TextBox ID="txtPwd1" runat="server" Width="260px"></asp:TextBox>
    <br />
    加密后密码:
    <asp:TextBox ID="txtPwd2" runat="server" Width="260px"></asp:TextBox>
    <asp:Button ID="btnCompare" runat="server" Text="比较"
    onclick
    ="btnCompare_Click" />
    <asp:TextBox ID="txtNow" runat="server" Width="260px"></asp:TextBox>
    </div>
    </form>
    </body>
    </html>
    后台代码
    using System;
    using System.Security.Cryptography;
    using System.Text;


    public partial class Encrypt : System.Web.UI.Page
    {
    private const int saltLength = 4;//偶数,随机值的位数,4位的“盐”
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    /// <summary>
    /// 生成要存储在数据库中的秘密
    /// </summary>
    /// <param name="password">用户输入的秘密</param>
    /// <returns>生成的秘密字符串</returns>
    public static string CreateDbPassword(string password)
    {
    string strSaltValue = CreateSaltValue();//创建随即的4位“盐”
    return CreateSaltedPassword(strSaltValue, CreateHashPassword(password));//先返回16进制哈希密码,再返回加了“盐”后的总共36位16进制哈希密码
    }

    /// <summary>
    /// 比较秘密是否相同
    /// </summary>
    /// <param name="storedPassword">存在数据库中的秘密</param>
    /// <param name="password">用户提供的秘密</param>
    /// <returns>是否相同</returns>
    public static bool ComparePasswords(string storedPassword, string password)
    {
    string hashPassword = CreateHashPassword(password);//根据输入的密码创建16进制哈希密码
    if (storedPassword == null || storedPassword.Length != 32 + saltLength) return false;//如果加密后的密码为空或者不够36位,则返回
    string saltValue = storedPassword.Substring(32, saltLength);//截取已加密密码的后四位,即:“盐”
    string saltPassword = CreateSaltedPassword(saltValue, hashPassword);//创建加“盐”的16进制哈希密码
    return (saltPassword == storedPassword);
    }

    /// <summary>
    /// 根据提供的秘码生成对应的Hash值
    /// </summary>
    /// <param name="password">秘码</param>
    /// <returns>Hash值字符串</returns>
    private static string CreateHashPassword(string password)
    {
    System.Security.Cryptography.MD5 md5
    = new MD5CryptoServiceProvider();//创建MD5抽象类, 哈希算法的所有实现均从中继承
    byte[] hexHashPassword = md5.ComputeHash(Encoding.ASCII.GetBytes(password));//先转换密码为ASCII字节数组,然后计算指定字节数组的哈希值,哈希值是一段数据唯一且极其紧凑的数值表示形式
    string strHashPaword = HexToStr(hexHashPassword);//将哈希值转换为16进制
    return strHashPaword;
    }

    /// <summary>
    /// 把字节数组转换成对应的字符串
    /// </summary>
    /// <param name="buf"></param>
    /// <returns></returns>
    private static string HexToStr(byte[] buf)
    {
    string aa = "";
    string sTemp = "";
    for (int i = 0; i < buf.Length; i++)
    {
    sTemp
    = System.Convert.ToString(buf[i], 16);//将字节数组转换为16进制
    aa += sTemp.PadLeft(2, '0');//转换后的16进制为两位,若不够则左边补零
    }
    return aa;
    }

    /// <summary>
    /// 生成随机值 字符串
    /// </summary>
    /// <returns></returns>
    private static string CreateSaltValue()
    {
    RNGCryptoServiceProvider rng
    = new RNGCryptoServiceProvider();//使用加密服务提供程序 (CSP) 提供的实现来实现加密随机数生成器 (RNG)。此类不能继承。
    byte[] saltValue = new byte[saltLength / 2];//创建字节数组
    rng.GetBytes(saltValue);//生成随即数,赋值给字节数组
    string strSaltValue = HexToStr(saltValue);//转换为16进制
    return strSaltValue;
    }

    /// <summary>
    ///生成带有随机值的密码
    /// </summary>
    /// <param name="saltValue">随机值</param>
    /// <param name="hashPassword">秘密的Hash值</param>
    /// <returns>带有随机值的密码字符串</returns>
    private static string CreateSaltedPassword(string saltValue, string hashPassword)
    {
    System.Security.Cryptography.MD5 md5
    = new MD5CryptoServiceProvider();//创建MD5抽象类, 哈希算法的所有实现均从中继承
    string tempPassword = hashPassword + saltValue;//经过加密后的密码再加上“盐”
    byte[] hexSaltPassword = md5.ComputeHash(Encoding.ASCII.GetBytes(tempPassword));//将加了盐密码先转换密码为ASCII字节数组,然后计算指定字节数组的哈希值,哈希值是一段数据唯一且极其紧凑的数值表示形式
    string strSaltPassword = HexToStr(hexSaltPassword);//将加了盐的哈希密码转换为16进制
    string dbPassword = strSaltPassword + saltValue;//再将密码再加上“盐”,此时密码长度为36位,至此加密完成
    return dbPassword;
    }

    /// <summary>
    /// 加密按钮
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnEncrypt_Click(object sender, EventArgs e)
    {
    string pwd = txtOriginal.Text.Trim(); //这里的字符串没有经过太多处理,只是测试
    txtPwd1.Text = CreateDbPassword(pwd);//调用加密函数
    }

    /// <summary>
    /// 比较按钮
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnCompare_Click(object sender, EventArgs e)
    {
    bool isTrue;
    isTrue
    = ComparePasswords(txtPwd2.Text.Trim(), txtOriginal.Text.Trim());//判断加密后的密码,与原始密码加密后是否相等
    txtNow.Text = isTrue ? "相等" : "不相等";
    }
    }

    运行结果:

    如有不足之处,请大家补充;若有其他的好的办法,也希望大家踊跃讨论!

  • 相关阅读:
    spring-boot4
    spring-boot3代码
    spring-boot3
    spring-boot2代码
    spring-boot2
    Java Socket编程
    eclipse项目中.classpath文件详解
    spring-boot1
    ASCII 在线转换器
    如何在Android开发中让你的代码更有效率
  • 原文地址:https://www.cnblogs.com/Johnny_Z/p/1779101.html
Copyright © 2011-2022 走看看