C#使用CredWrite访问C$我正在尝试使用没有服务器权限的域帐户访问服务器的C$。我需要以该服务器的本地登录形式保存凭据,以便程序运行。如何使用CredWrite保存这些凭据我发现的凭据管理器类:(编辑:下面是有效的代码。)使用系统;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用System.Runtime.InteropServices;使用Microsoft.Win32.SafeHandles;命名空间Test_Manager{publicclassWin32CredMan{[DllImport("Advapi32.dll",EntryPoint="CredReadW",CharSet=CharSet.Unicode,SetLastError=true)]staticexternboolCredRead(stringtarget,CRED_TYPEtype,intreservedFlag,outIntPtrCredentialPtr);[DllImport("Advapi32.dll",EntryPoint="CredWriteW",CharSet=CharSet.Unicode,SetLastError=true)]staticexternboolCredWrite([In]refNativeCredentialuserCredential,[In]UInt32flags);[DllImport("Advapi32.dll",EntryPoint="CredFree",SetLastError=true)]staticexternboolCredFree([In]IntPtrcred);publicenumCRED_TYPE:uint{GENERIC=1,DOMAIN_PASSWORD=2,DOMAIN_CERTIFICATE=3,DOMAIN_VISIBLE_PASSWORD=4,GENERIC_CERTIFICATE=5,DOMAIN_EXTENDED=6,MAXIMUM=7,//最大支持的信用类型MAXIMUM_EX=(MAXIMUM+1000),//允许新应用程序在旧操作系统上运行}publicenumCRED_PERSIST:uint{SESSION=1,LOCAL_MACHINE=2,ENTERPRISE=3,}[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]privatestructNativeCredential{publicUInt32Flags;公共CRED_TYPE类型;公共IntPtr目标名称;公共IntPtr评论;公共System.Runtime.InteropServices.ComTypes.FILETIMELastWritten;公共UInt32CredentialBlobSize;公共IntPtrCredentialBlob;公共UInt32坚持;公共UInt32属性计数;publicIntPtr属性;公共IntPtrTargetAlias;公共IntPtr用户名;//////此方法从给定的Credential实例派生NativeCredential实例。//////包含要存储的数据的托管凭证副本。///从给定的Credential///实例派生的NativeCredential实例。内部静态NativeCredentialGetNativeCredential(Credentialcred){NativeCredentialncred=newNative凭据();ncred.AttributeCount=0;ncred.Attributes=IntPtr.Zero;ncred.Comment=IntPtr.Zero;ncred.TargetAlias=IntPtr.Zero;ncred.Type=(CRED_TYPE)cred.Type;ncred.Persist=(UInt32)cred.Persist;ncred.CredentialBlobSize=(UInt32)cred.CredentialBlobSize;ncred.TargetName=Marshal.StringToCoTaskMemUni(cred.TargetName);ncred.CredentialBlob=Marshal.StringToCoTaskMemUni(cred.CredentialBlob);ncred.UserName=Marshal.StringToCoTaskMemUni(cred.UserName);返回信任;}}[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)]privatestructCredential{publicUInt32Flags;公共CRED_TYPE类型;公共字符串目标名称;公共字符串注释;公共System.Runtime.InteropServices.ComTypes.FILETIMELastWritten;公共UInt32CredentialBlobSize;公共字符串CredentialBlob;公共CRED_PERSIST坚持;公共UInt32属性计数;publicIntPtr属性;公共字符串TargetAlias;公共字符串用户名;}#region关键HandleTypedefinitionsealedclassCriticalCredentialHandle:CriticalHandleZeroOrMinusOneIsInvalid{//设置句柄。内部CriticalCredentialHandle(IntPtrpreexistingHandle){SetHandle(preexistingHandle);}internalCredentialGetCredential(){if(!IsInvalid){//从mem位置获取CredentialNativeCredentialncred=(NativeCredential)Marshal.PtrToStructure(handle,typeof(NativeCredential));//创建托管凭据类型并使用来自本机对应项的数据填充它。凭据cred=newCredential();cred.CredentialBlobSize=ncred.CredentialBlobSize;cred.CredentialBlob=Marshal.PtrToStringUni(ncred.CredentialBlob,(int)ncred.CredentialBlobSize/2);cred.UserName=Marshal.PtrToStringUni(ncred.UserName);cred.TargetName=Marshal.PtrToStringUni(ncred.TargetName);cred.TargetAlias=Marshal.PtrToStringUni(ncred.TargetAlias);cred.Type=ncred.Type;cred.Flags=ncred.Flags;cred.Persist=(CRED_PERSIST)ncred.P坚持;回报信用;}else{thrownewInvalidOperationException("InvalidCriticalHandle!");}}//执行任何特定操作以释放ReleaseHandle方法中的句柄。//通常,您需要使用Pinvoke调用Win32API以释放//句柄。然而,在这种情况下,我们可以使用Marshal类来释放非托管内存。overrideprotectedboolReleaseHandle(){//如果设置了句柄,则释放它。返回成功。if(!IsInvalid){//注意:我们还应该将分配给句柄的内存清零,然后再释放它//因此内存中不会留下任何敏感数据的痕迹。CredFree(句柄);//将句柄标记为对未来用户无效。SetHandleAsInvalid();返回真;}//返回假。返回假;}}#endregionpublicintWriteCred(stringkey,stringuser,stringsecret){//验证。byte[]byteArray=Encoding.Unicode.GetBytes(秘密);如果(byteArray.Length>512)抛出新的ArgumentOutOfRangeException("密文已超过512字节。");//继续我们所拥有的,将其填充到CredMan结构中。凭据cred=newCredential();cred.TargetName=密钥;cred.UserName=用户名;cred.CredentialBlob=秘密;cred.CredentialBlobSize=(UInt32)Encoding.Unicode.GetBytes(secret).Length;cred.AttributeCount=0;cred.Attributes=IntPtr.Zero;cred.Comment=null;cred.TargetAlias=null;cred.Type=CRED_TYPE.DOMAIN_PASSWORD;cred.Persist=CRED_PERSIST.ENTERPRISE;NativeCredentialncred=NativeCredential.GetNativeCredential(cred);//将信息写入CredMan存储。boolwritten=CredWrite(refncred,0);intlastError=Marshal.GetLastWin32Error();如果(写){返回0;}else{stringmessage=string.Format("CredWrite失败,错误代码为{0}。",lastError);抛出新的异常(消息);}}publicstaticstringReadCred(stringkey){//验证。IntPtrnCredPtr;字符串读取密码文本=nu二;//使用P/Invoke签名进行API调用boolread=CredRead(key,CRED_TYPE.GENERIC,0,outnCredPtr);intlastError=Marshal.GetLastWin32Error();//如果API成功,则...if(read){using(CriticalCredentialHandlecritCred=newCriticalCredentialHandle(nCredPtr)){readPasswordText=cred.CredentialBlob;}}else{readPasswordText=string.Empty;//1168是“找不到元素”——忽略它并返回空字符串:if(lastError!=1168){stringmessage=string.Format("ReadCredfailedwiththeerrorcode{0}.",lastError);抛出新的异常(消息);}}返回读密码文本;}}}长话短说这是我正在尝试使用的描述代码中的方法:publicintWriteCred(stringkey,stringuser,stringsecret){//验证。byte[]byteArray=Encoding.Unicode.GetBytes(秘密);if(byteArray.Length>512)thrownewArgumentOutOfRangeException("秘密消息已超过512字节。");//继续d用我们拥有的东西将其填充到CredMan结构中。凭据cred=newCredential();cred.TargetName=密钥;cred.UserName=用户名;cred.CredentialBlob=秘密;cred.CredentialBlobSize=(UInt32)Encoding.Unicode。cred.AttributeCount=0;cred.Attributes=IntPtr.Zero;cred.Comment=null;cred.TargetAlias=null;cred.Type=CRED_TYPE.DOMAIN_PASSWORD;cred.Persist=CRED_PERSIST.ENTERPRISE;ncred=NativeCredential.GetNativeCredential(信用);//将信息写入CredMan存储。boolwritten=CredWrite(refncred,0);intlastError=Marshal.GetLastWin32Error();如果(写){返回0;}else{stringmessage=string.Format("CredWrite失败,错误代码为{0}。",lastError);抛出新的异常(消息);这就是我在程序文字中所做的:Win32CredMancm=newWin32CredMan();cm.WriteCred("TheServer-18",@"TheServer-18Administrator","P4SSw0rD!");我假设我无法访问,因为没有正确添加凭据更新:我介绍的过程是将通用凭据添加到Windows凭据管理器。但是,如果不使用WriteCred方法中指定的用户名。我不懂为什么。问题解决了,上面的代码现在可以正常运行了。问题与GetNativeCredential有关,它不是使用在WriteCred方法中分配给cred的值,而是一些已设置的静态值。此外,我将信息输入WriteCred方法的方式不正确。上面的代码已经修复,因此它可以正常运行。以上就是C#学习教程:C#使用CredWrite访问C$共享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
