设备商的朋友跟我吐槽过一件事他们给客户做的一台绕线机控制器用的就是西门子S7-200 Smart交付时出于信任把CPU密码直接告诉了车间主任。结果半年后客户打电话过来说设备参数被改得一塌糊涂产品批量报废。人到现场一查密码被人改过程序也被动过连是谁改的都查不出来。这种场景在中小型设备上太常见了也让我下定决心在后续项目里做一套“双保险”第一层是S7-200 Smart自带的原生密码保护锁住外人动手脚的入口第二层是自己开发的动态锁屏密码功能解决静态密码流传出去就再也收不回来的问题。这篇文章把这两层方案的完整思路和落地代码写出来给正在做同类设备的工程师做个参考。1. 为什么静态密码不够用设备交付后的权限失控1.1 一套设备上有三类人权限诉求完全不同我做过的几十个S7-200 Smart项目里凡是出权限问题的几乎都出在“一套设备多人共享一组密码”这个源头上。一套设备交付后长期围着它转的基本有三类人操作工每天在触摸屏上启停设备、调速度、查产量偶尔还要修改温度曲线、配方参数。他们真正需要的是“可以用”但绝不应该碰到程序内部的核心工艺。维修电工设备报警了要排查可能要在线监控、强制某些变量、甚至上传程序看逻辑。他们需要“能修”但设备商通常不希望他们看到全部工艺算法。设备商/厂家也就是我们这些写程序的人。需要保留完整访问权限快速定位问题也侧面保护自己的知识产权。这三类人的权限边界如果用同一组固定密码去划分基本等于没有边界。密码一旦进了车间流传速度远超想象写在本子上、发在班组群里、录在手机备忘录里甚至直接贴在触摸屏旁边。1.2 静态密码的三个天生缺陷固定密码最大的问题是“无法区分授权和泄密”。我见过最典型的项目设备商的调试密码是“1234”客户要求改参数工程师就把密码告诉操作工操作工又告诉下一班同事最后四个班全能改配方。等产品出问题才发现整条产线的配方参数早就不是出厂值了。固定密码还有两个在工程上非常致命的弱点无法自动回收密码一旦给出去除非你重新跑到现场重新下载系统块否则它永远有效。很多时候你根本不知道哪些人手里有密码换密码就意味着停机和差旅成本。无法审计追溯用同一个密码做的所有操作在系统里完全无法区分是谁干的。出了质量事故你连“什么时间改了哪个参数”都查不全更不用说定位到人。1.3 动态锁屏密码解决的是什么问题后来我在几个项目里改成了“动态锁屏密码”机制设备管理员手里握着一套算法和密钥可以给当天的任何时间段生成一次性口令操作工想要修改关键参数或者进入受保护画面必须打电话或通过内部系统索取当天有效口令。口令通常每隔一小时自动变化一次过期就作废。这套机制解决的就是静态密码的三大痛点口令具体绑定到“某个时间段”时间一过自动失效算法掌握在管理员手里下发权限可以随时撤回每次口令使用都会被PLC记录方便事后追溯是谁在什么时间点解了锁。它不是银弹但配合原生的CPU密码保护可以挡住绝大多数非授权操作。2. S7-200 SMART的原生密码保护先锁住程序访问入口2.1 CPU密码保护系统块里的访问控制等级S7-200 Smart的CPU密码在STEP 7-MicroWIN SMART里配置入口在“系统块 → CPU → 密码保护”。这个功能管的是“外部能不能对你的PLC进行编程操作”包括上传程序、下载程序、在线监控、修改运行模式、强制变量等。它有几个从低到高的保护等级简单理解就是保护等级允许的操作需要密码的操作完全访问查看、上传、下载、监控、强制、修改运行无受保护访问查看、监控、上传下载、强制、修改运行、其他编程操作完全保护基本在线监控受限几乎所有编程功能都需要密码验证不同软件版本对等级的叫法会有一点差异但核心逻辑一致等级越高外部能无密码执行的操作越少。我个人的经验是设备正式交付后直接选择最高保护等级这个保护等级下即使有人能建立以太网连接想上传程序、下载程序、切换运行状态都必须先过密码验证这一关。配置过程本身很容易踩一个坑密码是在系统块里设置的必须把系统块下载到PLC之后才生效单独编译程序块不会触发密码保护。下载系统块之后CPU会重启一次重启后在线连接就要求输入密码了。如果是在项目调试阶段我建议先把所有程序和系统块都下载完、确认设备运行正常最后再下载带密码的系统块避免自己把自己挡在外面。2.2 专有技术保护程序块级别的“代码加密”CPU密码保护管的是“能不能操作”它管不了另一件事有权限的维修电工把程序上传回去之后能不能读懂你的逻辑。如果想要保护工艺算法自己的“知识产权”S7-200 Smart还有一层“专有技术保护”。在STEP 7-MicroWIN SMART左侧的项目树里右键点击任意程序块MAIN、SBR_0、INT_0等选择“专有技术保护”设置一个密码该程序块就会被加密。设置后PLC里运行的程序不受影响但是当你把程序从PLC里上载回来受保护的块在MicroWIN SMART里显示为一个“加密块”双击进去看不到任何梯形图或STL代码。我通常把“CPU密码保护”和“专有技术保护”叠加使用CPU密码挡住外部对整个CPU的编程操作专有技术保护挡住内部有权限者对某一两个核心子程序块的源码读取。两者配合才是真正的双层防御。2.3 设置前必须做的几个准备动作密码这玩意设置错了代价很大。我个人的工作习惯是先全量存档把整个项目和导出文件完整备份一份写上日期和密码放在项目档案里。这一步看着简单但能救大命。确认通信路径S7-200 Smart的密码保护不分通信方式以太网口和485口访问都要验证。别想着“我网口设了密码串口还能绕过”不存在。选等级要冷静有些人为了安全直接选完全保护结果第二天自己想去车间看程序密码忘了只能干瞪眼。我的原则是设备还在调试期用低级保护甚至不设密码正式验收交付后上最高保护。3. 动态锁屏密码的算法设计基于实时时钟的小时级口令3.1 动态口令的三种常见玩法“动态锁屏密码”不是西门子出厂自带的功能而是工程上利用PLC的实时时钟加逻辑运算实现的一种自定义安全机制。它的核心思路是用时间作为输入算出一组会变化的口令。工程上常见的有三档方案方案实现方式安全性复杂度静态密码人工定期更换密码存在HMI或PLC里管理员定期去改低更换周期长容易泄密最低基于RTC的小时级口令PLC读取系统时钟按公式生成每小时有效的口令中时间窗口内可重复使用但足够应对车间场景低挑战-响应式口令PLC动态生成随机挑战码由上位机算法算出响应码高每次解锁口令不同防重放高需要上位机配合车间现场大多数情况下用第二种就够了。它的特点是实现简单、不依赖PC和通信链路而且可以完全离线验证——一个Excel表格就能算口令非常实用。第三种更适合有上位机系统的场合后文会简单提一下。3.2 小时级口令的算法设计我习惯的口令算法是这样的口令 (月份 × 100 日期) × 10 小时 固定密钥取结果的低4位。举个例子2024年7月15日下午2点固定密钥设为3690那么计算过程是月份 7日期 15 → 7 × 100 15 715715 × 10 14小时 71647164 3690 10854取低4位 0854这就是当天14点这个小时内唯一有效的动态口令。这个算法有几个细节是经过实际使用打磨的“月份×100 日期”保证每天的口令都不同不同日期即使同一小时前半段基础值也不一样。“×10 小时”保证同一天内每小时的口令不同到下一小时基础值自动变化。加固定密钥是把真正的密码因子藏在程序里操作员拿到手的永远是混淆后的结果看不到原始算法和密钥。取低4位是为了让口令好记、好输四位数字在HMI数字键盘上输入非常方便。因为触摸屏数值输入框存的是整数0854显示成854也没关系操作员输入854也能通过。实际生产环境里还必须考虑一个时间窗口问题操作员正好在整点跨小时的瞬间输入口令比如14:59输入的是14点口令15:00一过口令立刻变成15点的新值刚输进去就报错。这种体验非常糟糕。所以我在实现里加了一个“双窗口”机制——当前小时口令和上一小时口令同时有效。也就是说在15:00到15:59之间输入14点或15点的口令都能通过。这样既保证了口令会过期又不会卡死跨小时边缘。3.3 需要用到的指令和存储资源在S7-200 Smart里实现这套逻辑核心依赖两样东西第一是读取实时时钟。MicroWIN SMART里的指令叫“READ_RTC”读实时时钟操作数是一个字节地址开头连续8个字节的缓冲区。读取结果全部是BCD码顺序是年、月、日、时、分、秒、保留字节、星期。比如缓冲区起始地址是VB100那么VB100存两位年份24代表2024VB101存月份BCD码07代表7月VB102存日期VB103存小时以此类推。第二是BCD码转整数。这是新手最容易翻车的地方。BCD码和二进制整数不是一回事比如BCD码的0x15表示十进制15但当它作为十六进制数转到整数时数值变成了21。所以必须用“BCD_I”指令把BCD码转成真正的整数。月份、日期、小时这三个值在使用前都要先转到整数寄存器里。运算部分会用到乘法和加法以及最后取低4位的“除法取余”。S7-200 Smart没有直接的“取余”指令但整数除法指令DIV_I有个特殊的返回格式它把商放到32位输出区的高16位余数放到低16位。比如VD300里放的是被除数执行DIV_I 10000, VD300之后商在VW302余数在VW300我们直接用VW300作为静态口令即可。4. 梯形图与HMI联动实现变量表、伪代码和画面做法4.1 存储区规划为了让逻辑清晰我建议把这块功能独立划出一段V区规划如下地址用途说明VB100READ_RTC缓冲区起始连续8字节存放时间BCD码VW200月份整数BCD_I转换后存放VW202日期整数BCD_I转换后存放VW204小时整数BCD_I转换后存放VW206上一次读取的小时用于判断是否跨小时VW210当前小时口令算法计算结果VW212上一小时口令跨小时时备份旧值VW214操作员输入的密码HMI数值输入写入M10.0解锁成功标志为1时允许进入受保护画面M10.1锁定标志为1时即使密码正确也不放行C10密码错误计数连续错误计数T37锁定延时30分钟锁定计时4.2 核心梯形图逻辑的伪代码下面的写法不是完整梯形图而是方便你照着在MicroWIN SMART里拼出逻辑的伪代码。我用的是主程序里普通梯形图即可完成不需要写中断程序// 初始化上电第一次扫描清零 SM0.1 MOVW 0, VW206 MOVW 0, VW210 MOVW 0, VW212 MOVW 0, VW214 RESET C10, 1 // 每0.5秒读一次实时时钟并更新动态口令 SM0.5上升沿 READ_RTC VB100 // 读取时间到VB100起始的8字节 // BCD转整数 MOVW 0, VW201? // 示例先清零VW200的高位字节VB200 MOVB VB101, VB201 // 把月份BCD字节放到VW200的低字节 BCD_I VW200, VW200 // VW200 月份整数 MOVB VB102, VB203 // 日期BCD字节 BCD_I VW202, VW202 // VW202 日期整数 MOVB VB103, VB205 // 小时BCD字节 BCD_I VW204, VW204 // VW204 小时整数 // 判断是否跨小时 LDW VW204, VW206 // 如果当前小时与上一次不同 // 更严谨的写法若VW204 VW206则 MOVW VW210, VW212 // 把旧口令备份到上一小时口令 MOVW VW204, VW206 // 更新上一次小时记录 // 重新计算当前小时口令 MOVW VW202, VW220 // VW220 日期 *I 10, VW220 // VW220 日期 × 10 I VW204, VW220 // VW220 日期 × 10 小时 // 再算上月份权重基础值 (月份×100日期)×10小时 MOVW VW200, VW222 *I 100, VW222 // VW222 月份 × 100 I VW202, VW222 // VW222 月份×100 日期 *I 10, VW222 // VW222 (月份×100日期)×10 I VW204, VW222 // VW222 (月份×100日期)×10小时 I 3690, VW222 // 固定密钥 MOVW VW222, VD300 // 被除数送入VD300低16位注意先清零VD300高位 DIV_I 10000, VD300 // 商在VW302余数在VW300 MOVW VW300, VW210 // VW210 当前小时口令这段逻辑我故意写得细了一点因为实际拼梯形图时最容易乱的就是DIV_I的32位操作数。DIV_I要求输出是一个32位双字地址比如VD300。被除数要先放进这个双字里而且双字的高16位必须清零否则会把VW302里的历史数据一起当成被除数的高位算出完全错误的结果。我见过不少同事在这里栽跟头。4.3 输入校验和错误锁定逻辑口令验证逻辑放在操作员按下触摸屏“解锁确认”按钮时触发// 按钮按下的上升沿 M10.2上升沿 // 密码正确等于当前小时口令或上一小时口令 LDW VW214, VW210 OW VW214, VW212 AN M10.1 // 锁定期间不接受解锁 // 解锁成功 SET M10.0, 1 // 输出解锁标志给HMI RESET C10, 1 // 清零错误计数 // 密码错误 LDW VW214, VW210 AW VW214, VW212 AN M10.1 INC C10 // 错误次数加1 // 错误次数达到3次锁定30分钟 LDW C10, 3 SET M10.1, 1 // 置锁定标志 TONR T37, 1800000 // 30分钟保持型定时器 LD T37 RESET M10.1, 1 // 锁定时间到解除锁定 RESET C10, 1这里有一个工程细节锁定时间到后必须顺带把错误计数器清零否则操作员第4次错误输入会瞬间又触发锁定。另外解锁成功标志M10.0在HMI侧使用后建议由“退出参数画面”按钮复位或者做一个“无操作10分钟后自动重新锁定”的定时器避免解锁状态长时间挂在那边。4.4 HMI画面怎么配合触摸屏这边我用过威纶通MT系列也用西门子Smart Line。两家的实现逻辑其实一致画面放一个数字输入框绑定VW214一个“确认解锁”按钮控制M10.2一个“锁定/退出”按钮复位M10.0再放几个指示灯绑定M10.0和M10.1。不建议在触摸屏宏指令里做密码计算再传给PLC因为HMI工程很容易被复制算法一旦泄出去整套机制就破了。正确做法是所有计算全部在PLC里做触摸屏只负责输入数字和显示结果。锁屏画面的设计要特别注意“防跳出”用弹出式窗口覆盖整个屏幕禁用物理返回键和左上角返回按钮操作员只能看到数字键盘和提示文字。输入错误时只显示“口令无效请重新输入”不要提示“差一个数字”或者“密钥不对”这类精确反馈避免被试探出算法。4.5 管理员的离线口令生成工具动态密码最大的便利是管理员不需要守在设备旁边。我交付时给设备方做了一个Excel模板管理员只需要输入月份、日期、小时再加上项目自己的固定密钥就能算出口令。公式就是前面那个算法在Excel里写MODE((A1*100B1)*10C13690,10000)配合单元格自定义格式“0000”就能显示四位口令。哪位操作员打电话来要密码管理员看一眼手机上的Excel报个四位数就行。如果有C#开发能力也可以写个同样算法的小工具但这套机制本身不依赖OPC、不依赖上位机通路是最轻量可靠的方案。5. 加固与踩坑动态密码用久之后才会注意到的边界5.1 防爆破与审计增强基础版动态密码能挡普通操作工但几个明显的弱点必须补齐。首先是暴力尝试四位数口令最多一万种组合如果让人随便输一晚上慢慢试也能试出来。所以连续错误锁定是必须的锁定时长可以根据项目场景调整车间现场我一般设30分钟如果是保密要求高的工序直接锁2小时。其次是审计。为了追溯是谁解的锁我在HMI上增加了一个“操作工编号”输入框绑定VW220之类的位置解锁时PLC把当前时钟和操作工编号一起写入保持性V区形成一条最简单的流水记录。设备方日后查“三班倒里到底谁动过参数”翻PLC存的数据就行。这块不需要额外硬件只需要HMI上多一个输入框。5.2 时钟相关的最典型三个坑这年头做S7-200 Smart动态密码十次里八次问题出在时钟上。第一个坑是BCD码没转换。前面已经强调过这个坑发生在“明明是7月运算出来却是18”这种诡异情况。一定要用BCD_I指令把月、日、时全部转成整数再参与公式计算。第二个坑是PLC断电后时钟漂移。S7-200 Smart内部有时钟保持电容断电几个小时没问题断电几天再上电时间就会慢。结果就是管理员按当前时间算出的口令PLC那边用的是慢了两个小时的时间怎么输都不对。解决方法是在每台设备上增加HMI或者其他上位机的定期校时机制威纶通的系统时间可以和PLC同步Smart Line也支持通过通讯设置时间。设备上电后先校一次时这个问题基本就消失了。第三个坑是跨小时边界。14:59和15:01输入同一个14点口令一个通过一个不通过操作员会以为设备坏了。双窗口方案就是为这个准备的务必实现当前小时口令和上一小时口令同时生效。5.3 别忘了第一层保护的兜底作用动态锁屏密码防的是“没有算法和密钥的人”它防不住“能够把PLC程序上传走的人”。如果CPU本身被设成了完全访问维修电工把完整程序上载回去把动态密码算法和固定密钥一分析整个机制彻底报废。所以正确的关系一定是CPU密码保护是外层门锁动态锁屏密码是内层保险柜。我在所有项目里都会先把CPU密码设成最高等级再给核心程序块做专有技术保护最后才把这套动态口令逻辑部署到HMI层。三层缺一不可顺序也不能乱。5.4 忘记密码的恢复路径任何人都可能忘记密码包括自己。S7-200 Smart的密码机制保护得很死一旦遗忘官方没有提供常规在线破解手段。我经历过的恢复方式主要有两种一是将PLC存储区和程序全部清除恢复到出厂状态但这意味着设备里的程序、数据块、驱动配置全部丢失必须用备份重新下载二是联系西门子技术支持走官方协助路径同样需要提供购买和项目证明。所以密码设置前项目源文件的存档是第一优先级。我个人习惯是在项目交付清单里专门留一页“密码记录页”写上CPU密码、专有技术保护密码、动态口令算法密钥、设置日期、程序版本。这一页只交给设备方管理层不进随机图纸。密码这种东西只有在“必须知道的人才看得到”的前提下才算真正被保护。如果你手头正好有S7-200 Smart的样机按上面的变量表一个下午就能把整个动态锁屏密码功能搭起来。算法本身不复杂真正花时间的是把权限边界想清楚、把时钟坑躲开、让HMI交互足够顺手。这几件事都做好了设备交付后半夜里被电话吵醒的概率会小很多。