Chemmy's Blog

chengming0916@outlook.com

国标ID是在国标GB/T28181中使用的ID,在一个空间下保持唯一,命名规则应遵从GB/T 28181-2016《公共安全视频监控联网系统信息传输、交换、控制技术要求》。

国标ID由中心编码(8位)、行业编码(2位)、类型编码(3位)、网络标识(1位)和序号(6位)共20位十进制数字字符构成,其中:

  • 中心编码指用户或设备所归属的监控中心编码,按照监控中心所在地的行政区划代码确定,当不是基层单位时空余为0,行政区划分代码采用GB/T 2260-2007规定的行政区划代码表示。
  • 行业编码是指用户或设备所归属的行业,规则说明见“行业编码规则”。
  • 类型编码指定了设备或用户的具体类型。
  • 详细说明如下“详细规则说明”。

详细编码规则

gb2

行业编码规范

参考

1、安装nuget包MSBuildTasks

2、编辑项目的csproj文件,找到被注释掉的target的beforebuild,去掉注释,添加如下代码。代码如下。

1
2
3
4
5
6
7
8
9
<Target Name="BeforeBuild">
<Version VersionFile="Propertiesversion.txt" Major="1" Minor="0" BuildType="Automatic" StartDate="09/01/2017" RevisionType="BuildIncrement">
<Output TaskParameter="Major" PropertyName="Major" />
<Output TaskParameter="Minor" PropertyName="Minor" />
<Output TaskParameter="Build" PropertyName="Build" />
<Output TaskParameter="Revision" PropertyName="Revision" />
</Version>
<AssemblyInfo CodeLanguage="CS" OutputFile="Properties\FileVersionInfo.cs" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
</Target>     

3、编译项目一次就会在项目文件夹下生成 Propertiesversion.txt

4、在AssemblyInfo.cs文件中包含了AssemblyVersion和AssemblyFileVersion,这里把AssemblyFileVersion单独放到了FileVersionInfo.cs中,编译时会自动生成FileVersionInfo.cs文件,其内容为AssemblyFileVersion,把该文件包含到项目中即可。这里并没有让程序自动生成AssemblyVersion。

这种方式生成版本号会在vs编译时更新版本号。

1.1 InstallShield的安装

  InstallShield 2010下载地址  点击这里 ,安装方法网上有很多就不赘述了。

1.2 绿色版安装包的前期准备

如果你需要打包的绿色版软件比较小(1G以内),或者文件结构比较简单,请忽视此段,由于我所要打包的软件体积比较大,最重要的是文件结构比较复杂,内部文件夹嵌套较多,且例如图片,xml等小文件较多,这样 InstallShield软件在打包导入的时候会非常慢,我尝试导入了10多个小时也没有结束就放弃了,所以在这里我建议对文件结构复杂的软件进行压缩处理,压缩方式请转

RAR打包为自解压exe文件教程,得到一个单独的 EXE文件(自解压格式)后进行接下来的操作。

2.1创建新的 Windows Installer | InstallScript MSI Projcet

这种类型的工程既有打包向导,又可以写一点脚本实现自定义操作,比较适合使用。

2.2 打包向导主界面

这里是InstallShield提供的向导主界面,我们是通过点击选择下方的动作条进行操作。

2.3应用程序信息

公司信息,应用程序名称等等,这里没什么好说的。

2.4 安装要求

这里要说一下,大家可能会把这里理解为是安装依赖,但是这里与其说是依赖不如说是安装的前提或要求,这里勾选的环境 会在你双击setup后立即开始检测,并且在不满足条件时,只会对你做相应的提醒(如:请安装Adobe reader6!)后直接结束安装并退出,并没有引导用户安装的选项。明显与我们想将缺少的依赖环境集成引导加以安装的需求不相符,但是考虑到有些人会有这样的需求,也在接下来简单讲一下。

2.4.1 系统安装要求的勾选

对于InstallShield软件已经列出的选项直接勾选就可以,不再赘述。

2.4.2 自定义系统安装要求

对于InstallShield没有列出的我们可以通过左侧 创建一个自定义软件条件 来自行添加,如下图,你可以选择不同的满足条件(如 注册表某一项的值为XXX或 系统的某一路径下存在某一文件等等),这里的选项可以满足自定义几乎所有的安装要求。

2.5安装体系结构

在这里可以新建多个Feature,每一个Feature代表一类安装软件,具体以例子说明,见下面第二张图。

这中类型的图片大家一定很熟悉,这是大多数软件点击自定义安装后出现的界面, 以下图为例,My sql数据库,MuseMail这两个选项就对应两个Feature,也就是上一幅图中的defaultFeature和New_Feature2这两个,然后属于musemail类里面的多个软件就被添加到MuseMail的Feature下,对于MuseMail->初始化工具,则要创建初始化工具的Feature,以此类推。

2.6应用程序文件

在此界面为每一个Feature添加文件。若有多个文件可选择添加文件夹。 这些Feature将是用户自定义安装时选择的对象。

2.7 应用程序快捷方式

在这里添加在上一部分添加的文件中,每一个在你安装后的系统可能用到的文件的快捷方式,建议只添加必须的。右侧可以选择快捷方式出现的位置。

2.8应用程序注册表

在这里可以选择应用程序想要写入注册表的信息,右键添加即可,比较简单。

2.9安装本地化

这一部分用来选择安装语言

2.10构建安装

选择生成安装包。讲到这里比较简单的安装包已经可以打包好了,已经可以点击生成了,选择对应的生成类型即可。

选择安装设计器界面—>应用程序数据—>可再分发,在这里可以选择系统所需的环境,并且在环境不满足的情况下弹出下载安装的提醒。

InstallShield软件已经集成了部分依赖环境,可以勾选添加,并且可以在部署前下载,这样可以添加到安装包中,免除用户在安装过程中下载过程。但是InstallShield中不包含的怎么办呢,接下来来讲自定义依赖环境。

InstallShield提供的依赖环境是以 .prq文件的方式提供的,目录是    X:\..\InstallShield\2010\SetupPrerequisites,在这里有很多.prq文件,自定义不存在的依赖环境就是在网上下载.prq文件,或自己创建

常用prq文件地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="UTF-8"?>
<SetupPrereq>
<!-- 安装条件:检测注册表 -->
<conditions>
<condition Type="2"
Comparison="2"
Path="HKEY_LOCAL_MACHINE\SOFTWARE\test"
FileName="test"
ReturnValue="1"/>
</conditions>

