MFC哈希实现 目标:知道初始密码的人,才能改密码及登录。只知道登录密码只能登录。避免密码直接写在代码里或本地,通过软件评估报告。----安全行业基础5

一种简单的登录设计,密码保存在本地。(直接MD5不安全,别人可以更换本地的密码,得再加一层算法就相对安全一点)

当然也可以用加密机或专门存密码的系统来实现,就过于复杂。

目标:1、为了避免密码直接写在代码里或本地,通过软件评估报告。2、知道初始密码的人,才能改密码及登录。只知道登录密码只能登录。

密码

1.初始密码暂时先用这个ASDEedsa@123321,转为MD5写在应用里:5329B69272930C2F9E9F743B11215AFD。修改的密码用MD5计算后保存到注册表 https://www.sojson.com/md5/ 
2.首次登录或点重置密码先输入初始密码,再修改密码,再进入主界面。再次登录就可以使用新密码。
3. 密码规则:数字,字母,大小写,及符号组成的不少于6位的密码。
4. 如果工具在idle 状态下15分钟以上没动,再用工具时,需要用户重新Login。

界面

MFC哈希实现 目标:知道初始密码的人,才能改密码及登录。只知道登录密码只能登录。避免密码直接写在代码里或本地,通过软件评估报告。----安全行业基础5_第1张图片
条件1实现:https://blog.csdn.net/chenhao0568/article/details/134654801?spm=1001.2014.3001.5501
条件2实现:逻辑了。
条件3实现:https://blog.csdn.net/chenhao0568/article/details/134654768?spm=1001.2014.3001.5501
条件4实现:https://blog.csdn.net/chenhao0568/article/details/134654747?spm=1001.2014.3001.5501

// CPasswordDlg.cpp: 实现文件
//

#include "stdafx.h"
#include "afxdialogex.h"
#include "CPasswordDlg.h"
#include "Resource.h"

static int status = 0;//0输入初始密码 1输入新密码  2正常登录(注册表有密码)
static CString registerPassword = "";
#include "md5.h"
#define MD5_INIT_PASSWORD "5329B69272930C2F9E9F743B11215AFD"
#define KEY_PATH  _T("Software\\MyApplication5329B69272930C2F9E9F743B11215AFD")
#define VALUE_NAME _T("PW_MD5")

void WriteRegistryValue(const CString& keyPath, const CString& valueName, const CString& value) {
	CRegKey key;
	if (key.Create(HKEY_CURRENT_USER, keyPath) == ERROR_SUCCESS) {
		key.SetStringValue(valueName, value);
		key.Close();
	}
}
CString ReadRegistryValue(const CString& keyPath, const CString& valueName) {
	CString value;
	CRegKey key;
	if (key.Open(HKEY_CURRENT_USER, keyPath, KEY_READ) == ERROR_SUCCESS) {
		TCHAR buffer[256];
		ULONG len = 256;
		if (key.QueryStringValue(valueName, buffer, &len) == ERROR_SUCCESS) {
			value = buffer;
		}
		key.Close();
	}
	return value;
}

bool IsPasswordValid(const CString& password) {
	if (password.GetLength() < 6) {
		return false;  // 密码长度不足6位
	}

	bool hasDigit = false;
	bool hasLower = false;
	bool hasUpper = false;
	bool hasSymbol = false;

	for (int i = 0; i < password.GetLength(); ++i) {
		TCHAR ch = password[i];

		if (_istdigit(ch)) {
			hasDigit = true;
		}
		else if (_istlower(ch)) {
			hasLower = true;
		}
		else if (_istupper(ch)) {
			hasUpper = true;
		}
		else if (_istpunct(ch)) {
			hasSymbol = true;
		}
	}

	return hasDigit && hasLower && hasUpper && hasSymbol;
}

// CPasswordDlg 对话框
IMPLEMENT_DYNAMIC(CPasswordDlg, CDialogEx)

CPasswordDlg::CPasswordDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG1, pParent)
{
}

CPasswordDlg::~CPasswordDlg()
{
}

void CPasswordDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}


BEGIN_MESSAGE_MAP(CPasswordDlg, CDialogEx)
	ON_BN_CLICKED(IDOK, &CPasswordDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDR_GERTEC_ADBKEY11, &CPasswordDlg::OnBnClickedGertecAdbkey11)
END_MESSAGE_MAP()


