Unity3d c#으로 https통신하기

유니티에서 http/https 통신하는 방법은 어셋을 사용하지 않는 선에서 크게 3가지 존재한다.

1. WWW

2. UnityWebRequest

3. HttpWebRequest


3가지 모두 HTTP 통신에는 문제가 없다. 

하지만 HTTPS에서는 문제가 발생한다.

어떤 문제가 있었는지 정리해 본다.


인증서 만드는 법은 여기서

인증서 만들 때, CN값을 MERONG으로 입력해 뒀다.


Unity3d에서 https post로 통신하는 테스트 코드

IEnumerator TestHttpPost(string uri, byte[] bodyData) { //////////////////////////////////////////////////////////////////////////////////////////////////////////// // for WWW //////////////////////////////////////////////////////////////////////////////////////////////////////////// WWW www = new WWW(uri, bodyData); yield return www; Debug.Log("www:" + www.error + " responsed data len:" + www.bytesDownloaded); //////////////////////////////////////////////////////////////////////////////////////////////////////////// // for UnityWebRequest //////////////////////////////////////////////////////////////////////////////////////////////////////////// UnityWebRequest unityWebRequest = UnityWebRequest.Post(uri, Encoding.ASCII.GetString(bodyData)); //UnityWebRequest unityWebRequest = UnityWebRequest.Put(uri, Encoding.ASCII.GetString(bodyData)); yield return unityWebRequest.Send(); if (unityWebRequest.isError) { Debug.Log("UnityWebRequest:" + unityWebRequest.error); } else { Debug.Log("UnityWebRequest: responsed data len:" + unityWebRequest.downloadedBytes); } //////////////////////////////////////////////////////////////////////////////////////////////////////////// // for HttpWebRequest //////////////////////////////////////////////////////////////////////////////////////////////////////////// ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri); httpWebRequest.Method = "POST"; httpWebRequest.ContentType = "application/octet-stream"; httpWebRequest.ContentLength = bodyData.Length; httpWebRequest.BeginGetRequestStream(new AsyncCallback((iar) =>{ try { using (Stream stream = httpWebRequest.EndGetRequestStream(iar)) { if (bodyData != null) { stream.Write(bodyData, 0, bodyData.Length); } stream.Close(); httpWebRequest.BeginGetResponse(new AsyncCallback((IAsyncResult iarres) =>{ try { using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.EndGetResponse(iarres)) { using (StreamReader streamReader = new StreamReader(response.GetResponseStream())) { Debug.Log("HttpWebRequest: responsed data len:" + streamReader.ReadToEnd().Length); } response.Close(); } } catch (Exception e) { Debug.Log(e); } }), null); } } catch (Exception e) { Debug.Log(e); } }), null); } void Start() { StartCoroutine(TestHttpPost("https://localhost:8443" + "/hellomvc2/", new byte[] { 61, 61 })); }

WWW에서 오류발생

www:SSL: certificate subject name 'MERONG' does not match target host name 'localhost' responsed data len:0 UnityEngine.Debug:Log(Object) <TestHttpPost>c__Iterator0:MoveNext() (at Assets/Scripts/UIs/LoginGUI.cs:169) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

UnityWebRequest 오류발생

UnityWebRequest:Unknown Error UnityEngine.Debug:Log(Object) <TestHttpPost>c__Iterator0:MoveNext() (at Assets/Scripts/UIs/LoginGUI.cs:159) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)

HttpWebRequest에서 예외발생