<!-- 操作系统支持 -->
<operatingsystemconditions>
<!-- Windows XP SP2+ -->
<operatingsystemcondition MajorVersion="5" MinorVersion="1"
PlatformId="2" CSDVersion=""
Bits="1" ProductType="1"
ServicePackMajorMin="2"/>
<!-- Windows Server 2003 -->
<operatingsystemcondition MajorVersion="5" MinorVersion="2"
PlatformId="2" ProductType="2|3"/>
<!-- Windows Server 2003 x64 -->
<operatingsystemcondition MajorVersion="5" MinorVersion="2"
PlatformId="2" Bits="2" ProductType="1"/>
<!-- Windows Vista -->
<operatingsystemcondition MajorVersion="6" MinorVersion="0"
PlatformId="2"/>
<!-- Windows Server 2008 -->
<operatingsystemcondition MajorVersion="6" MinorVersion="0"
PlatformId="2" ProductType="2|3"/>
<!-- Windows 7 / Server 2008 R2 -->
<operatingsystemcondition MajorVersion="6" MinorVersion="0"
PlatformId="2" ProductType="1"/>
</operatingsystemconditions>

<!-- 文件下载配置 -->
<files>
<file LocalFile="<ISProductFolder>\SetupPrerequisites\test\test 3.5\test3.5.exe"
URL="http://download.test.com/download/test3.5.exe"
CheckSum="D481CDA2625D9DD2731A00F482484D86"
FileSize="0,242743296"/>
</files>

<!-- 执行命令配置 -->
<execute file="Helper.exe"
cmdline="/p dotnetfx35.exe /l 1033 /v &quot;/q /norestart&quot;"
cmdlinesilent="/p dotnetfx35.exe /l 1033 /v &quot;/q /norestart&quot;"
returncodetoreboot="1641,3010"
requiresmsiengine="1"/>

<!-- 依赖包属性 -->
<properties Id="{074EE22F-2485-4FED-83D1-AAC36C3D9ED0}"
Description="This prerequisite installs the .NET Framework 3.5 Service Pack 1 full package."
AltPrqURL="http://saturn.installshield.com/is/prerequisites/microsoft .net framework 3.5 sp1.prq"/>

<!-- 重启行为 -->
<behavior Reboot="2"/>
</SetupPrereq>

关键配置说明

配置项 说明
<conditions> 安装前检测条件,如注册表键值
<operatingsystemconditions> 支持的操作系统版本
<files> 需要下载的依赖文件
<execute> 安装执行命令及参数
<properties> 依赖包标识和描述
<behavior> 安装后的重启行为

使用步骤

  1. .prq 文件保存至 InstallShield\SetupPrerequisites 目录
  2. 重启 InstallShield 软件
  3. 应用程序数据 → 可再分发 中勾选该依赖

一、 核心概念与架构

1.1 什么是 Ansible?

Ansible 是一款基于 Python 开发的开源自动化运维工具,它集成了众多同类工具(如 Puppet, Chef, Fabric)的优点,能够实现批量系统配置、批量程序部署、批量运行命令等功能。

核心特性

  • 无代理架构:基于 SSH 协议与远程主机通信,无需在目标主机上安装任何客户端(Agent)
  • 模块化设计:功能由模块实现,Ansible 本身提供执行框架。
  • 简单易用:使用 YAML 语言编写 Playbook,学习曲线平缓。
  • 功能强大:拥有大量内置模块,覆盖日常运维的绝大部分场景。
  • 被红帽收购:已成为自动化运维领域的事实标准之一。
1.2 Ansible 架构

组件 说明
Ansible Core 核心引擎,负责解析 Playbook、调用模块、管理任务流。
Inventory 主机清单,定义 Ansible 需要管理的主机及其分组信息。
Playbooks “剧本”,YAML 格式文件,用于定义复杂、可重复的自动化任务序列。
Core Modules 核心模块,Ansible 自带的模块库,是执行具体操作(如文件管理、包管理)的单元。
Custom Modules 自定义模块,用户可用 Python 等语言编写,扩展 Ansible 功能。
Connection Plugins 连接插件,默认使用 SSH,也支持 WinRM、Docker 等其他连接方式。
1.3 任务执行模式
  • Ad-Hoc 模式(临时命令):使用 ansible 命令行工具执行单条命令或单个模块,适合快速、一次性的任务。
    1
    2
    ansible all -m ping
    ansible web_servers -m shell -a 'uptime'
  • Playbook 模式(剧本):使用 ansible-playbook 执行 YAML 格式的 Playbook 文件,用于定义复杂的、可版本控制的自动化流程,是 Ansible 的主要使用方式。

二、 安装与基础配置

2.1 安装 Ansible

方式一:YUM 安装(推荐用于 RHEL/CentOS)

1
2
3
4
# 1. 安装 EPEL 仓库
yum install epel-release -y
# 2. 安装 Ansible
yum install ansible -y

方式二:PIP 安装(适用于任何支持 Python 的系统)

1
2
3
4
# 1. 安装 pip
yum install python-pip -y
# 2. 使用 pip 安装 Ansible
pip install ansible

安装后目录结构(YUM安装)

  • 配置文件目录/etc/ansible/
  • 执行文件目录/usr/bin/
  • 模块库目录/usr/lib/pythonX.X/site-packages/ansible/
2.2 配置文件 (ansible.cfg)

Ansible 按以下顺序查找配置文件(后者覆盖前者):

  1. 环境变量 ANSIBLE_CONFIG 指定的文件。
  2. 当前目录下的 ./ansible.cfg
  3. 用户家目录下的 ~/.ansible.cfg
  4. 系统默认的 /etc/ansible/ansible.cfg

常见配置项/etc/ansible/ansible.cfg):

1
2
3
4
5
6
7
[defaults]
inventory = /etc/ansible/hosts # 主机清单文件路径
library = /usr/share/ansible # 模块库路径
remote_user = root # 默认远程连接用户
host_key_checking = False # 首次连接不检查主机密钥(方便测试)
timeout = 10 # SSH 连接超时时间(秒)
log_path = /var/log/ansible.log # 启用日志记录(默认不记录)
2.3 主机清单 (inventory)

主机清单文件(默认为 /etc/ansible/hosts)定义了被管理的主机,支持分组和变量定义。

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 1. 直接定义主机(IP 或主机名)
192.168.1.101
web01.example.com

# 2. 定义主机组
[web_servers]
192.168.1.101
192.168.1.102

[db_servers]
db01.example.com
db02.example.com

# 3. 嵌套组和变量
[datacenter:children] # 定义一个父组,包含其他组
web_servers
db_servers

[web_servers:vars] # 为 web_servers 组设置变量
ansible_user = deploy
http_port = 8080
2.4 配置 SSH 免密登录

