(一百七十二) WiFi如何分辨出不同加密方式的AP?
1. ie
之前获取扫描结果的流程中有个将从kernel获取的scan result转换成framework的过程
/*** Fetch the latest scan result from kernel via wificond.* @param ifaceName Name of the interface.* @return Returns an ArrayList of ScanDetail.* Returns an empty ArrayList on failure.*/public ArrayList getScanResults(@NonNull String ifaceName, int scanType) {ArrayList results = new ArrayList<>();IWifiScannerImpl scannerImpl = getScannerImpl(ifaceName);if (scannerImpl == null) {Log.e(TAG, "No valid wificond scanner interface handler");return results;}try {NativeScanResult[] nativeResults;if (scanType == SCAN_TYPE_SINGLE_SCAN) {nativeResults = scannerImpl.getScanResults();} else {nativeResults = scannerImpl.getPnoScanResults();}for (NativeScanResult result : nativeResults) {WifiSsid wifiSsid = WifiSsid.createFromByteArray(result.ssid);String bssid;try {bssid = NativeUtil.macAddressFromByteArray(result.bssid);} catch (IllegalArgumentException e) {Log.e(TAG, "Illegal argument " + result.bssid, e);continue;}if (bssid == null) {Log.e(TAG, "Illegal null bssid");continue;}ScanResult.InformationElement[] ies =InformationElementUtil.parseInformationElements(result.infoElement);InformationElementUtil.Capabilities capabilities =new InformationElementUtil.Capabilities();capabilities.from(ies, result.capability);String flags = capabilities.generateCapabilitiesString();NetworkDetail networkDetail;try {networkDetail = new NetworkDetail(bssid, ies, null, result.frequency);} catch (IllegalArgumentException e) {Log.e(TAG, "Illegal argument for scan result with bssid: " + bssid, e);continue;}ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags,result.signalMbm / 100, result.frequency, result.tsf, ies, null);ScanResult scanResult = scanDetail.getScanResult();// Update carrier network info if this AP's SSID is associated with a carrier Wi-Fi// network and it uses EAP.if (ScanResultUtil.isScanResultForEapNetwork(scanDetail.getScanResult())&& mCarrierNetworkConfig.isCarrierNetwork(wifiSsid.toString())) {scanResult.isCarrierAp = true;scanResult.carrierApEapType =mCarrierNetworkConfig.getNetworkEapType(wifiSsid.toString());scanResult.carrierName =mCarrierNetworkConfig.getCarrierName(wifiSsid.toString());}// Fill up the radio chain info.if (result.radioChainInfos != null) {scanResult.radioChainInfos =new ScanResult.RadioChainInfo[result.radioChainInfos.size()];int idx = 0;for (RadioChainInfo nativeRadioChainInfo : result.radioChainInfos) {scanResult.radioChainInfos[idx] = new ScanResult.RadioChainInfo();scanResult.radioChainInfos[idx].id = nativeRadioChainInfo.chainId;scanResult.radioChainInfos[idx].level = nativeRadioChainInfo.level;idx++;}}results.add(scanDetail);}} catch (RemoteException e1) {Log.e(TAG, "Failed to create ScanDetail ArrayList");}if (mVerboseLoggingEnabled) {Log.d(TAG, "get " + results.size() + " scan results from wificond");}return results;}
从上面可以看到解析出ssid和bssid
加密方式没怎么看的到,抽出来看下这一段
ScanResult.InformationElement[] ies =InformationElementUtil.parseInformationElements(result.infoElement);InformationElementUtil.Capabilities capabilities =new InformationElementUtil.Capabilities();capabilities.from(ies, result.capability);String flags = capabilities.generateCapabilitiesString();NetworkDetail networkDetail;try {networkDetail = new NetworkDetail(bssid, ies, null, result.frequency);} catch (IllegalArgumentException e) {Log.e(TAG, "Illegal argument for scan result with bssid: " + bssid, e);continue;}ScanDetail scanDetail = new ScanDetail(networkDetail, wifiSsid, bssid, flags,result.signalMbm / 100, result.frequency, result.tsf, ies, null);ScanResult scanResult = scanDetail.getScanResult();
看下capabilities.from
/*** Parse the Information Element and the 16-bit Capability Information field* to build the InformationElemmentUtil.capabilities object.** @param ies -- Information Element array* @param beaconCap -- 16-bit Beacon Capability Information field*/public void from(InformationElement[] ies, BitSet beaconCap) {protocol = new ArrayList();keyManagement = new ArrayList>();groupCipher = new ArrayList();pairwiseCipher = new ArrayList>();if (ies == null || beaconCap == null) {return;}isESS = beaconCap.get(CAP_ESS_BIT_OFFSET);isPrivacy = beaconCap.get(CAP_PRIVACY_BIT_OFFSET);for (InformationElement ie : ies) {if (ie.id == InformationElement.EID_RSN) {parseRsnElement(ie);}if (ie.id == InformationElement.EID_VSA) {if (isWpaOneElement(ie)) {parseWpaOneElement(ie);}if (isWpsElement(ie)) {// TODO(b/62134557): parse WPS IE to provide finer granularity information.isWPS = true;}}}}// RSNE format (size unit: byte)//// | Element ID | Length | Version | Group Data Cipher Suite |// 1 1 2 4// | Pairwise Cipher Suite Count | Pairwise Cipher Suite List |// 2 4 * m// | AKM Suite Count | AKM Suite List | RSN Capabilities |// 2 4 * n 2// | PMKID Count | PMKID List | Group Management Cipher Suite |// 2 16 * s 4//// Note: InformationElement.bytes has 'Element ID' and 'Length'// stripped off alreadyprivate void parseRsnElement(InformationElement ie) {ByteBuffer buf = ByteBuffer.wrap(ie.bytes).order(ByteOrder.LITTLE_ENDIAN);try {// versionif (buf.getShort() != RSNE_VERSION) {// incorrect versionreturn;}// found the RSNE IE, hence start building the capability stringprotocol.add(ScanResult.PROTOCOL_WPA2);// group data cipher suitegroupCipher.add(parseRsnCipher(buf.getInt()));// pairwise cipher suite countshort cipherCount = buf.getShort();ArrayList rsnPairwiseCipher = new ArrayList<>();// pairwise cipher suite listfor (int i = 0; i < cipherCount; i++) {rsnPairwiseCipher.add(parseRsnCipher(buf.getInt()));}pairwiseCipher.add(rsnPairwiseCipher);// AKM// AKM suite countshort akmCount = buf.getShort();ArrayList rsnKeyManagement = new ArrayList<>();for (int i = 0; i < akmCount; i++) {int akm = buf.getInt();switch (akm) {case WPA2_AKM_EAP:rsnKeyManagement.add(ScanResult.KEY_MGMT_EAP);break;case WPA2_AKM_PSK:rsnKeyManagement.add(ScanResult.KEY_MGMT_PSK);break;case WPA2_AKM_FT_EAP:rsnKeyManagement.add(ScanResult.KEY_MGMT_FT_EAP);break;case WPA2_AKM_FT_PSK:rsnKeyManagement.add(ScanResult.KEY_MGMT_FT_PSK);break;case WPA2_AKM_EAP_SHA256:rsnKeyManagement.add(ScanResult.KEY_MGMT_EAP_SHA256);break;case WPA2_AKM_PSK_SHA256:rsnKeyManagement.add(ScanResult.KEY_MGMT_PSK_SHA256);break;default:// do nothingbreak;}}// Default AKMif (rsnKeyManagement.isEmpty()) {rsnKeyManagement.add(ScanResult.KEY_MGMT_EAP);}keyManagement.add(rsnKeyManagement);} catch (BufferUnderflowException e) {Log.e("IE_Capabilities", "Couldn't parse RSNE, buffer underflow");}}
这边不怎么看的懂了,但大概就是将加密方式解析出来了
然后生成Capabilities显示成我们常见的加密方式
/*** Build the ScanResult.capabilities String.** @return security string that mirrors what wpa_supplicant generates*/public String generateCapabilitiesString() {String capabilities = "";// private Beacon without an RSNE or WPA IE, hence WEP0boolean isWEP = (protocol.isEmpty()) && isPrivacy;if (isWEP) {capabilities += "[WEP]";}for (int i = 0; i < protocol.size(); i++) {capabilities += "[" + protocolToString(protocol.get(i));if (i < keyManagement.size()) {for (int j = 0; j < keyManagement.get(i).size(); j++) {capabilities += ((j == 0) ? "-" : "+")+ keyManagementToString(keyManagement.get(i).get(j));}}if (i < pairwiseCipher.size()) {for (int j = 0; j < pairwiseCipher.get(i).size(); j++) {capabilities += ((j == 0) ? "-" : "+")+ cipherToString(pairwiseCipher.get(i).get(j));}}capabilities += "]";}if (isESS) {capabilities += "[ESS]";}if (isWPS) {capabilities += "[WPS]";}return capabilities;}}private String keyManagementToString(int akm) {switch (akm) {case ScanResult.KEY_MGMT_NONE:return "None";case ScanResult.KEY_MGMT_PSK:return "PSK";case ScanResult.KEY_MGMT_EAP:return "EAP";case ScanResult.KEY_MGMT_FT_EAP:return "FT/EAP";case ScanResult.KEY_MGMT_FT_PSK:return "FT/PSK";case ScanResult.KEY_MGMT_EAP_SHA256:return "EAP-SHA256";case ScanResult.KEY_MGMT_PSK_SHA256:return "PSK-SHA256";default:return "?";}}
看下AccessPoint怎么获取加密方式的
private static int getSecurity(ScanResult result) {if (result.capabilities.contains("WEP")) {return SECURITY_WEP;} else if (result.capabilities.contains("PSK")) {return SECURITY_PSK;} else if (result.capabilities.contains("EAP")) {return SECURITY_EAP;}return SECURITY_NONE;}
可以看到是和上面对应的,虽然这边就是简单的判断是否包含字符串。
2.总结
看了个大概,加密方式大概是从扫描结果中的ie解析出来放在一个叫做capabilities里的,后续上面判断加密方式就简单判断下是否包含特定加密方式的字符串就好了。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