// CPasswordDlg 消息处理程序
void CPasswordDlg::OnBnClickedOk()
{
	CString password="";
	GetDlgItem(IDC_EDIT1)->GetWindowText(password);

	unsigned char out[MD5_MAX_LEN] = { 0 };
	md5((const unsigned char*)password.GetBuffer(), strlen(password), out);
	char hex_md5[MD5_MAX_LEN] = { 0 };
	byteToHexStr(out, 16, (char*)hex_md5);

	if (status == 0)
	{
		if (memcmp(MD5_INIT_PASSWORD, hex_md5, strlen(MD5_INIT_PASSWORD)) == 0)
		{
			status = 1;
			this->SetWindowText("Please enter a new password");
		}
		else
		{
			AfxMessageBox("Password error");
		}
		GetDlgItem(IDC_EDIT1)->SetWindowText("");
		GetDlgItem(IDC_EDIT1)->SetFocus();
		return;
	}
	else if (status == 1)
	{
		//check and write
		if (IsPasswordValid(password))
		{
			memcpy(registerPassword.GetBuffer(strlen(MD5_INIT_PASSWORD)), hex_md5, strlen(MD5_INIT_PASSWORD)); registerPassword.ReleaseBuffer();
			WriteRegistryValue(KEY_PATH, VALUE_NAME, registerPassword);
			AfxMessageBox("Password set successfully");
			CDialogEx::OnOK();
		}
		else
		{
			AfxMessageBox("Password error,the password must be at least 6 characters long and include numbers, letters, both upper and lower case, and symbols.");
			GetDlgItem(IDC_EDIT1)->SetWindowText("");
			GetDlgItem(IDC_EDIT1)->SetFocus();
		}

	}
	else
	{
		if (memcmp(registerPassword, hex_md5, strlen(MD5_INIT_PASSWORD)) == 0)
		{
			CDialogEx::OnOK();
		}
		else
		{
			AfxMessageBox("Password error");
			GetDlgItem(IDC_EDIT1)->SetWindowText("");
			GetDlgItem(IDC_EDIT1)->SetFocus();
		}
	}

}


BOOL CPasswordDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//WriteRegistryValue(KEY_PATH, VALUE_NAME, MD5_INIT_PASSWORD);
	//WriteRegistryValue(KEY_PATH, VALUE_NAME, "");
	registerPassword = ReadRegistryValue(KEY_PATH, VALUE_NAME); registerPassword.ReleaseBuffer();
	if (registerPassword.GetLength() > 0)
	{
		status = 2;
		this->SetWindowText("Please input password");
	}
	else
	{
		status = 0;
		this->SetWindowTextA("Please enter the initial password");
	}
	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}


void CPasswordDlg::OnBnClickedGertecAdbkey11()
{
	status = 0;
	this->SetWindowTextA("Please enter the initial password");
	GetDlgItem(IDC_EDIT1)->SetWindowText("");
	GetDlgItem(IDC_EDIT1)->SetFocus();
}

再加一层算法,比如写前按一组随机的数字相加,读后再反操作。

哈希算法(Hash Algorithm)是一种从任意长度的消息中创建小的固定长度“哈希值”(或“哈希代码”)的算法。哈希算法在计算机科学中有着广泛的应用,例如数据检索、安全加密和数据完整性验证。以下是一些主要的特点和应用场景:

特点

  1. 确定性:相同的输入总是产生相同的哈希值。
  2. 高效计算:能够快速计算出任意输入数据的哈希值。
  3. 抗碰撞性:找到两个不同的输入但产生相同哈希值的情况非常困难。
  4. 原像抗性:从哈希值很难反推出原始输入数据。

应用场景

  1. 数据存储:数据库和其他数据结构(如哈希表)使用哈希算法快速定位和检索数据。
  2. 安全加密:在密码学中,哈希函数用于加密数据,确保信息传输的安全。
  3. 数据完整性验证:用于检查文件或数据传输过程中是否被篡改。
  4. 数字签名:用于验证文件或消息的真实性。

常见哈希算法

  • MD5:一种广泛使用的哈希算法,但现在被认为是不安全的。
  • SHA系列(如SHA-256):提供更高安全性的哈希算法,广泛用于加密货币和网络安全。
  • CRC32:主要用于检测数据传输或存储过程中的错误。

哈希算法的选择取决于具体的应用需求,如对速度、安全性或抗碰撞性的不同要求。在安全相关的应用中,选择一个经过时间检验且被广泛认可的安全哈希算法尤为重要。

你可能感兴趣的:(c++复习,密码,保存在本地,评估,安全,hash,哈希)