为了执行流畅,建议配置控制节点到所有被管节点的 SSH 密钥认证。

1
2
3
4
5
6
7
# 1. 在控制节点生成密钥(如果尚未生成)
ssh-keygen -t rsa

# 2. 将公钥分发到所有被管节点
ssh-copy-id root@192.168.1.101
ssh-copy-id root@192.168.1.102
# 或使用脚本批量分发

三、 命令行工具与 Ad-Hoc 模式

3.1 Ansible 核心命令集
命令 用途
ansible 执行 Ad-Hoc 命令的核心工具。
ansible-doc 查看模块文档和帮助信息。
ansible-playbook 执行 Playbook 剧本。
ansible-vault 加密/解密敏感数据文件。
ansible-galaxy 从 Galaxy 社区下载/管理 Roles。
ansible-console 交互式命令行界面。
ansible-pull 拉取模式(较少使用)。
3.2 ansible 命令详解

基本语法ansible <主机模式> -m <模块名> -a "<模块参数>" [选项]

常用选项

选项 说明
-i INVENTORY 指定自定义的主机清单文件。
-m MODULE 指定要执行的模块(默认为 command)。
-a ARGS 传递给模块的参数。
-u REMOTE_USER 指定远程连接用户。
-k 提示输入 SSH 密码。
-K 提示输入 sudo 密码。
-b, --become 提权执行(通常用 sudo)。
--become-user USER 提权到指定用户。
-f FORKS 并行执行的任务数(默认5)。
-v, -vv, -vvv 输出更详细的执行信息。

示例

1
2
3
4
5
6
7
8
# 测试所有主机的连通性
ansible all -m ping

# 在所有 web 服务器上执行 shell 命令
ansible web_servers -m shell -a "uptime"

# 使用 sudo 安装软件包
ansible db_servers -m yum -a "name=mysql-server state=present" -b -K
3.3 ansible-doc 命令

用于查询模块的详细用法。

1
2
3
4
5
6
# 列出所有可用模块
ansible-doc -l

# 查看指定模块的详细帮助和示例
ansible-doc -s yum # 查看概要
ansible-doc yum # 查看完整文档(包含示例)
3.4 Ansible 执行流程(Ad-Hoc)
  1. 加载配置(ansible.cfg)。
  2. 解析主机清单(inventory),确定目标主机。
  3. 加载指定模块。
  4. 生成临时 Python 脚本,并通过 SFTP/SCP 传输到目标主机的 ~/.ansible/tmp/ 目录。
  5. 在目标主机上执行该脚本。
  6. 返回执行结果,并删除临时脚本。

四、 常用核心模块详解

4.1 连接测试模块:ping

用于测试与目标主机的连通性及 Ansible 环境是否正常。

1
ansible all -m ping

返回 pong 即表示成功。

4.2 命令执行模块:command & shell
  • command 模块:执行简单的命令,不支持管道 |、重定向 >、环境变量 $HOME 等 Shell 特性。是默认模块。
    1
    ansible web -m command -a "ls -l /var/www"
  • shell 模块:通过 /bin/sh 执行命令,支持所有 Shell 特性
    1
    ansible web -m shell -a "ps aux | grep nginx"

常用参数

  • chdir:在执行命令前,先切换到此目录。
  • creates:如果此路径的文件存在,则不执行命令。
  • removes:如果此路径的文件不存在,则不执行命令。
4.3 文件管理模块:copy

将本地文件复制到远程主机。

1
ansible web -m copy -a "src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf owner=root group=root mode=0644"

常用参数

  • src:本地源文件路径(可以是目录)。
  • dest:远程目标路径(必须是绝对路径)。
  • owner/group/mode:设置文件属主、属组和权限。
  • backup=yes:覆盖前备份原文件。
  • content:直接用字符串内容创建文件,替代 src
4.4 文件属性模块:file

管理文件、目录、链接的属性。

1
2
3
4
5
6
7
8
9
10
11
# 创建目录
ansible web -m file -a "path=/app/data state=directory mode=0755"

# 创建软链接
ansible web -m file -a "src=/etc/nginx.conf dest=/app/nginx.conf state=link"

# 删除文件或目录
ansible web -m file -a "path=/tmp/old.log state=absent"

# 修改属主和权限
ansible web -m file -a "path=/app/www owner=www group=www mode=755"

state 参数

  • directory:创建目录。
  • touch:创建空文件或更新时间戳。
  • link / hard:创建软/硬链接。
  • absent:删除。
4.5 包管理模块:yum (RHEL/CentOS)

管理软件包。

1
2
3
4
5
6
7
8
9
10
11
# 安装最新版
ansible web -m yum -a "name=nginx state=latest"

# 安装指定版本
ansible web -m yum -a "name=nginx-1.20.1 state=present"

# 卸载软件包
ansible web -m yum -a "name=nginx state=absent"

# 更新所有包
ansible web -m yum -a "name=* state=latest"

state 参数

  • presentinstalled:确保安装。
  • latest:确保安装最新版。
  • absentremoved:确保卸载。
4.6 服务管理模块:service

管理系统服务。

1
2
3
4
5
6
7
8
# 启动服务并设置开机自启
ansible web -m service -a "name=nginx state=started enabled=yes"

# 重启服务
ansible web -m service -a "name=nginx state=restarted"

# 停止服务
ansible web -m service -a "name=nginx state=stopped"
4.7 用户管理模块:user

管理系统用户。

1
2
3
4
5
6
7
8
# 创建用户
ansible db -m user -a "name=mysql uid=1001 group=mysql shell=/sbin/nologin"

# 删除用户并移除家目录
ansible db -m user -a "name=olduser state=absent remove=yes"

# 修改用户密码(需要已加密的密码字符串)
ansible db -m user -a 'name=test password="{{ \'mypassword\' | password_hash(\'sha512\') }}"'
4.8 计划任务模块:cron

管理 Cron 任务。

1
2
3
4
5
# 添加计划任务
ansible web -m cron -a 'name="Daily Backup" minute="0" hour="2" job="/opt/backup.sh"'

# 删除计划任务
ansible web -m cron -a 'name="Daily Backup" state=absent'
4.9 信息收集模块:setup

收集目标主机的详细信息(Facts),这些信息可以作为变量在 Playbook 中使用。

1
2
3
4
5
6
7
8
# 收集所有信息
ansible web -m setup

# 过滤收集特定信息(如内存)
ansible web -m setup -a 'filter="ansible_memory_mb"'

