So, I’m trying to create a Windows setup wizard for simply entering Wifi credentials on a claimed photon and am hitting some snags. I have looked at the source for the iOS and Android setup wizards and it seems pretty straight forward, but for some reason I am having some issues. Here is where things stand:
I put the device into listening mode (it is blinking blue and broadcasting its SSID)
I am able to send commands and receive responses (e.g scan command, device id command, etc.) without any issues
This is where the wheels come off. I am able to send the wifi connection credentials, but don’t get back a response code. Instead, I get back “\n\n” but no response follows.
I am then able to send a “connect to AP” command and receive a response code of 0, indicating all is well, but it never connects and never exits listening mode. After reading some other posts, I have tried hitting reset after receiving the connection response, but to no avail.
A couple more points. I am only interested in setting the wifi credentials. The device is already claimed and the claim code in the "device id " response is 1. I am starting to suspect that it may have something to do with me not having sent a claim code to the device prior to trying to establish a connection, but I’m unsure. I don’t want to use the CLI because I would like to run this on a customer’s computer without installing unnecessary software.
Has anyone had a similar issues or have any ideas as to where I’m going off the rails here? Any help would be greatly appreciated!
I am currently just sending the passcode in plain text. The iOS SDK does this if as a fallback, so I believe it should work without RSA encrypting the passcode? The reason for doing this twofold. First, I am trying to limit my bug surface and can tackle that afterward. Lastly, I am unsure of the format of the public key. It must have a modulus and an exponent, but I haven't started to dig into where one ends and the other begins.
Regardless, I also wondered if this might be part of the problem and so enabled an open guest network and had identical results.
I see. i don’t know if it works unencrypted - if i remember right it didn’t when i tried to do it in .net (otherwise i would’ve spared myself all the trouble in this thread
@smnnekho I can’t believe I didn’t come across this in all of my searching . This looks incredibly promising. I will try it out tonight to see if I can get things moving. I really can’t thank you enough, especially after smashing my head against the wall for the last few days!
The first code i posted is as simple as possible (in vb.net though - but easy to convert) and it worked. so that should definatly get you started:
Imports System.Net
Imports System.Runtime.InteropServices
Imports System.Security.Cryptography
Imports System.Text
Imports System.Web.Script.Serialization
Imports PCLCrypto
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim jss As New JavaScriptSerializer
Dim devID = jss.Deserialize(Of device_idResponse)(getData(RequestType.DeviceID))
Dim pubKey = jss.Deserialize(Of publicKeyResponse)(getData(RequestType.PublicKey))
Debug.WriteLine(String.Format("Device ID: {0}", devID.id))
Debug.WriteLine(String.Format("Public Key: {0} | {1}", pubKey.b, pubKey.r))
Dim d = System.Text.Encoding.UTF8.GetBytes(pubKey.b)
Dim EncryptedKey = EncryptString(">password_here<", StringToByteArray(pubKey.b))
Debug.WriteLine(EncryptedKey.ToString)
Dim EncryptedKeyString = ByteArrayToString(EncryptedKey)
Debug.WriteLine(String.Format("Encrypted PWD: {0}", EncryptedKeyString))
Debug.WriteLine("Scanned APs:")
Dim scans = jss.Deserialize(Of scanAPResult)(getData(RequestType.ScannedWifi))
For Each i In scans.scans
Debug.WriteLine(i.ssid)
If i.ssid.ToLower.Contains("office") Then ' just testing out!
Using client As New WebClient
Dim apData As New configAP
With apData
.ch = i.ch
.idx = 0
.pwd = EncryptedKeyString
.sec = i.sec
.ssid = i.ssid
End With
Dim apDataStr = jss.Serialize(apData)
client.UploadString("http://192.168.0.1/configure-ap", apDataStr)
System.Threading.Thread.Sleep(1000)
Dim connectData As New connectAP
connectData.idx = 0
client.UploadString("http://192.168.0.1/connect-ap", jss.Serialize(connectData))
End Using
End If
Next
End Sub
Public Function EncryptString(inputString As String, keyBuffer As Byte()) As Byte()
Dim algorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.AsymmetricAlgorithm.RsaPkcs1)
Dim publicKey = algorithm.ImportPublicKey(keyBuffer)
Dim plainBuffer = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(inputString, Encoding.UTF8)
Return WinRTCrypto.CryptographicEngine.Encrypt(publicKey, plainBuffer)
End Function
Private Function getData(req As RequestType) As String
Using client As New WebClient
Select Case req
Case RequestType.DeviceID
Return client.DownloadString("http://192.168.0.1/device-id")
Case RequestType.PublicKey
Return client.DownloadString("http://192.168.0.1/public-key")
Case RequestType.ScannedWifi
Return client.DownloadString("http://192.168.0.1/scan-ap")
Case Else
Return ""
End Select
End Using
End Function
Public Shared Function StringToByteArray(hex As String) As Byte()
Return Enumerable.Range(0, hex.Length).Where(Function(x) x Mod 2 = 0).[Select](Function(x) Convert.ToByte(hex.Substring(x, 2), 16)).ToArray()
End Function
Public Shared Function ByteArrayToString(ba As Byte()) As String
Dim hex As New StringBuilder(ba.Length * 2)
For Each b As Byte In ba
hex.AppendFormat("{0:x2}", b)
Next
Return hex.ToString()
End Function
End Class
Public Enum RequestType
DeviceID
PublicKey
ScannedWifi
End Enum
<Serializable> Public Class device_idResponse
Public Property id As String
Public Property c As String
End Class
<Serializable> Public Class publicKeyResponse
Public Property b As String
Public Property r As Integer
End Class
<Serializable> Public Class scanAPResult
Public Property scans As ObjectModel.Collection(Of Scan)
End Class
<Serializable> Public Class Scan
Public Property ssid As String
Public Property rssi As Integer
Public Property sec As Integer
Public Property ch As Integer
Public Property mdr As Integer
End Class
Public Class configAP
Public Property idx As Integer
Public Property ssid As String
Public Property sec As Integer
Public Property ch As Integer
Public Property pwd As String
End Class
Public Class connectAP
Public Property idx As Integer
End Class
I have tried the code, but am still not having any luck. I get a white flash now, but that’s about it. Using a webclient I am also getting a response code for the “configure-ap” command (which is 0 indicating success).
After running the key bytes and plaintext passcode through the encryption function, I am also getting a key length of 258 like in the linked post, but unfortunately trimming the first two characters from the ciphertext is not leading to success in my case.
Dim EncryptedKey = EncryptString(">password_here<", StringToByteArray(pubKey.b))
Public Function EncryptString(inputString As String, keyBuffer As Byte()) As Byte()
Dim algorithm = WinRTCrypto.AsymmetricKeyAlgorithmProvider.OpenAlgorithm(PCLCrypto.AsymmetricAlgorithm.RsaPkcs1)
Dim publicKey = algorithm.ImportPublicKey(keyBuffer)
Dim plainBuffer = WinRTCrypto.CryptographicBuffer.ConvertStringToBinary(inputString, Encoding.UTF8)
Return WinRTCrypto.CryptographicEngine.Encrypt(publicKey, plainBuffer)
End Function
and converting the ByteArray.
Dim EncryptedKeyString = ByteArrayToString(EncryptedKey)
Public Shared Function ByteArrayToString(ba As Byte()) As String
Dim hex As New StringBuilder(ba.Length * 2)
For Each b As Byte In ba
hex.AppendFormat("{0:x2}", b)
Next
Return hex.ToString()
End Function
in vb.net. which language/runtime are you trying to use anyways?