VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 封装与访问修饰符——用C#开发用户隐私信息保护

第一部分:C#基础入门
实例4:封装与访问修饰符——用户隐私信息保护
实例介绍
在软件系统中,用户隐私信息(如身份证号、密码、手机号)是核心敏感数据,封装和访问修饰符是保护这些数vb.net教程C#教程python教程SQL教程access 2010教程据的关键手段。封装通过“信息隐藏”原则,将敏感字段设为私有,仅暴露安全的访问接口;访问修饰符则控制字段/方法的可见范围,防止非法修改。本实例通过实现一个安全的用户类,带你掌握如何用封装保护隐私,理解不同访问修饰符的作用,写出安全、合规的代码。
需求分析
1.定义用户类:包含公开信息(姓名、年龄)和隐私信息(身份证号、密码);
2.隐私保护:
1.身份证号:禁止直接访问,仅允许脱敏显示(如110101****1234);
2.密码:加密存储(模拟MD5加密),禁止明文访问,修改需验证旧密码;
3.访问控制:
1.公开信息(姓名、年龄)可读写;
2.隐私信息仅通过指定方法访问/修改(如GetMaskedIdCard()、ChangePassword());
4.数据完整性:身份证号初始化时验证格式(模拟18位校验),密码长度不低于6位;
5.操作日志:记录隐私信息的修改操作(如密码修改时间)。
代码实现
csharp

	using System;
	using System.Security.Cryptography;
	using System.Text;
	
	namespace PrivacyProtectionDemo
	{
	// 用户类:封装隐私信息,控制访问权限
	public class User
	{
	// 1. 私有字段:隐私信息(仅类内部可访问)
	private string _idCard; // 身份证号(私有,禁止外部直接访问)
	private string _encryptedPwd; // 加密后的密码(私有)
	private DateTime _pwdLastChangedTime; // 密码最后修改时间(私有)
	
	// 2. 公共属性:公开信息(外部可读写/只读)
	public string Name { get; set; } // 姓名:可读写
	public int Age { get; set; } // 年龄:可读写
	public string Email { get; } // 邮箱:只读(构造函数初始化)
	
	// 3. 构造函数:初始化用户信息,验证敏感数据格式
	public User(string name, int age, string email, string idCard, string initialPwd)
	{
	Name = name;
	Age = age;
	Email = email; // 只读属性,仅构造函数可赋值
	
	// 验证身份证格式(模拟18位校验)
	if (!IsValidIdCard(idCard))
	throw new ArgumentException("身份证号格式无效(需18位)");
	_idCard = idCard;
	
	// 验证初始密码长度,加密存储
	if (initialPwd.Length < 6)
	throw new ArgumentException("密码长度需≥6位");
	_encryptedPwd = EncryptPassword(initialPwd);
	_pwdLastChangedTime = DateTime.Now;
	}
	
	// 4. 公共方法:安全访问隐私信息(脱敏/加密)
	/// <summary>
	/// 获取脱敏身份证号(前6后4,中间隐藏)
	/// </summary>
	public string GetMaskedIdCard()
	{
	if (string.IsNullOrEmpty(_idCard)) return string.Empty;
	return $"{_idCard.Substring(0,6)}******{_idCard.Substring(14)}";
	}
	
	/// <summary>
	/// 修改密码(需验证旧密码)
	/// </summary>
	public bool ChangePassword(string oldPwd, string newPwd)
	{
	// 验证旧密码是否正确
	if (EncryptPassword(oldPwd) != _encryptedPwd)
	return false;
	// 验证新密码长度
	if (newPwd.Length <6)
	return false;
	// 更新加密密码和修改时间
	_encryptedPwd = EncryptPassword(newPwd);
	_pwdLastChangedTime = DateTime.Now;
	return true;
	}
	
	/// <summary>
	/// 获取密码最后修改时间(只读)
	/// </summary>
	public DateTime GetPwdLastChangedTime() => _pwdLastChangedTime;
	
	// 5. 私有方法:内部工具(外部不可见)
	/// <summary>
	/// 模拟密码加密(实际项目用SHA256+盐)
	/// </summary>
	private string EncryptPassword(string pwd)
	{
	using (var md5 = MD5.Create())
	{
	byte[] bytes = Encoding.UTF8.GetBytes(pwd);
	byte[] hash = md5.ComputeHash(bytes);
	return BitConverter.ToString(hash).Replace("-", "").ToLower();
	}
	}
	
	/// <summary>
	/// 模拟身份证格式验证(仅检查长度)
	/// </summary>
	private bool IsValidIdCard(string idCard)
	{
	return !string.IsNullOrEmpty(idCard) && idCard.Length ==18;
	}
	}
	
	// 主程序:测试用户隐私保护功能
	class Program
	{
	static void Main(string[] args)
	{
	try
	{
	// 创建用户(初始化时验证身份证和密码)
	var user = new User(
	name: "张三",
	age: 30,
	email: "zhangsan@example.com",
	idCard: "110101199405201234",
	initialPwd: "Zhang123!"
	);
	
	// 访问公开信息
	Console.WriteLine($"姓名:{user.Name}");
	Console.WriteLine($"年龄:{user.Age}");
	Console.WriteLine($"邮箱:{user.Email}"); // 只读属性,无法修改
	
	// 访问隐私信息(脱敏显示)
	Console.WriteLine($"脱敏身份证:{user.GetMaskedIdCard()}");
	Console.WriteLine($"密码最后修改时间:{user.GetPwdLastChangedTime():yyyy-MM-dd HH:mm}");
	
	// 尝试修改密码(正确旧密码)
	bool pwdChanged = user.ChangePassword(oldPwd: "Zhang123!", newPwd: "NewPass456!");
	Console.WriteLine($"密码修改成功?{pwdChanged}");
	Console.WriteLine($"新密码修改时间:{user.GetPwdLastChangedTime():yyyy-MM-dd HH:mm}");
	
	// 尝试直接访问私有字段(编译错误!)
	// Console.WriteLine(user._idCard); // 错误:_idCard是private
	// user._encryptedPwd = "123"; // 错误:_encryptedPwd是private
	}
	catch (Exception ex)
	{
	Console.WriteLine($"错误:{ex.Message}");
	}
	}
	}
	}