# 将收集的信息保存到本地文件
ansible web -m setup --tree /tmp/facts/
4.10 其他实用模块
  • **fetch**:从远程主机拉取文件到控制节点。
  • **script**:在远程主机上执行控制节点本地的脚本。
  • **group**:管理系统用户组。
  • **get_url**:从 HTTP/FTP 下载文件。
  • **unarchive**:解压文件。

五、 总结与后续

本文涵盖了 Ansible 的基础知识、安装配置、Ad-Hoc 命令以及最常用的核心模块。掌握这些内容是使用 Ansible 进行自动化运维的第一步。

核心要点回顾

  1. 无代理、基于 SSH 是 Ansible 的基石。
  2. Inventory 定义了“对谁操作”。
  3. 模块 定义了“执行什么操作”。
  4. Ad-Hoc 用于快速执行单次任务。
  5. Playbook 是用于复杂、可重复任务的强大工具(将在后续文章中详述)。

下一步学习建议

  1. 深入 Playbook:学习 YAML 语法、任务结构、变量、循环、条件判断等。
  2. 理解 Roles:用于组织和复用 Playbook 的最佳实践。
  3. 使用 Ansible Vault:加密管理密码等敏感数据。
  4. 探索 Ansible Galaxy:从社区获取现成的 Roles。
  5. 学习高级特性:如动态 Inventory、回调插件、自定义模块等。

通过结合 Ad-Hoc 命令的灵活性和 Playbook 的强大编排能力,Ansible 能够帮助您高效、可靠地管理从几台到上万台服务器的运维工作。

一、FastDFS介绍

FastDFS 开源地址:https://github.com/happyfish100

参考:分布式文件系统FastDFS设计原理

参考:FastDFS分布式文件系统

个人封装的 FastDFS Java API:https://github.com/bojiangzhou/lyyzoo-fastdfs-java

1.1 简介

FastDFS 是一个开源的高性能分布式文件系统(DFS)。它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size < 500MB)为载体的在线服务。

FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。

角色 说明
Tracker Server 跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server 和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。
Storage Server 存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。
Client 客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。

FastDFS架构图

1.2 FastDFS的存储策略

为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。

在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。

1.3 FastDFS的上传过程

FastDFS 向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。

Storage Server 会定期的向 Tracker Server 发送自己的存储信息。当 Tracker Server Cluster 中的 Tracker Server 不止一个时,各个 Tracker 之间的关系是对等的,所以客户端上传时可以选择任意一个 Tracker。

当 Tracker 收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的 group,当选定了 group 后就要决定给客户端分配 group 中的哪一个 storage server。当分配好 storage server 后,客户端向 storage 发送写文件请求,storage 将会为文件分配一个数据存储目录。然后为文件分配一个 fileid,最后根据以上的信息生成文件名存储文件。

FastDFS上传过程

1.4 FastDFS的文件同步

写文件时,客户端将文件写至 group 内一个 storage server 即认为写文件成功,storage server 写完文件后,会由后台线程将文件同步至同 group 内其他的 storage server。

每个 storage 写文件后,同时会写一份 binlog,binlog 里不包含文件数据,只包含文件名等元信息,这份 binlog 用于后台同步,storage 会记录向 group 内其他 storage 同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有 server 的时钟保持同步。

storage 的同步进度会作为元数据的一部分汇报到 tracker 上,tracker 在选择读 storage 的时候会以同步进度作为参考。

1.5 FastDFS的文件下载

客户端 upload file 成功后,会拿到一个 storage 生成的文件名,接下来客户端根据这个文件名即可访问到该文件。

FastDFS下载过程

跟 upload file 一样,在 download file 时客户端可以选择任意 tracker server。tracker 发送 download 请求给某个 tracker,必须带上文件名信息,tracker 从文件名中解析出文件的 group、大小、创建时间等信息,然后为该请求选择一个 storage 用来服务读请求。


二、安装FastDFS环境

2.1 前言

操作环境:CentOS 7 X64,以下操作都是单机环境。

把所有安装包下载到 /softpackages/ 下,解压到当前目录。

先做一件事,修改 hosts,将文件服务器的 ip 与域名映射(单机 Tracker Server 环境),因为后面很多配置里面都需要去配置服务器地址,ip 变了,就只需要修改 hosts 即可:

1
2
3
# vim /etc/hosts
# 增加如下一行,这是我的IP
192.168.51.128 file.ljzsg.com

如果要本机访问虚拟机,在 C:\Windows\System32\drivers\etc\hosts 中同样增加一行。

2.2 下载安装 libfastcommon

libfastcommon 是从 FastDFS 和 FastDHT 中提取出来的公共 C 函数库,基础环境,安装即可。

① 下载 libfastcommon

1
# wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz

② 解压

1
2
# tar -zxvf V1.0.7.tar.gz
# cd libfastcommon-1.0.7

③ 编译、安装

1
2
# ./make.sh
# ./make.sh install

④ libfastcommon.so 安装到了 /usr/lib64/libfastcommon.so,但是 FastDFS 主程序设置的 lib 目录是 /usr/local/lib,所以需要创建软链接

1
2
3
4
# ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
# ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
# ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
# ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so

2.3 下载安装 FastDFS

① 下载 FastDFS

1
# wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz

② 解压

1
2
# tar -zxvf V5.05.tar.gz
# cd fastdfs-5.05

③ 编译、安装

1
2
# ./make.sh
# ./make.sh install

④ 默认安装方式安装后的相应文件与目录

  • 服务脚本:

    • /etc/init.d/fdfs_storaged
    • /etc/init.d/fdfs_tracker
  • 配置文件(这三个是作者给的样例配置文件):

    • /etc/fdfs/client.conf.sample
    • /etc/fdfs/storage.conf.sample
    • /etc/fdfs/tracker.conf.sample
  • 命令工具在 /usr/bin/ 目录下:

    • fdfs_appender_test
    • fdfs_appender_test1
    • fdfs_append_file
    • fdfs_crc32
    • fdfs_delete_file
    • fdfs_download_file
    • fdfs_file_info
    • fdfs_monitor
    • fdfs_storaged
    • fdfs_test
    • fdfs_test1
    • fdfs_trackerd
    • fdfs_upload_appender
    • fdfs_upload_file
    • stop.sh
    • restart.sh

⑤ FastDFS 服务脚本设置的 bin 目录是 /usr/local/bin,但实际命令安装在 /usr/bin/ 下

两种方式:

  • 方式一:修改 FastDFS 服务脚本中相应的命令路径,也就是把 /etc/init.d/fdfs_storaged/etc/init.d/fdfs_tracker 两个脚本中的 /usr/local/bin 修改成 /usr/bin
