获取Wi-Fi配置文件信息

3

我使用的是Windows 8.1,它没有一个带有GUI的工具来管理wifi网络配置文件。因此,我正在编写一个能够帮助我的工具。我进行了一些搜索,找到了Managed Wifi API,并通过教程的帮助将以下代码组合在一起:

foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
{
    foreach (Wlan.WlanProfileInfo profileInfo in wlanIface.GetProfiles())
    {
        string profileName = profileInfo.profileName;
        ListViewItem item = new ListViewItem(profileName);

        string profileXML = wlanIface.GetProfileXml(profileInfo.profileName);
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(profileXML);
        var NSManager = new XmlNamespaceManager(doc.NameTable);
        NSManager.AddNamespace("d", "http://www.microsoft.com/networking/WLAN/profile/v1");
        XmlNode node = doc.DocumentElement.SelectSingleNode("//d:WLANProfile/d:MSM/d:security/d:authEncryption/d:authentication", NSManager);

        item.SubItems.Add(node.InnerText);
        Profiles.Items.Add(item);
    }
}

获取已保存的网络配置文件列表并将其打印在ListView上。我有两个问题。一是如何使用Managed Wifi API获取完整的配置文件信息?因为我能获取到的只有配置文件名称,网站上没有文档说明。

第二个问题是,由于无法使用API获取完整的网络信息,我使用API以XML格式打印配置文件信息,然后解析XML并读取它。一个示例XML:

<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
    <name>MEDO PUB</name>
    <SSIDConfig>
        <SSID>
            <hex>4D45444F20505542</hex>
            <name>MEDO PUB</name>
        </SSID>
    </SSIDConfig>
    <connectionType>ESS</connectionType>
    <connectionMode>manual</connectionMode>
    <MSM>
        <security>
            <authEncryption>
                <authentication>WPA2PSK</authentication>
                <encryption>AES</encryption>
                <useOneX>false</useOneX>
            </authEncryption>
            <sharedKey>
                <keyType>passPhrase</keyType>
                <protected>true</protected>
                <keyMaterial>someReallyLongStringLike500+chars</keyMaterial>
            </sharedKey>
        </security>
    </MSM>
</WLANProfile>

我需要获取wifi密码,但我认为它是加密的。我应该如何获取实际密码或解码加密的密码?
更新:我找到了两个链接:揭示WiFi密码的秘密[C++]转储无线密码,但我不确定它们是否有效,或如何在C#中实施它们。

不要试图破解密码。您可以使用类似以下网页中的代码递归地添加XML:https://dev59.com/questions/JknSa4cB1Zd3GeqPR-Rq - jdweng
@jdweng 我不确定你的意思。我不想读取XML值。我想要解密加密或“哈希”过的XML值,即WiFi密码。 - akinuri
这是一个密码,设计成无法被解密。 - jdweng
@jdweng 第三方应用程序可以解密密码,例如WinFi,或以某种方式访问它。 - akinuri
1
可能是重复的问题(Possible duplicate):https://dev59.com/kmTWa4cB1Zd3GeqPBke2另外,“Windows 8.1没有管理WiFi网络配置文件的工具”这个说法是不正确的。你可以使用cmd工具netsh来完成。以管理员身份打开cmd窗口,然后输入:netsh wlan show profiles,接着获取密码:netsh wlan show profile "<a profile from the last step> key=clear - alexcalibur
@alexcalibur 是的,通常我使用命令行来完成这个操作。我的意思是除了 netsh 之外的其他工具,例如在 Windows 7 中使用图形用户界面。如果我表达不清楚,对不起。我会查看你提供的链接中的问题。我也想不使用 Managed Wifi API 来完成它。 - akinuri
1个回答

7

如我在评论中提到的,您可以使用以下方法实现此操作:

netsh wlan show profiles

那么

netsh wlan show profile "<a profile from the last step>" key=clear

如果您仍希望在代码中执行此操作,请继续阅读:
您使用的托管WiFi API没有此功能,但您可以轻松添加它。
请将Interop.cs中的WlanProfileFlags枚举修改为以下内容:
[Flags]
public enum WlanProfileFlags
{
    /// <remarks>
    /// The only option available on Windows XP SP2.
    /// </remarks>
    AllUser = 0,
    GroupPolicy = 1,
    User = 2,
    GetPlaintextKey = 4
}

将此功能添加到WlanApi.cs文件中,可能靠近GetProfileXml函数(为了组织的缘由)。
/// <summary>
/// Gets the profile's XML specification. Key is unencrypted.
/// </summary>
/// <param name="profileName">The name of the profile.</param>
/// <returns>The XML document.</returns>
public string GetProfileXmlUnencrypted(string profileName)
{
    IntPtr profileXmlPtr;
    Wlan.WlanProfileFlags flags = Wlan.WlanProfileFlags.GetPlaintextKey;
    Wlan.WlanAccess access;
    Wlan.ThrowIfError(
        Wlan.WlanGetProfile(client.clientHandle, info.interfaceGuid, profileName, IntPtr.Zero, out profileXmlPtr, out flags, out access));
    try
    {
        return Marshal.PtrToStringUni(profileXmlPtr);
    }
    finally
    {
        Wlan.WlanFreeMemory(profileXmlPtr);
    }
}

您可以调用此函数以获取未加密的密钥。
我没有测试过,但应该可以正常工作。如果您有任何问题,请告诉我。

您提供的代码示例运行良好。我有一个问题。您是如何了解这个的呢?我试图寻找关于Managed Wifi API的文档和教程,但没有找到。这是基于经验吗还是有某种来源?我可能需要在构建此工具时进一步帮助,所以我想知道。 - akinuri
我一直在使用本机WiFi API,所以我只是看了管理的API正在做什么,并添加了缺失的功能。这里是相关本机函数WlanGetProfile的链接。请注意,第四个参数pdwFlags具有值WLAN_PROFILE_GET_PLAINTEXT_KEY。 这对应于我添加的4。 - alexcalibur
糟糕,我是指第六个参数。 - alexcalibur
由于我看到了很多关于这个托管WiFi API的问题,而且它似乎很受欢迎,所以我决定将其克隆到github上在这里。现在它只是Codeplex上的一个副本,但如果您还有其他问题,请随时在那里打开一个问题,我会帮助解决。 - alexcalibur
我很高兴你这么做了,因为我认为我会改进我的工具,肯定需要帮助 :) - akinuri
@alexcalibur 这个可以用,谢谢。我有两个问题:1)如何列出与“netsh wlan show profile”结果完全相同的已保存无线局域网?2)如何仅通过给定的Profile/SSID名称直接访问配置文件数据?我知道,我可以循环遍历所有接口和所有配置文件 - 如果名称匹配,则找到所需的配置文件。是否有更直接的方法?谢谢。 - SUSiS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接