MD5算法原理简要介绍并采用C#应用在桌面应用系统的用户登录与注册中

MD5算法原理简要介绍并采用C#应用在桌面应用系统的用户登录与注册中

    接上文,本文简要介绍一下MD5加密算法的原理,并采用C#实现MD5算法的加密与解密过程,将这一实现过程应用在我自己开发的桌面办公应用-工资管理系统  中的用户注册与登录模块,有需要进一步了解的博友可以在下面留言或者可以加我QQ:1974544863(记得备注:"桌面办公应用"),我可以与您一同交流其中实现的原理。

    MD5,是message-digest(即“信息-摘要”)的简称,是一种加密算法,具有不可逆性,简要地说:“MD5是以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值”。具体的原理可以参考这篇csdn博客 :MD5算法原理

    我虽然喜欢算法,但在开发软件过程中,考虑到软件的开发周期,就没深入研究MD5的具体原理,而只是从中抽取了核心的关键点:明文,密钥key,密钥。 从这点入手,去网上搜索几篇采用C#实现MD5算法的代码,之后导入自己的项目工程中,一步一步加breakpoint,单步debug,最后实现了自己想要的效果!

    下面介绍采用C#实现MD5算法的代码,正如上面提到的,核心关键点有明文,密钥key,密钥这三点,所以代码也就主要有三个功能方法MD5Encrypt(string pToEncrypt, string sKey),GenerateKey(),MD5Decrypt(string pToDecrypt, string sKey)。下面是代码(在代码有部分进行了注释,就不再进行详解,若想知晓每一句代码的原理,请你参考上面提到的那篇参考博客MD5算法原理)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;

namespace SMS.cmmMessage
{
    class MD5EncryptAndDecrypt
    {
        // 创建Key
        public string GenerateKey()
        {
            DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
            //将产生的tempKey采用ASCII进行编码
            return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
        }
        ///MD5加密
        public string MD5Encrypt(string pToEncrypt, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            ret.ToString();
            return ret.ToString();
        }

        ///MD5解密
        public string MD5Decrypt(string pToDecrypt, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
            for (int x = 0; x < pToDecrypt.Length / 2; x++)
            {
                int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
                inputByteArray[x] = (byte)i;
            }

            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            StringBuilder ret = new StringBuilder();

            return System.Text.Encoding.Default.GetString(ms.ToArray());
        }
    }
}
    值得说明的是,我这个实现的是:产生的密文是16位的,当然你也可以改改成为32位的,或者网上搜搜!

    算法的研究如果只是停留在研究的层次,或者研究只是为了书写一大堆学术论文的话,我个人觉得没多大意思。像我一直比较崇拜的MSRA,就真的是将研究的成果应用到诸多产品中,我觉得那才有意思!(可惜自己能力有限啊,不然真的想去MSRA跟那堆牛人共事!)。

    因为自己最近正好在自己开发一套企业使用的工资管理系统,其中涉及到用户注册于登录模块,对于投身应用软件开发的人而言,势必需要经常与“安全”打交道,因为,正如上文提到的“有应用系统就会有用户,有用户就会涉及到登录注册,涉及到登录注册则势必与密码挂钩,而有密码则会涉及到安全,想到了安全则自然需要想到加密”。正是这样的想法驱动,我将C#实现的MD5加密解密算法应用了我开发的桌面办公应用系统-工资管理系统中。

    实现的过程,核心的地方有两点:一点是三个核心关键:明文,密钥key,密钥;另一点是在key上再拼接自定义的一段字符串!

    下面以我自主开发的工资管理系统为例,下面是注册界面与代码:我们只关心用户的登录密码,其他的用户信息的处理以及含义在后续博文中会陆续介绍!


    在窗体初始化方法之后,加上下面一段定义MD5加解密类的对象

        //加密解密工具
        MD5EncryptAndDecrypt md5 = new MD5EncryptAndDecrypt();
    在保存时候,即注册用户时候,保存用户的登录密码那一段代码是这样的:     

            //加密密码与密钥
            String loginKeyTemp=md5.GenerateKey();//产生临时密钥
            String loginPasswordEncrypt=md5.MD5Encrypt(empLoginPassword,loginKeyTemp);//产生密文
            String loginKeyEncrypt=loginKeyTemp+CommonMessage.lastKeyStr;//产生真正存储的密钥
    之后,数据库中的用户表中关于登录密码的需要有两个字段:loginPassword,loginKey,其中loginPassword存储的是用户明文密码加密后的密文,loginKey存储的是真正的密钥(当然了,真正有用的是那个临时的密钥:需要截断自定义的那段拼接的字符串)。

    所以在登录时候,代码是这样的

        //登录事件
        private void buttonLogin_Click(object sender, EventArgs e)
        {
            try
            {
                string userName = textBoxUserName.Text.Trim();
                string userPwd = textBoxPwd.Text.Trim();
                if (userName == "" || userPwd == "")
                {
                    MessageBox.Show("用户名或密码不能为空!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                else
                {
                    String[] loginFieldNames = new String[]{
                            "loginPassword","loginKey"
                        };
                    String tempSQL = " from tb_employee where loginName='" + userName + "'";
                    String strSql = cmmUtils.organizeSqlStatementWithFields(loginFieldNames, tempSQL);
                    Console.WriteLine(strSql);
                    String[] dataResults = operate.GetDatasFromSelectedTable(strSql.ToString(), loginFieldNames);
                    //不存在该用户名
                    if (dataResults==null)
                    {
                        MessageBox.Show("该用户名不存在!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        String loginPasswordEncrypt = dataResults[0];//用户名对应的登录密码 
                        String loginKeyTemp = dataResults[1];//用户名对应的加了拼接字符串的登录密钥
                        String loginKeyReal = loginKeyTemp.Substring(0, loginKeyTemp.IndexOf(CommonMessage.lastKeyStr));//截断后才是真正的密钥
                        String loginPasswordDecrypt = md5.MD5Decrypt(loginPasswordEncrypt, loginKeyReal);//解密密文
                        if (!userPwd.Equals(loginPasswordDecrypt))
                        {
                            MessageBox.Show("用户密码错误!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        else
                        {
                            //MessageBox.Show("登陆成功!", "友情提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.Hide();
<span style="white-space:pre">			</span>    //密码匹配正确即成功登录:记录当前的用户名与用户密码
                            CommonMessage.userName = userName;
                            CommonMessage.userPassword = userPwd;

                            String[] selFieldNames = new String[]{//主要用于获取当前用户的用户权限
                                "powerName"
                        };
                            String tempPowerSQL = " from tb_employee,tb_powerType where tb_employee.powerId=tb_powerType.powerId and tb_employee.loginName='" + userName + "'";
                            String strPowerSql = cmmUtils.organizeSqlStatementWithFields(selFieldNames, tempPowerSQL);
                            String[] dataPowerResults = operate.GetDatasFromSelectedTable(strPowerSql.ToString(), selFieldNames);
                            CommonMessage.userPower = dataPowerResults[0];
                            frmMain fMain = new frmMain();
                            fMain.ShowDialog();
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message + "\n请与管理员联系!", "错误信息", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            
        }

     以上即为采用C#实现MD5加密算法的代码并将其应用在我的工资管理系统中的用户注册登录模块中!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修罗debug

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值