1
2
3
4
5
6
7
# vim fdfs_trackerd
# 使用查找替换命令进行统一修改
:%s+/usr/local/bin+/usr/bin

# vim fdfs_storaged
# 使用查找替换命令进行统一修改
:%s+/usr/local/bin+/usr/bin

修改服务脚本

  • 方式二:建立 /usr/bin 到 /usr/local/bin 的软链接(我是用这种方式)
1
2
3
4
# ln -s /usr/bin/fdfs_trackerd   /usr/local/bin
# ln -s /usr/bin/fdfs_storaged /usr/local/bin
# ln -s /usr/bin/stop.sh /usr/local/bin
# ln -s /usr/bin/restart.sh /usr/local/bin

2.4 配置 FastDFS 跟踪器 (Tracker)

配置文件详细说明参考:FastDFS 配置文件详解

① 进入 /etc/fdfs,复制 FastDFS 跟踪器样例配置文件 tracker.conf.sample,并重命名为 tracker.conf

1
2
3
# cd /etc/fdfs
# cp tracker.conf.sample tracker.conf
# vim tracker.conf

② 编辑 tracker.conf

1
2
3
4
5
6
7
8
9
10
11
# 配置文件是否不生效,false 为生效
disabled=false

# 提供服务的端口
port=22122

# Tracker 数据和日志目录地址(根目录必须存在,子目录会自动创建)
base_path=/ljzsg/fastdfs/tracker

# HTTP 服务端口
http.server_port=80

③ 创建 tracker 基础数据目录

1
# mkdir -p /ljzsg/fastdfs/tracker

④ 防火墙中打开跟踪端口(默认的 22122)

1
2
3
4
5
6
# vim /etc/sysconfig/iptables
# 添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT

# 重启防火墙:
# service iptables restart

⑤ 启动 Tracker

初次成功启动,会在 /ljzsg/fastdfs/tracker/(配置的 base_path)下创建 data、logs 两个目录。

1
2
3
4
5
# 可以用这种方式启动
# /etc/init.d/fdfs_trackerd start

# 也可以用这种方式启动,前提是上面创建了软链接,后面都用这种方式
# service fdfs_trackerd start

查看 FastDFS Tracker 是否已成功启动,22122 端口正在被监听,则算是 Tracker 服务安装成功。

1
# netstat -unltp|grep fdfs

查看Tracker状态

关闭 Tracker 命令:

1
# service fdfs_trackerd stop

⑥ 设置 Tracker 开机启动

1
# chkconfig fdfs_trackerd on

或者:

1
2
3
# vim /etc/rc.d/rc.local
# 加入配置:
/etc/init.d/fdfs_trackerd start

⑦ tracker server 目录及文件结构

Tracker 服务启动成功后,会在 base_path 下创建 data、logs 两个目录。目录结构如下:

1
2
3
4
5
6
${base_path}
|__data
| |__storage_groups.dat:存储分组信息
| |__storage_servers.dat:存储服务器列表
|__logs
| |__trackerd.log: tracker server 日志文件

2.5 配置 FastDFS 存储 (Storage)

① 进入 /etc/fdfs 目录,复制 FastDFS 存储器样例配置文件 storage.conf.sample,并重命名为 storage.conf

1
2
3
# cd /etc/fdfs
# cp storage.conf.sample storage.conf
# vim storage.conf

② 编辑 storage.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 配置文件是否不生效,false 为生效
disabled=false

# 指定此 storage server 所在 组(卷)
group_name=group1

# storage server 服务端口
port=23000

# 心跳间隔时间,单位为秒 (这里是指主动向 tracker server 发送心跳)
heart_beat_interval=30

# Storage 数据和日志目录地址(根目录必须存在,子目录会自动生成)
base_path=/ljzsg/fastdfs/storage

# 存放文件时 storage server 支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。
store_path_count=1

# 逐一配置 store_path_count 个路径,索引号基于 0。
# 如果不配置 store_path0,那它就和 base_path 对应的路径一样。
store_path0=/ljzsg/fastdfs/file

# FastDFS 存储文件时,采用了两级目录。这里配置存放文件的目录个数。
# 如果本参数只为 N(如: 256),那么 storage server 在初次运行时,会在 store_path 下自动创建 N * N 个存放文件的子目录。
subdir_count_per_path=256

# tracker_server 的列表 ,会主动连接 tracker_server
# 有多个 tracker server 时,每个 tracker server 写一行
tracker_server=file.ljzsg.com:22122

# 允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定。
sync_start_time=00:00
sync_end_time=23:59

# 访问端口
http.server_port=80

③ 创建 Storage 基础数据目录

1
2
3
4
# mkdir -p /ljzsg/fastdfs/storage

# 这是配置的store_path0路径
# mkdir -p /ljzsg/fastdfs/file

④ 防火墙中打开存储器端口(默认的 23000)

1
2
3
4
5
6
7
# vim /etc/sysconfig/iptables

# 添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 23000 -j ACCEPT

# 重启防火墙:
# service iptables restart

配置Storage防火墙

⑤ 启动 Storage

启动 Storage 前确保 Tracker 是启动的。初次启动成功,会在 /ljzsg/fastdfs/storage 目录下创建 data、logs 两个目录。

1
2
3
4
5
# 可以用这种方式启动
# /etc/init.d/fdfs_storaged start

# 也可以用这种方式,后面都用这种
# service fdfs_storaged start

查看 Storage 是否成功启动,23000 端口正在被监听,就算 Storage 启动成功。

1
# netstat -unltp|grep fdfs

查看Storage状态

关闭 Storage 命令:

1
# service fdfs_storaged stop

查看 Storage 和 Tracker 是否在通信:

1
/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

查看通信状态

⑥ 设置 Storage 开机启动

1
# chkconfig fdfs_storaged on

或者:

1
2
3
# vim /etc/rc.d/rc.local
# 加入配置:
/etc/init.d/fdfs_storaged start

⑦ Storage 目录

同 Tracker,Storage 启动成功后,在 base_path 下创建了 data、logs 目录,记录着 Storage Server 的信息。

在 store_path0 目录下,创建了 N*N 个子目录:

Storage目录结构

2.6 文件上传测试

① 修改 Tracker 服务器中的客户端配置文件

1
2
3
# cd /etc/fdfs
# cp client.conf.sample client.conf
# vim client.conf

修改如下配置即可,其它默认。

1
2
3
4
5
# Client 的数据和日志目录
base_path=/ljzsg/fastdfs/client

# Tracker端口
tracker_server=file.ljzsg.com:22122

② 上传测试

在 linux 内部执行如下命令上传 namei.jpeg 图片:

1
# /usr/bin/fdfs_upload_file /etc/fdfs/client.conf namei.jpeg

上传成功后返回文件 ID 号:group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg

上传测试结果

返回的文件 ID 由 group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

文件ID结构


三、安装Nginx

上面将文件上传成功了,但我们无法下载。因此安装 Nginx 作为服务器以支持 HTTP 方式访问文件。同时,后面安装 FastDFS 的 Nginx 模块也需要 Nginx 环境。

Nginx 只需要安装到 Storage Server 所在的服务器即可,用于访问文件。我这里由于是单机,Tracker Server 和 Storage Server 在一台服务器上。

3.1 安装 nginx 所需环境

① gcc 安装

② PCRE pcre-devel 安装

1
# yum install -y pcre pcre-devel

③ zlib 安装

1
# yum install -y zlib zlib-devel

④ OpenSSL 安装

1
# yum install -y openssl openssl-devel

3.2 安装 Nginx

① 下载 nginx

1
# wget -c https://nginx.org/download/nginx-1.12.1.tar.gz

② 解压

1
2
# tar -zxvf nginx-1.12.1.tar.gz
# cd nginx-1.12.1

③ 使用默认配置

④ 编译、安装

⑤ 启动 nginx

1
2
3
4
5
6
7
# cd /usr/local/nginx/sbin/
# ./nginx

# 其它命令
# ./nginx -s stop
# ./nginx -s quit
# ./nginx -s reload

⑥ 设置开机启动

1
2
3
4
5
6
# vim /etc/rc.local
# 添加一行:
/usr/local/nginx/sbin/nginx

# 设置执行权限
# chmod 755 rc.local

⑦ 查看 nginx 的版本及模块

1
/usr/local/nginx/sbin/nginx -V

查看Nginx版本

⑧ 防火墙中打开 Nginx 端口(默认的 80)

添加后就能在本机使用 80 端口访问了。

1
2
3
4
5
6
7
# vim /etc/sysconfig/iptables

# 添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

# 重启防火墙:
# service iptables restart

配置Nginx防火墙

3.3 访问文件

简单的测试访问文件。

① 修改 nginx.conf

1
2
3
4
5
6
7
8
9
# vim /usr/local/nginx/conf/nginx.conf

# 添加如下行,将 /group1/M00 映射到 /ljzsg/fastdfs/file/data
location /group1/M00 {
alias /ljzsg/fastdfs/file/data;
}

# 重启 nginx
# /usr/local/nginx/sbin/nginx -s reload

配置Nginx映射

② 在浏览器访问之前上传的图片,成功

1
http://file.ljzsg.com/group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg

四、FastDFS 配置 Nginx 模块

4.1 安装配置 Nginx 模块

① fastdfs-nginx-module 模块说明

FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进行文件复制,有同步延迟的问题。

假设 Tracker 服务器将文件上传到了 192.168.51.128,上传成功后文件 ID 已经返回给客户端。

此时 FastDFS 存储集群机制会将这个文件同步到同组存储 192.168.51.129,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 192.168.51.129 上取文件,就会出现文件无法访问的错误。

而 fastdfs-nginx-module 可以重定向文件链接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。

② 下载 fastdfs-nginx-module、解压

1
2
3
4
5
6
7
8
# 这里为啥这么长一串呢,因为最新版的 master 与当前 nginx 有些版本问题。
# wget https://github.com/happyfish100/fastdfs-nginx-module/archive/5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip

# 解压
# unzip 5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip

# 重命名
# mv fastdfs-nginx-module-5e5f3566bbfa57418b5506aaefbe107a42c9fcb1 fastdfs-nginx-module-master

③ 配置 Nginx

在 nginx 中添加模块:

1
2
3
4
5
6
7
8
9
10
11
# 先停掉 nginx 服务
# /usr/local/nginx/sbin/nginx -s stop

# 进入解压包目录
# cd /softpackages/nginx-1.12.1/

# 添加模块
# ./configure --add-module=../fastdfs-nginx-module-master/src

# 重新编译、安装
# make && make install

④ 查看 Nginx 的模块

1
# /usr/local/nginx/sbin/nginx -V

有下面这个就说明添加模块成功:

查看Nginx模块

⑤ 复制 fastdfs-nginx-module 源码中的配置文件到 /etc/fdfs 目录,并修改

1
2
3
# cd /softpackages/fastdfs-nginx-module-master/src

# cp mod_fastdfs.conf /etc/fdfs/

修改如下配置,其它默认:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 连接超时时间
connect_timeout=10

# Tracker Server
tracker_server=file.ljzsg.com:22122

# StorageServer 默认端口
storage_server_port=23000

# 如果文件ID的uri中包含/group**,则要设置为true
url_have_group_name = true

# Storage 配置的store_path0路径,必须和storage.conf中的一致
store_path0=/ljzsg/fastdfs/file

⑥ 复制 FastDFS 的部分配置文件到 /etc/fdfs 目录

1
2
3
# cd /softpackages/fastdfs-5.05/conf/

# cp anti-steal.jpg http.conf mime.types /etc/fdfs/

⑦ 配置 nginx,修改 nginx.conf

1
# vim /usr/local/nginx/conf/nginx.conf

修改配置,其它的默认。在 80 端口下添加 fastdfs-nginx 模块:

1
2
3
location ~/group([0-9])/M00 {
ngx_fastdfs_module;
}

配置fastdfs-nginx模块

注意:

  • listen 80 端口值是要与 /etc/fdfs/storage.conf 中的 http.server_port=80(前面改成 80 了)相对应。如果改成其它端口,则需要统一,同时在防火墙中打开该端口。
  • location 的配置,如果有多个 group 则配置 location ~/group([0-9])/M00,没有则不用配 group。

⑧ 在 /ljzsg/fastdfs/file 文件存储目录下创建软链接,将其链接到实际存放数据的目录,这一步可以省略

1
# ln -s /ljzsg/fastdfs/file/data/ /ljzsg/fastdfs/file/data/M00

⑨ 启动 nginx

1
# /usr/local/nginx/sbin/nginx

打印处如下就算配置成功:

启动Nginx成功

⑩ 在地址栏访问

能下载文件就算安装成功。注意和第三点中直接使用 nginx 路由访问不同的是,这里配置 fastdfs-nginx-module 模块,可以重定向文件链接到源服务器取文件。

1
http://file.ljzsg.com/group1/M00/00/00/wKgz6lnduTeAMdrcAAEoRmXZPp870.jpeg

最终部署结构图

可以按照下面的结构搭建环境:

部署结构图


五、Java客户端