逐行讲解

  1. 访问修饰符的使用
    private string _idCard:身份证号设为私有,仅User类内部可访问。外部代码无法直接读取/修改,避免隐私泄露;
    public string Name { get; set; }:姓名设为公共可读写,属于公开信息,允许外部修改;
    public string Email { get; }:邮箱设为公共只读,仅构造函数可初始化,外部无法修改,保证邮箱唯一性;
    private string EncryptPassword(string pwd):加密方法设为私有,外部无需知道加密细节,仅内部使用。
  2. 隐私信息保护逻辑
    身份证脱敏:GetMaskedIdCard()方法返回脱敏后的身份证号,隐藏中间敏感部分,既满足显示需求又保护隐私;
    密码加密存储:EncryptPassword()方法用MD5模拟加密(实际项目需加盐+SHA256),禁止明文存储,即使数据泄露也无法直接获取密码;
    密码修改验证:ChangePassword()方法需验证旧密码,防止非法修改,同时记录修改时间,便于审计。
  3. 数据完整性验证
    构造函数验证:初始化用户时,验证身份证长度(模拟18位)和密码长度(≥6位),确保数据合法;
    只读属性:Email设为只读,避免外部随意修改,保证用户身份唯一。
    基础知识拓展
  4. C#访问修饰符全解析
    | 修饰符 | 作用范围 | 适用场景 |
    | ---- | ---- | ---- |
    | private | 仅当前类内部 | 隐私字段/内部工具方法(如加密、验证) |
    | protected | 当前类+子类 | 需被子类继承的方法/字段(如User子类可访问的基础信息) |
    | internal | 同一程序集(项目) | 程序集内部共享的类/方法(如工具类) |
    | protected internal | 同一程序集+子类(跨程序集) | 需被子类继承且程序集内部共享的成员 |
    | public | 全局可见 | 公开接口/公共类(如User类的公开方法) |

核心原则:最小权限原则——给成员分配尽可能小的访问范围,仅暴露必要的接口。
2. 封装的三大原则
信息隐藏:隐藏内部实现细节(如加密算法、验证逻辑),仅暴露抽象接口;
数据完整性:通过方法/属性控制数据修改,防止非法值(如密码长度不足);
模块化:将相关数据和方法封装到类中,提高代码可维护性。
3. 隐私保护进阶技巧
加盐加密:在密码前/后添加随机字符串(盐)再加密,防止彩虹表攻击;
敏感数据序列化忽略:用[JsonIgnore](Newtonsoft.Json)或[IgnoreDataMember]标记隐私字段,避免序列化泄露;
只读属性:用public string Prop { get; }实现只读字段,仅构造函数可赋值。
扩展思考
1.加强身份证验证:实现真实的18位身份证校验(如校验码计算),而非仅检查长度;
2.多因素认证:修改密码时添加短信验证码,进一步提升安全性;
3.敏感数据日志脱敏:记录操作日志时,自动脱敏身份证、手机号等敏感信息;
4.子类继承:创建AdminUser子类继承User,用protected修饰符让子类访问部分隐私信息(如简化密码修改流程);
5.数据过期策略:添加密码过期时间,强制用户定期修改密码。
总结
封装是保护用户隐私的核心手段,而访问修饰符是实现封装的“工具”。通过合理使用private隐藏敏感数据,public暴露必要接口,protected支持子类继承,我们能写出既安全又易维护的代码。记住:隐私保护不是可选功能,而是软件的基本责任——每一个敏感字段都应该被妥善封装,每一次数据访问都应该被严格控制。

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49405.html


相关教程