System.Net.WebException: Error getting response stream (Write: The authentication or decryption has failed.): SendFailure ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed. at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at System.Net.HttpWebRequest.EndGetRequestStream (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 at LoginGUI+<TestHttpPost>c__Iterator0+<TestHttpPost>c__AnonStorey1.<>m__0 (IAsyncResult iar) [0x00009] in G:\project\BlueFin\bluefin_dev\server\unity3d_workspace\CS_Sample\Sample\Assets\Scripts\UIs\LoginGUI.cs:115 UnityEngine.Debug:Log(Object) <TestHttpPost>c__AnonStorey1:<>m__0(IAsyncResult) (at Assets/Scripts/UIs/LoginGUI.cs:148) System.Net.WebConnection:InitConnection(Object)


WWW에서 발생한 오류 

www:SSL: certificate subject name 'MERONG' does not match target host name 'localhost'

인증서 CN 값과 연결하려는 호스트 이름이 다르단다.

인증서 만들 때, localhost 를 입력하고 다시 실행해 보자.

www: responsed data len:134 UnityWebRequest: responsed data len:134 System.Net.WebException: Error getting response stream (Write: The authentication or decryption has failed.): SendFailure ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed. at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00000] in <filename unknown>:0 at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 --- End of inner exception stack trace --- at System.Net.HttpWebRequest.EndGetRequestStream (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 at LoginGUI+<TestHttpPost>c__Iterator0+<TestHttpPost>c__AnonStorey1.<>m__0 (IAsyncResult iar) [0x00009] in G:\project\BlueFin\bluefin_dev\server\unity3d_workspace\CS_Sample\Sample\Assets\Scripts\UIs\LoginGUI.cs:142 UnityEngine.Debug:Log(Object) <TestHttpPost>c__AnonStorey1:<>m__0(IAsyncResult) (at Assets/Scripts/UIs/LoginGUI.cs:175) System.Net.WebConnection:InitConnection(Object)

이번엔,

WWW과 UnityWebRequest는 정상이지만,

HttpWebRequest 여전히 같은 오류가 난다. 

인증서 CN값이 달라서 오류가 발생한게 아니었다.

HTTPS 통신 성공 이후에 테스트 해 본거지만,

ServicePointManager.ServerCertificateValidationCallback 리턴값을 true로 해줬기 때문에.

인증서 CN값과 호스트 이름이 달라도 동작했다.


이 문제는,

SSL 핸드세이킹 중 복호화 실패 오류인데,

정말 이 문제로 고생 많이 했다. CA로 부터 인증을 못받아서 그런가 싶어

openssl로 CA 인증서도 만들어 봤지만 결과는 동일했다.


다행히,

openssl을 만지는 과정에서 https 사이트에 연결테스트를 해볼 수 있었는데, 거기서 차이점을 발견하게 되었다.

openssl로 localhost와 google를 연결해보았다.

$ openssl s_client -connect localhost:8443 -tls1 Loading 'screen' into random state - done CONNECTED(00000188) depth=0 /C=kr/ST=seoul/L=seoul/O=company/OU=team/CN=localhost verify error:num=18:self signed certificate verify return:1 depth=0 /C=kr/ST=seoul/L=seoul/O=company/OU=team/CN=localhost verify return:1 --- Certificate chain 0 s:/C=kr/ST=seoul/L=seoul/O=company/OU=team/CN=localhost i:/C=kr/ST=seoul/L=seoul/O=company/OU=team/CN=localhost --- Server certificate -----BEGIN CERTIFICATE----- MIIDYzCCAkugAwIBAgIELIf7OjANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQGEwJr cjEOMAwGA1UECBMFc2VvdWwxDjAMBgNVBAcTBXNlb3VsMRAwDgYDVQQKEwdjb21w YW55MQ0wCwYDVQQLEwR0ZWFtMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTcwNDIx MDYwMTQ5WhcNMjcwNDE5MDYwMTQ5WjBiMQswCQYDVQQGEwJrcjEOMAwGA1UECBMF c2VvdWwxDjAMBgNVBAcTBXNlb3VsMRAwDgYDVQQKEwdjb21wYW55MQ0wCwYDVQQL EwR0ZWFtMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDigSpCI32KkfyIIff1bFe8vBkrxc+sVcCrlLLqach4tBcVn9Ef 3+IS4D0+ou78tijo+zFMlchtHMFTIcVZjwpLbvhR3VW1K1Hu6KGy+wEtB4jEleh1 4a0OkpQUKbiopAG5Hp7jQ77SSsr5M9NLTZuGRlDbylW9ZfkjgQ+nuGTbySrAUPmM Q6d098q59n/nnvVuSci74RPZ1XEC/OLRsr5/yh5hmzNK3rI75A4r0QEiX9DK605P TZtzGa/NOJiYIusuJuOzaJRfp8WewPJxAiWh4Y9Eh2+h+29SfXoN0yvhmrG+s8SZ lpHK/7/cwHsi6ftCbsE+tUz5dtfXl3dsgqsXAgMBAAGjITAfMB0GA1UdDgQWBBQK h8+3q7PMasozo3uTh3j44+TvozANBgkqhkiG9w0BAQsFAAOCAQEAhEIBdkkP7n1z oS9O8JuaCkhFzurk8gh2aImhAPCyEMgPtG36+LKxsjrxicOmUniqbm6E817u/4l9 yVyslOzNOgC4K+acg//JcSfVOz6yVjJuoaeTDPQ9QtKZzNwex1On6OSIR83Aicru PcAxkicupj7PHQ2mPlLeevCX00ZyInX5Xaqa7CIffeM8b+ZgCt+s/P7H/MZm198V pAPcQgY9vkX+wv9UHNDPZEkjfE5wNWzEPbpo3EzCG4xfpJITGDEAbsQiEVfBQiAW bnlEKoTnlImF+hOLj0esqvtqH45R9nwR/IXTJP4skz5ZwwxqDtA+klB4Exqf0qhO DGmUUE37Vg== -----END CERTIFICATE----- subject=/C=kr/ST=seoul/L=seoul/O=company/OU=team/CN=localhost issuer=/C=kr/ST=seoul/L=seoul/O=company/OU=team/CN=localhost --- No client certificate CA names sent --- SSL handshake has read 1548 bytes and written 292 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA Server public key is 2048 bit Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES128-SHA Session-ID: 58F9A34D462F3565E4A1B8354E756B1A690EEE71D6F8364BD77100ADA13FCB71 Session-ID-ctx: Master-Key: 4FEF0288D2D823960397C964A7D360C79F38AD840CFA27C312530EDD9097B89C A51950A477E16CFE86E8429166DFBA72 Key-Arg : None Start Time: 1492755277 Timeout : 7200 (sec) Verify return code: 18 (self signed certificate) --- $ openssl s_client -connect google.com:443 -tls1 Loading 'screen' into random state - done CONNECTED(00000188) depth=2 /C=US/O=GeoTrust Inc./CN=GeoTrust Global CA verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com i:/C=US/O=Google Inc/CN=Google Internet Authority G2 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2 i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority --- Server certificate -----BEGIN CERTIFICATE----- MIIgkjCCH3qgAwIBAgIIPUHY0Fje+9UwDQYJKoZIhvcNAQELBQAwSTELMAkGA1UE BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl cm5ldCBBdXRob3JpdHkgRzIwHhcNMTcwNDEyMTMzMDAxWhcNMTcwNzA1MTMyODAw WjBkMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzETMBEGA1UEAwwKZ29v Z2xlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALef9Jnvrg0F 9KgR3b6/OP8C9k8kXK75uyiNi+E1p/rnfLetVdab8iryadM7Rzbn5tHPUEQDZW/I PBWC97vmA/DFKOBXkBvZJUppXHtchBellktHW/BtSqvMQW6QWAnHNsbcBWioUrd+ 9gI9MNPwQDECLU/dA4qfszn0XOd/ctyNKavbJH4HOm+arET/kmVA67SLccmDoSFf 5aIIJe8Kl5F1KZtn4AWEgcW8j00RKQpdNKrNwYOMrEYJ+C86RHFwNsocK+aRKGNv FbpifWXeBN170xxN9rjjXBobCKy6Z56+qZEwQTXIhW7s0yXpI6AXfZfZAqdJGs29 nADFSLgJttkCAwEAAaOCHWEwgh1dMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEF BQcDAjCCHC0GA1UdEQSCHCQwghwgggpnb29nbGUuY29tggoqLjJtZG4ubmV0gg0q LmFuZHJvaWQuY29tghYqLmFwcGVuZ2luZS5nb29nbGUuY29tghQqLmF1LmRvdWJs ZWNsaWNrLm5ldIILKi5jYy1kdC5jb22CEiouY2xvdWQuZ29vZ2xlLmNvbYIUKi5k ZS5kb3VibGVjbGljay5uZXSCESouZG91YmxlY2xpY2suY29tghEqLmRvdWJsZWNs aWNrLm5ldIIVKi5mbHMuZG91YmxlY2xpY2submV0ghQqLmZyLmRvdWJsZWNsaWNr Lm5ldIIOKi5nY3AuZ3Z0Mi5jb22CFiouZ29vZ2xlLWFuYWx5dGljcy5jb22CCyou Z29vZ2xlLmFjggsqLmdvb2dsZS5hZIILKi5nb29nbGUuYWWCCyouZ29vZ2xlLmFm ggsqLmdvb2dsZS5hZ4ILKi5nb29nbGUuYWyCCyouZ29vZ2xlLmFtggsqLmdvb2ds ZS5hc4ILKi5nb29nbGUuYXSCCyouZ29vZ2xlLmF6ggsqLmdvb2dsZS5iYYILKi5n b29nbGUuYmWCCyouZ29vZ2xlLmJmggsqLmdvb2dsZS5iZ4ILKi5nb29nbGUuYmmC CyouZ29vZ2xlLmJqggsqLmdvb2dsZS5ic4ILKi5nb29nbGUuYnSCCyouZ29vZ2xl LmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUuY2F0ggsqLmdvb2dsZS5jY4ILKi5n b29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdvb2dsZS5jZ4ILKi5nb29nbGUuY2iC CyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIILKi5nb29nbGUuY22CCyouZ29vZ2xl LmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29nbGUuY28uYneCDiouZ29vZ2xlLmNv LmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29nbGUuY28uaHWCDiouZ29vZ2xlLmNv Lmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29nbGUuY28uaW2CDiouZ29vZ2xlLmNv Lmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29nbGUuY28uanCCDiouZ29vZ2xlLmNv Lmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29nbGUuY28ubHOCDiouZ29vZ2xlLmNv Lm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29nbGUuY28ubnqCDiouZ29vZ2xlLmNv LnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29nbGUuY28udWeCDiouZ29vZ2xlLmNv LnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29nbGUuY28udmWCDiouZ29vZ2xlLmNv LnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29nbGUuY28uem2CDiouZ29vZ2xlLmNv Lnp3ggwqLmdvb2dsZS5jb22CDyouZ29vZ2xlLmNvbS5hZoIPKi5nb29nbGUuY29t LmFngg8qLmdvb2dsZS5jb20uYWmCDyouZ29vZ2xlLmNvbS5hcoIPKi5nb29nbGUu Y29tLmF1gg8qLmdvb2dsZS5jb20uYmSCDyouZ29vZ2xlLmNvbS5iaIIPKi5nb29n bGUuY29tLmJugg8qLmdvb2dsZS5jb20uYm+CDyouZ29vZ2xlLmNvbS5icoIPKi5n b29nbGUuY29tLmJ5gg8qLmdvb2dsZS5jb20uYnqCDyouZ29vZ2xlLmNvbS5jboIP Ki5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20uY3WCDyouZ29vZ2xlLmNvbS5j eYIPKi5nb29nbGUuY29tLmRvgg8qLmdvb2dsZS5jb20uZWOCDyouZ29vZ2xlLmNv bS5lZ4IPKi5nb29nbGUuY29tLmV0gg8qLmdvb2dsZS5jb20uZmqCDyouZ29vZ2xl LmNvbS5nZYIPKi5nb29nbGUuY29tLmdogg8qLmdvb2dsZS5jb20uZ2mCDyouZ29v Z2xlLmNvbS5ncoIPKi5nb29nbGUuY29tLmd0gg8qLmdvb2dsZS5jb20uaGuCDyou Z29vZ2xlLmNvbS5pcYIPKi5nb29nbGUuY29tLmptgg8qLmdvb2dsZS5jb20uam+C DyouZ29vZ2xlLmNvbS5raIIPKi5nb29nbGUuY29tLmt3gg8qLmdvb2dsZS5jb20u bGKCDyouZ29vZ2xlLmNvbS5seYIPKi5nb29nbGUuY29tLm1tgg8qLmdvb2dsZS5j b20ubXSCDyouZ29vZ2xlLmNvbS5teIIPKi5nb29nbGUuY29tLm15gg8qLmdvb2ds ZS5jb20ubmGCDyouZ29vZ2xlLmNvbS5uZoIPKi5nb29nbGUuY29tLm5ngg8qLmdv b2dsZS5jb20ubmmCDyouZ29vZ2xlLmNvbS5ucIIPKi5nb29nbGUuY29tLm5ygg8q Lmdvb2dsZS5jb20ub22CDyouZ29vZ2xlLmNvbS5wYYIPKi5nb29nbGUuY29tLnBl gg8qLmdvb2dsZS5jb20ucGeCDyouZ29vZ2xlLmNvbS5waIIPKi5nb29nbGUuY29t LnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29vZ2xlLmNvbS5wcoIPKi5nb29nbGUu Y29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyouZ29vZ2xlLmNvbS5ydYIPKi5nb29n bGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KCDyouZ29vZ2xlLmNvbS5zZ4IPKi5n b29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20uc3aCDyouZ29vZ2xlLmNvbS50aoIP Ki5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5jb20udHKCDyouZ29vZ2xlLmNvbS50 d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2dsZS5jb20udXmCDyouZ29vZ2xlLmNv bS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdvb2dsZS5jb20udm6CCyouZ29vZ2xl LmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUuZGWCCyouZ29vZ2xlLmRqggsqLmdv b2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29vZ2xlLmR6ggsqLmdvb2dsZS5lZYIL Ki5nb29nbGUuZXOCDCouZ29vZ2xlLmV1c4ILKi5nb29nbGUuZmmCCyouZ29vZ2xl LmZtggsqLmdvb2dsZS5mcoIMKi5nb29nbGUuZnJsggsqLmdvb2dsZS5nYYIMKi5n b29nbGUuZ2FsggsqLmdvb2dsZS5nZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmds ggsqLmdvb2dsZS5nbYILKi5nb29nbGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2ds ZS5neYILKi5nb29nbGUuaGuCCyouZ29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5n b29nbGUuaHSCCyouZ29vZ2xlLmh1ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2C CyouZ29vZ2xlLmlugg0qLmdvb2dsZS5pbmZvggsqLmdvb2dsZS5pcYILKi5nb29n bGUuaXKCCyouZ29vZ2xlLmlzggsqLmdvb2dsZS5pdIIOKi5nb29nbGUuaXQuYW+C CyouZ29vZ2xlLmplggsqLmdvb2dsZS5qb4INKi5nb29nbGUuam9ic4ILKi5nb29n bGUuanCCCyouZ29vZ2xlLmtnggsqLmdvb2dsZS5raYILKi5nb29nbGUua3qCCyou Z29vZ2xlLmxhggsqLmdvb2dsZS5saYILKi5nb29nbGUubGuCCyouZ29vZ2xlLmx0 ggsqLmdvb2dsZS5sdYILKi5nb29nbGUubHaCCyouZ29vZ2xlLm1kggsqLmdvb2ds ZS5tZYILKi5nb29nbGUubWeCCyouZ29vZ2xlLm1rggsqLmdvb2dsZS5tbIILKi5n b29nbGUubW6CCyouZ29vZ2xlLm1zggsqLmdvb2dsZS5tdYILKi5nb29nbGUubXaC CyouZ29vZ2xlLm13ggsqLmdvb2dsZS5uZYIOKi5nb29nbGUubmUuanCCDCouZ29v Z2xlLm5ldIILKi5nb29nbGUubmeCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4IL Ki5nb29nbGUubnKCCyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29v Z2xlLnBrggsqLmdvb2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsq Lmdvb2dsZS5wdIILKi5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5y dYILKi5nb29nbGUucneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29n bGUuc2iCCyouZ29vZ2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyou Z29vZ2xlLnNuggsqLmdvb2dsZS5zb4ILKi5nb29nbGUuc3KCCyouZ29vZ2xlLnN0 ggsqLmdvb2dsZS50ZIIMKi5nb29nbGUudGVsggsqLmdvb2dsZS50Z4ILKi5nb29n bGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29nbGUudG6CCyou Z29vZ2xlLnRvggsqLmdvb2dsZS50dIILKi5nb29nbGUudWGCCyouZ29vZ2xlLnVz ggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1ggsqLmdvb2ds ZS53c4ISKi5nb29nbGVhZGFwaXMuY29tghUqLmdvb2dsZWFkc3NlcnZpbmcuY26C DyouZ29vZ2xlYXBpcy5jboIUKi5nb29nbGVjb21tZXJjZS5jb22CFiouZ29vZ2xl dXNlcmNvbnRlbnQuY26CESouZ29vZ2xldmlkZW8uY29tggwqLmdzdGF0aWMuY26C DSouZ3N0YXRpYy5jb22CCiouZ3Z0MS5jb22CCiouZ3Z0Mi5jb22CFCouanAuZG91 YmxlY2xpY2submV0ghQqLm1ldHJpYy5nc3RhdGljLmNvbYIUKi51ay5kb3VibGVj bGljay5uZXSCDCoudXJjaGluLmNvbYIQKi51cmwuZ29vZ2xlLmNvbYIWKi55b3V0 dWJlLW5vY29va2llLmNvbYINKi55b3V0dWJlLmNvbYIWKi55b3V0dWJlZWR1Y2F0 aW9uLmNvbYILKi55dGltZy5jb22CFWFkLm1vLmRvdWJsZWNsaWNrLm5ldIIaYW5k cm9pZC5jbGllbnRzLmdvb2dsZS5jb22CC2FuZHJvaWQuY29tghtkZXZlbG9wZXIu YW5kcm9pZC5nb29nbGUuY26CHGRldmVsb3BlcnMuYW5kcm9pZC5nb29nbGUuY26C D2RvdWJsZWNsaWNrLmNvbYIPZG91YmxlY2xpY2submV0ggRnLmNvggZnb28uZ2yC FGdvb2dsZS1hbmFseXRpY3MuY29tgglnb29nbGUuYWOCCWdvb2dsZS5hZIIJZ29v Z2xlLmFlgglnb29nbGUuYWaCCWdvb2dsZS5hZ4IJZ29vZ2xlLmFsgglnb29nbGUu YW2CCWdvb2dsZS5hc4IJZ29vZ2xlLmF0gglnb29nbGUuYXqCCWdvb2dsZS5iYYIJ Z29vZ2xlLmJlgglnb29nbGUuYmaCCWdvb2dsZS5iZ4IJZ29vZ2xlLmJpgglnb29n bGUuYmqCCWdvb2dsZS5ic4IJZ29vZ2xlLmJ0gglnb29nbGUuYnmCCWdvb2dsZS5j YYIKZ29vZ2xlLmNhdIIJZ29vZ2xlLmNjgglnb29nbGUuY2SCCWdvb2dsZS5jZoIJ Z29vZ2xlLmNngglnb29nbGUuY2iCCWdvb2dsZS5jaYIJZ29vZ2xlLmNsgglnb29n bGUuY22CCWdvb2dsZS5jboIMZ29vZ2xlLmNvLmFvggxnb29nbGUuY28uYneCDGdv b2dsZS5jby5ja4IMZ29vZ2xlLmNvLmNyggxnb29nbGUuY28uaHWCDGdvb2dsZS5j by5pZIIMZ29vZ2xlLmNvLmlsggxnb29nbGUuY28uaW2CDGdvb2dsZS5jby5pboIM Z29vZ2xlLmNvLmplggxnb29nbGUuY28uanCCDGdvb2dsZS5jby5rZYIMZ29vZ2xl LmNvLmtyggxnb29nbGUuY28ubHOCDGdvb2dsZS5jby5tYYIMZ29vZ2xlLmNvLm16 ggxnb29nbGUuY28ubnqCDGdvb2dsZS5jby50aIIMZ29vZ2xlLmNvLnR6ggxnb29n bGUuY28udWeCDGdvb2dsZS5jby51a4IMZ29vZ2xlLmNvLnV6ggxnb29nbGUuY28u dmWCDGdvb2dsZS5jby52aYIMZ29vZ2xlLmNvLnphggxnb29nbGUuY28uem2CDGdv b2dsZS5jby56d4INZ29vZ2xlLmNvbS5hZoINZ29vZ2xlLmNvbS5hZ4INZ29vZ2xl LmNvbS5haYINZ29vZ2xlLmNvbS5hcoINZ29vZ2xlLmNvbS5hdYINZ29vZ2xlLmNv bS5iZIINZ29vZ2xlLmNvbS5iaIINZ29vZ2xlLmNvbS5iboINZ29vZ2xlLmNvbS5i b4INZ29vZ2xlLmNvbS5icoINZ29vZ2xlLmNvbS5ieYINZ29vZ2xlLmNvbS5ieoIN Z29vZ2xlLmNvbS5jboINZ29vZ2xlLmNvbS5jb4INZ29vZ2xlLmNvbS5jdYINZ29v Z2xlLmNvbS5jeYINZ29vZ2xlLmNvbS5kb4INZ29vZ2xlLmNvbS5lY4INZ29vZ2xl LmNvbS5lZ4INZ29vZ2xlLmNvbS5ldIINZ29vZ2xlLmNvbS5maoINZ29vZ2xlLmNv bS5nZYINZ29vZ2xlLmNvbS5naIINZ29vZ2xlLmNvbS5naYINZ29vZ2xlLmNvbS5n coINZ29vZ2xlLmNvbS5ndIINZ29vZ2xlLmNvbS5oa4INZ29vZ2xlLmNvbS5pcYIN Z29vZ2xlLmNvbS5qbYINZ29vZ2xlLmNvbS5qb4INZ29vZ2xlLmNvbS5raIINZ29v Z2xlLmNvbS5rd4INZ29vZ2xlLmNvbS5sYoINZ29vZ2xlLmNvbS5seYINZ29vZ2xl LmNvbS5tbYINZ29vZ2xlLmNvbS5tdIINZ29vZ2xlLmNvbS5teIINZ29vZ2xlLmNv bS5teYINZ29vZ2xlLmNvbS5uYYINZ29vZ2xlLmNvbS5uZoINZ29vZ2xlLmNvbS5u Z4INZ29vZ2xlLmNvbS5uaYINZ29vZ2xlLmNvbS5ucIINZ29vZ2xlLmNvbS5ucoIN Z29vZ2xlLmNvbS5vbYINZ29vZ2xlLmNvbS5wYYINZ29vZ2xlLmNvbS5wZYINZ29v Z2xlLmNvbS5wZ4INZ29vZ2xlLmNvbS5waIINZ29vZ2xlLmNvbS5wa4INZ29vZ2xl LmNvbS5wbIINZ29vZ2xlLmNvbS5wcoINZ29vZ2xlLmNvbS5weYINZ29vZ2xlLmNv bS5xYYINZ29vZ2xlLmNvbS5ydYINZ29vZ2xlLmNvbS5zYYINZ29vZ2xlLmNvbS5z YoINZ29vZ2xlLmNvbS5zZ4INZ29vZ2xlLmNvbS5zbIINZ29vZ2xlLmNvbS5zdoIN Z29vZ2xlLmNvbS50aoINZ29vZ2xlLmNvbS50boINZ29vZ2xlLmNvbS50coINZ29v Z2xlLmNvbS50d4INZ29vZ2xlLmNvbS51YYINZ29vZ2xlLmNvbS51eYINZ29vZ2xl LmNvbS52Y4INZ29vZ2xlLmNvbS52ZYINZ29vZ2xlLmNvbS52boIJZ29vZ2xlLmN2 gglnb29nbGUuY3qCCWdvb2dsZS5kZYIJZ29vZ2xlLmRqgglnb29nbGUuZGuCCWdv b2dsZS5kbYIJZ29vZ2xlLmR6gglnb29nbGUuZWWCCWdvb2dsZS5lc4IKZ29vZ2xl LmV1c4IJZ29vZ2xlLmZpgglnb29nbGUuZm2CCWdvb2dsZS5mcoIKZ29vZ2xlLmZy bIIJZ29vZ2xlLmdhggpnb29nbGUuZ2Fsgglnb29nbGUuZ2WCCWdvb2dsZS5nZ4IJ Z29vZ2xlLmdsgglnb29nbGUuZ22CCWdvb2dsZS5ncIIJZ29vZ2xlLmdygglnb29n bGUuZ3mCCWdvb2dsZS5oa4IJZ29vZ2xlLmhugglnb29nbGUuaHKCCWdvb2dsZS5o dIIJZ29vZ2xlLmh1gglnb29nbGUuaWWCCWdvb2dsZS5pbYIJZ29vZ2xlLmluggtn b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXKCCWdvb2dsZS5pc4IJZ29v Z2xlLml0ggxnb29nbGUuaXQuYW+CCWdvb2dsZS5qZYIJZ29vZ2xlLmpvggtnb29n bGUuam9ic4IJZ29vZ2xlLmpwgglnb29nbGUua2eCCWdvb2dsZS5raYIJZ29vZ2xl Lmt6gglnb29nbGUubGGCCWdvb2dsZS5saYIJZ29vZ2xlLmxrgglnb29nbGUubHSC CWdvb2dsZS5sdYIJZ29vZ2xlLmx2gglnb29nbGUubWSCCWdvb2dsZS5tZYIJZ29v Z2xlLm1ngglnb29nbGUubWuCCWdvb2dsZS5tbIIJZ29vZ2xlLm1ugglnb29nbGUu bXOCCWdvb2dsZS5tdYIJZ29vZ2xlLm12gglnb29nbGUubXeCCWdvb2dsZS5uZYIM Z29vZ2xlLm5lLmpwggpnb29nbGUubmV0gglnb29nbGUubmeCCWdvb2dsZS5ubIIJ Z29vZ2xlLm5vgglnb29nbGUubnKCCWdvb2dsZS5udYINZ29vZ2xlLm9mZi5haYIJ Z29vZ2xlLnBrgglnb29nbGUucGyCCWdvb2dsZS5wboIJZ29vZ2xlLnBzgglnb29n bGUucHSCCWdvb2dsZS5yb4IJZ29vZ2xlLnJzgglnb29nbGUucnWCCWdvb2dsZS5y d4IJZ29vZ2xlLnNjgglnb29nbGUuc2WCCWdvb2dsZS5zaIIJZ29vZ2xlLnNpggln b29nbGUuc2uCCWdvb2dsZS5zbYIJZ29vZ2xlLnNugglnb29nbGUuc2+CCWdvb2ds ZS5zcoIJZ29vZ2xlLnN0gglnb29nbGUudGSCCmdvb2dsZS50ZWyCCWdvb2dsZS50 Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRuggln b29nbGUudG+CCWdvb2dsZS50dIIJZ29vZ2xlLnVhgglnb29nbGUudXOCCWdvb2ds ZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53c4ISZ29vZ2xlY29t bWVyY2UuY29tggtnc3RhdGljLmNvbYIYc291cmNlLmFuZHJvaWQuZ29vZ2xlLmNu ggp1cmNoaW4uY29tggp3d3cuZ29vLmdsggh5b3V0dS5iZYILeW91dHViZS5jb22C FHlvdXR1YmVlZHVjYXRpb24uY29tMGgGCCsGAQUFBwEBBFwwWjArBggrBgEFBQcw AoYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcyLmNydDArBggrBgEFBQcwAYYf aHR0cDovL2NsaWVudHMxLmdvb2dsZS5jb20vb2NzcDAdBgNVHQ4EFgQUPQcNoAjb AaFeLXaduMux3LauOlEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBRK3QYWG7z2 aLV29YG2u2IaulqBLzAhBgNVHSAEGjAYMAwGCisGAQQB1nkCBQEwCAYGZ4EMAQIC MDAGA1UdHwQpMCcwJaAjoCGGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5j cmwwDQYJKoZIhvcNAQELBQADggEBAJf7X+zcJzFGTH5aKJuP7D1DkBa757RB8Gkh B+Y6q1OUWoKlO9GsdSYmZw01t3LB+OjI+B4fKn3S4XwDjiEHB5fw3g9btZD+Nu0H mMIW3/1pPnc05aWoB9J3fc0yrX+Sczj5HaroYJgyjrr5AaPdaJmR0JLzdw9et4kZ OELuRZpYOQulkciGogOlwbP/gC3MzEoKXJfQaJ6OK8D92PvnqTzAzCxLPuaOinFa WgSO+Vk0tRzKcFYRJB2VQng8gmFzkQH9tVXLw4lqjSf8nHXLry4sNaZgUGiGSxKE JhLO72lIz8k90hHn4KPHQF4fWCVIiVU6dGZeQSfGuhISjaWaou8= -----END CERTIFICATE----- subject=/C=US/ST=California/L=Mountain View/O=Google Inc/CN=google.com issuer=/C=US/O=Google Inc/CN=Google Internet Authority G2 --- No client certificate CA names sent --- SSL handshake has read 10572 bytes and written 420 bytes --- New, TLSv1/SSLv3, Cipher is AES128-SHA Server public key is 2048 bit Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : AES128-SHA Session-ID: Session-ID-ctx: Master-Key: BA2CBFF9CC73E8D62838CBB95F681DB9CFDBD58443668486245DEDB571C8B6EC 3B72E90BB7A35B6E78B6B09E31A27F8B Key-Arg : None TLS session ticket lifetime hint: 100800 (seconds) TLS session ticket: 0000 - 52 ec 05 c8 ac 58 4c be-9f e7 df b7 5f db 2e 87 R....XL....._... 0010 - 8b c3 f2 18 31 43 e6 4c-63 de 0a 5d fa 0d 71 6b ....1C.Lc..]..qk 0020 - 56 8e c2 fe 98 db 25 b2-f1 66 a6 fa 39 86 1c b0 V.....%..f..9... 0030 - 04 de bb ba 82 20 f8 02-73 c8 a9 05 b0 ba 3b 85 ..... ..s.....;. 0040 - 12 dd ad bb 7d 1a 8d 5b-c3 35 0f 93 6e 8b 96 e2 ....}..[.5..n... 0050 - 0a 52 ab c1 f0 3d 77 3a-1b bd 45 cf 4a 7e 00 68 .R...=w:..E.J~.h 0060 - 6f 06 e4 9e a1 e4 1c a3-79 e7 87 5c 3c c4 11 f7 o.......y..\<... 0070 - 2f d8 95 cf 1b 79 1a 8a-b1 2d 27 5a 6e 3a 5d 90 /....y...-'Zn:]. 0080 - 6b 5e a8 37 a9 61 06 df-54 4d 35 f0 2c d7 bd ae k^.7.a..TM5.,... 0090 - 53 19 54 00 05 0b 94 ab-b3 86 e3 21 6d dd 87 5c S.T........!m..\ 00a0 - 79 a4 bb 75 y..u Start Time: 1492755701 Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate) ---

SSL Cipher값이 

localhost는 DHE-RSA-AES128-SHA이지만, 

google은 AES128-SHA이다.

Tomcat server.xml에서 AES128-SHA 지원하도록 설정해보자.

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="${user.home}/aa.keystore" keystorePass="121212" clientAuth="false" sslProtocol="TLS" ciphers="TLS_RSA_WITH_AES_128_CBC_SHA"/>

Tomcat ciphers 값은 추천 암호화 목록이 있으니 참고해 보기


다시 테스트 코드 실행해 보기

www: responsed data len:134 UnityWebRequest: responsed data len:134 HttpWebRequest: responsed data len:134

모두 잘 받았다.

핸드쉐이킹 과정에서, 클라와 서버 모두 사용 가능한 암호기법이 있어야 했다.

유니티 모노버전이 낮아서 지원하는 암호기법이 한정적이었다.

뭐 어쨋든 성공!!


이번에는 서버에서 잘 받았는지 확인해 보자.

SpringFramework 기본 MVC이며, 

POST, PUT 두 가지로 BODY데이터를 받도록 했고, 받은 BODY길이를 로그로 찍었다.

@RequestMapping(value = "/", method = RequestMethod.POST) public String home(HttpServletRequest request, HttpServletResponse response, @RequestBody byte[] body) throws IOException { logger.info("post:" + body.length); return "home"; } @RequestMapping(value = "/", method = RequestMethod.PUT) public String homePut(HttpServletRequest request, HttpServletResponse response, @RequestBody byte[] body) throws IOException { logger.info("put:" + body.length); return "home"; }

서버 로그

INFO : bluefin.net.hellomvc2.HomeController - post:7 INFO : bluefin.net.hellomvc2.HomeController - post:7 INFO : bluefin.net.hellomvc2.HomeController - post:2

어라? 클라에서는 분명 new byte[]{61, 61}로 만들어 2바이트만 Body로 보냈다.

디버깅 결과 post:7을 남긴 녀석들은 WWW과 UnityWebRequest였다.


서버가 받은 데이터를 아스키문자로 변환하면 "%3E%3E="이다.

URLENCODE도 아니고 BASE64도 아니고 뭔지 모르겠다^^

스트링을 컨버전하는 사이트에서 확인해 봤는데, URLENCODE로 하는게 가장 비슷하게 나왔다.


문제는 WWW와 UnityWebRequest는 POST로 문자열만 보낼 수 있다.

바이너리 데이터를 보내고 싶었다.

UnityWebRequest에는 다행히 PUT으로 바이너리로 보낼 수 있었다.

테스트 결과는 put:2를 잘 남겼다.


http body에 바이너리를 담으려면, UnityWebRequest.PUT 또는 HttpWebRequest를 사용해야 한다.

간만에 긴 글을 작성했다.

시작은 HTTPS 통신이었고, 통신이 되면서 바이너리 통신을 해봤다, 결과는 휴 힘들었다^^

도움 되시길~