前面文件系统平台搭建好了,现在就要写客户端代码在系统中实现上传下载,这里只是简单的测试代码。

5.1 搭建 FastDFS 客户端 Java 开发环境

① 项目中使用 maven 进行依赖管理,可以在 pom.xml 中引入如下依赖即可

1
2
3
4
5
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>

其它的方式,参考官方文档:https://github.com/happyfish100/fastdfs-client-java

② 引入配置文件

可直接复制包下的 fastdfs-client.properties.sample 或者 fdfs_client.conf.sample,到你的项目中,去掉 .sample

配置文件位置

直接复制 fastdfs-client.properties.sample 中的配置到项目配置文件 config.properties 中,修改 tracker_servers。只需要加载这个配置文件即可:

配置文件内容

5.2 客户端 API

个人封装的 FastDFS Java API 已同步到 github:https://github.com/bojiangzhou/lyyzoo-fastdfs-java.git


六、权限控制

前面使用 nginx 支持 http 方式访问文件,但所有人都能直接访问这个文件服务器了,所以做一下权限控制。

FastDFS 的权限控制是在服务端开启 token 验证,客户端根据文件名、当前 unix 时间戳、秘钥获取 token,在地址中带上 token 参数即可通过 http 方式访问文件。

6.1 服务端开启 token 验证

修改 http.conf:

1
2
3
4
5
6
7
8
9
10
11
12
13
# vim /etc/fdfs/http.conf

# 设置为true表示开启token验证
http.anti_steal.check_token=true

# 设置token失效的时间单位为秒(s)
http.anti_steal.token_ttl=1800

# 密钥,跟客户端配置文件的fastdfs.http_secret_key保持一致
http.anti_steal.secret_key=FASTDFS1234567890

# 如果token检查失败,返回的页面
http.anti_steal.token_check_fail=/ljzsg/fastdfs/page/403.html

记得重启服务。

6.2 配置客户端

客户端只需要设置如下两个参数即可,两边的密钥保持一致:

1
2
3
4
5
# token 防盗链功能
fastdfs.http_anti_steal_token=true

# 密钥
fastdfs.http_secret_key=FASTDFS1234567890

6.3 客户端生成 token

访问文件需要带上生成的 token 以及 unix 时间戳,所以返回的 token 是 token 和时间戳的拼接。

之后,将 token 拼接在地址后即可访问:

1
file.ljzsg.com/group1/M00/00/00/wKgzgFnkaXqAIfXyAAEoRmXZPp878.jpeg?token=078d370098b03e9020b82c829c205e1f&ts=1508141521
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* 获取访问服务器的token,拼接到地址后面
*
* @param filepath 文件路径 group1/M00/00/00/wKgzgFnkTPyAIAUGAAEoRmXZPp876.jpeg
* @param httpSecretKey 密钥
* @return 返回token,如: token=078d370098b03e9020b82c829c205e1f&ts=1508141521
*/
public static String getToken(String filepath, String httpSecretKey){
// unix seconds
int ts = (int) Instant.now().getEpochSecond();
// token
String token = "null";
try {
token = ProtoCommon.getToken(getFilename(filepath), ts, httpSecretKey);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
}

StringBuilder sb = new StringBuilder();
sb.append("token=").append(token);
sb.append("&ts=").append(ts);

return sb.toString();
}

6.4 注意事项

如果生成的 token 验证无法通过,请进行如下两项检查:

  • A. 确认调用 token 生成函数(ProtoCommon.getToken),传递的文件 ID 中没有包含 group name。传递的文件 ID 格式形如:M00/00/00/wKgzgFnkTPyAIAUGAAEoRmXZPp876.jpeg
  • B. 确认服务器时间基本是一致的,注意服务器时间不能相差太多,不要相差到分钟级别。

6.5 小结

对比下发现,如果系统文件隐私性较高,可以直接通过 fastdfs-client 提供的 API 去访问即可,不用再配置 Nginx 走 http 访问。配置 Nginx 的主要目的是为了快速访问服务器的文件(如图片),如果还要加权限验证,则需要客户端生成 token,其实已经没有多大意义。

关键是,这里我没找到 FastDFS 如何对部分资源加 token 验证,部分开放。有知道的还请留言。

一、概述

随着计算机技术的快速发展,信息安全问题日益突出。软件非法复制、通信泄密、数据安全威胁、解密及盗版问题日益严重,甚至引发国际争端。在信息安全技术中,加密技术占有不可替代的重要位置。因此,对信息加密技术和加密手段的研究与开发受到各国计算机界的高度重视,相关技术发展日新月异。

本文将详细介绍几种常用的加密算法,分析它们的特点、应用场景及安全性,帮助读者更好地理解和选择适合的加密方案。

二、对称加密算法

2.1 DES加密算法

算法简介
DES(Data Encryption Standard)是一种分组密码算法,以64位为分组对数据进行加密。其密钥长度为56位,加密和解密使用相同的算法。

工作原理

  • 将64位明文分组输入
  • 经过16轮复杂的置换和代换操作
  • 输出64位密文

安全性分析

  • DES加密算法的安全性依赖于密钥的保密性,算法本身是公开的
  • 对于56位长度的密钥,使用穷举法搜索的运算次数为2^56次
  • 随着计算机计算能力的提升,DES的安全性已相对较弱
  • 目前仅用于旧系统的兼容性支持,更多被新的加密标准取代

应用场景

  • 历史遗留系统
  • 对安全性要求不高的场景

2.2 AES加密算法

算法简介
AES(Advanced Encryption Standard)是密码学中的高级加密标准,采用对称分组密码体制。它被设计用于替代原先的DES算法。

技术参数

  • 密钥长度:支持128位、192位、256位
  • 分组长度:128位
  • 轮数:根据密钥长度不同,分别为10、12、14轮

安全性特点

  • 美国联邦政府采用的区块加密标准
  • 经过多方分析,被全世界广泛使用
  • 密钥空间巨大:128位对应约3.4×10^38个密钥,256位对应约1.1×10^77个密钥

应用场景

  • 政府机构数据加密
  • 金融交易安全
  • 企业敏感数据保护
  • 无线网络安全(WPA2)

三、非对称加密算法

3.1 RSA加密算法

算法简介
RSA是目前最有影响力的公钥加密算法之一,被普遍认为是优秀的公钥方案。它是第一个能同时用于加密和数字签名的算法。

数学原理
基于大数分解的困难性:

  • 将两个大素数相乘十分容易
  • 但对乘积进行因式分解极其困难
  • 公钥由两个大素数的乘积构成
  • 私钥由这两个大素数构成

