如何通过官方C#方式解密mslaps-encryptedpassword获取LAPS密码?
解密LAPS
mslaps-encryptedpassword 属性的C#实现方案 目前微软没有提供公开的官方C# API直接解密mslaps-encryptedpassword,但可以通过P/Invoke调用LAPS原生库的方式实现原生C#解密,无需依赖PowerShell脚本或模块。
核心实现思路
PowerShell的Get-LapsADPassword本质是调用LAPS安装包自带的原生库(如LAPS.dll)中的解密函数,我们可以直接在C#中通过P/Invoke复用这些底层逻辑。
具体步骤与代码示例
- 获取
mslaps-encryptedpassword字节数组:你已经完成这一步,确保拿到的是AD中该属性的原始二进制数据。 - P/Invoke调用LAPS解密函数:
LAPS安装后,系统中会存在LAPS.dll(通常位于C:\Windows\System32目录),其中导出了用于解密的函数。以下是C#中的调用示例:
using System; using System.Runtime.InteropServices; using System.ComponentModel; public class LapsDecryptor { [DllImport("LAPS.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool LapspsDecryptPassword(byte[] encryptedPassword, out IntPtr plaintextPassword, out uint plaintextLength); public static string DecryptLapsPassword(byte[] encryptedPassword) { if (encryptedPassword == null || encryptedPassword.Length == 0) throw new ArgumentNullException(nameof(encryptedPassword)); IntPtr plaintextPtr = IntPtr.Zero; uint plaintextLen = 0; try { bool success = LapspsDecryptPassword(encryptedPassword, out plaintextPtr, out plaintextLen); if (!success) { int win32Error = Marshal.GetLastWin32Error(); throw new Win32Exception(win32Error, "解密LAPS密码失败"); } // 转换为Unicode字符串(每个字符占2字节) return Marshal.PtrToStringUni(plaintextPtr, (int)(plaintextLen / 2)); } finally { // 释放原生内存 if (plaintextPtr != IntPtr.Zero) Marshal.FreeHGlobal(plaintextPtr); } } }
关键注意事项
- 权限要求:运行代码的身份必须拥有AD中对应计算机对象的LAPS密码读取权限(通常是域管理员或授权的用户组)。
- 库版本匹配:确保使用的
LAPS.dll与你部署的LAPS版本(2023年4月及以后的新版本)一致,不同版本的加密逻辑可能存在差异。 - 系统架构适配:如果你的C#程序是32位,需要调用
C:\Windows\SysWOW64\LAPS.dll;64位程序则调用C:\Windows\System32\LAPS.dll,也可以通过动态加载库的方式自动适配。
关于2023年4月LAPS新版本的说明
启用加密选项后,AD中不会再存储msLAPS-Password明文属性,所有密码数据仅以mslaps-encryptedpassword的加密形式存在,因此必须通过上述解密方式获取明文密码。
内容的提问来源于stack exchange,提问作者tryonlinux
相关产品推荐
相关产品推荐