技术特点

  • 密钥长度通常为1024位或2048位
  • 已被ISO推荐为公钥数据加密标准
  • 能够抵抗目前已知的所有密码攻击

应用场景

  • SSL/TLS协议
  • 数字证书
  • 安全电子邮件
  • 数字签名

四、编码与哈希算法

4.1 Base64编码

算法简介
Base64不是加密算法,而是一种编码方式。它是网络上最常见的用于传输8bit字节代码的编码方式之一。

工作原理

  • 将每3个8位字节转换为4个6位字节
  • 6位字节的值映射到64个可打印字符
  • 填充字符”=”用于处理不足3字节的情况

应用场景

  • HTTP环境下传递较长的标识信息
  • 电子邮件附件编码
  • URL参数编码
  • 数据库存储二进制数据

特点

  • 编码后的数据不会被人用肉眼直接识别
  • 主要用于数据传输,不提供安全性保护

4.2 MD5哈希算法

算法简介
MD5(Message-Digest Algorithm 5)是一种广泛使用的密码散列函数,用于提供消息的完整性保护。

工作原理

  • 以512位分组处理输入信息
  • 每个分组划分为16个32位子分组
  • 经过四轮处理,每轮16次操作
  • 输出128位散列值

应用场景

  • 文件完整性验证
  • 密码存储(加盐后)
  • 数字签名
  • 软件发布验证

安全性现状

  • 已被证明存在碰撞漏洞
  • 不再推荐用于安全性要求高的场景
  • 仍可用于非安全性相关的校验

4.3 SHA-1哈希算法

算法简介
SHA-1(Secure Hash Algorithm 1)是和MD5一样流行的消息摘要算法,设计用于与数字签名算法(DSA)一起使用。

技术参数

  • 输入长度:不超过2^64位
  • 输出长度:160位消息摘要
  • 处理块大小:512位

工作原理

  • 模仿MD4算法设计
  • 采用Merkle-Damgård结构
  • 包含80轮操作

安全性分析

  • 比MD5安全性强
  • 2017年被证明存在实际碰撞攻击
  • 谷歌等公司已宣布逐步淘汰SHA-1
  • 目前推荐使用SHA-256或SHA-3

应用场景

  • Git版本控制系统
  • 旧版SSL/TLS证书
  • 部分遗留系统

五、算法对比分析

算法类型 算法名称 密钥/摘要长度 安全性 性能 主要应用
对称加密 DES 56位 遗留系统
对称加密 AES 128/192/256位 现代加密标准
非对称加密 RSA 1024/2048位 数字签名、密钥交换
编码算法 Base64 - 数据传输编码
哈希算法 MD5 128位 文件校验(非安全)
哈希算法 SHA-1 160位 逐步淘汰中
哈希算法 SHA-256 256位 现代安全应用

六、选择建议

6.1 加密需求分析

  1. 机密性保护:选择AES(对称)或RSA(非对称)
  2. 完整性验证:选择SHA-256或SHA-3
  3. 身份认证:结合数字签名和证书
  4. 数据传输:使用SSL/TLS协议栈

6.2 安全性考虑

  1. 避免使用:DES、MD5、SHA-1(安全性不足)
  2. 推荐使用:AES-256、RSA-2048、SHA-256
  3. 未来趋势:关注后量子密码学发展

6.3 性能平衡

  1. 对称加密:适合大数据量加密,性能高
  2. 非对称加密:适合密钥交换和小数据量,性能较低
  3. 哈希算法:适合完整性验证,性能高

七、发展趋势

7.1 当前挑战

  1. 量子计算威胁:Shor算法可能破解RSA和ECC
  2. 算法漏洞:新的密码分析技术不断出现
  3. 实现安全:侧信道攻击等实现层面的威胁

7.2 发展方向

  1. 后量子密码学:抵抗量子计算攻击的新算法
  2. 同态加密:支持在密文上进行计算
  3. 多方安全计算:保护参与方隐私的协同计算
  4. 轻量级密码:适合物联网等资源受限环境

八、总结

加密算法是密码技术的核心,不同的算法适用于不同的应用场景。在选择加密算法时,需要综合考虑安全性、性能、兼容性和未来发展等因素。

当前建议:

  1. 对于对称加密,优先选择AES-256
  2. 对于非对称加密,使用RSA-2048或ECC
  3. 对于哈希算法,采用SHA-256或SHA-3
  4. 避免使用已知存在安全漏洞的算法

随着技术的不断发展,加密算法世界将会有新的成员加入,期待更安全、更高效的算法诞生,为信息安全提供更坚实的保障。


安全建议

  1. 定期更新加密算法和密钥
  2. 采用多层防御策略
  3. 关注安全社区的最新动态
  4. 进行定期的安全审计和测试

WPF引用xmlns:i=”clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity”后可以设置很多自定义的行为:

       <i:Interaction.Triggers\>
            <i:EventTrigger EventName\="ValueChanged"\>
                <i:InvokeCommandAction Command\="{Binding ValueChangedCommand}" />
            </i:EventTrigger\>
        </i:Interaction.Triggers\>

<UserControl.Resources>
<ControlTemplate x:Key=“trackThumb” TargetType=“{x:Type Slider}”>
<Border Background=“{TemplateBinding Background}” BorderBrush=“{TemplateBinding BorderBrush}” BorderThickness=“{TemplateBinding BorderThickness}”>
<Grid>
<Track x:Name=“PART_Track”>
<Track.Thumb>
<Thumb Width=“10”>
<i:Interaction.Triggers>
<i:EventTrigger EventName=“DragCompleted”>
<i:InvokeCommandAction Command=“{Binding ValueChangedCommand}” />
</i:EventTrigger>
</i:Interaction.Triggers>
</Thumb>
</Track.Thumb>
</Track>
</Grid>
</Border>
</ControlTemplate>
</UserControl.Resources>

当时当我们有一些自定义的需求时,需要自定义行为,例如给每个控件添加一个双击复制文本的行为。

1. 定义行为

public class MouseDoubleClickCopyTextBehavior : Behavior {
///


/// 需要复制的内容
///

public string CopyText
{ get { return (string)GetValue(CopyTextProperty); } set { SetValue(CopyTextProperty, value); }
} public static readonly DependencyProperty CopyTextProperty = DependencyProperty.Register(“CopyText”, typeof(string), typeof(MouseDoubleClickCopyTextBehavior), new PropertyMetadata(null)); protected override void OnAttached()
{ base.OnAttached();
AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
} protected override void OnDetaching()
{ base.OnDetaching();
AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
} void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{ if (e.ClickCount >= 2)
Clipboard.SetDataObject(CopyText);
}

  1. 控件绑定行为