기본 콘텐츠로 건너뛰기

[상추 키우기] 두 번째 상추...

 게으름으로 인하여 두 번째 상추 재배는 수확까지 끝난 다음에야 포스팅을 하게 되었습니다. 두 번째 상추 재배는 새로운 그로잉스펀지와 재배기에 심을 수 있는 12포트 중에서 4포트만 사용하여 상추를 재배했습니다. 그리고, TDS 측정기를 이용하여 양액의 농도 측정도 하면서 재배를 하였습니다. 수경 재배기를 살 때 포함되어 왔던 그로잉스펀지는 지난번 상추 재배로 인하여 모두 소비되어서 알리에서 새로운 스펀지를 주문했습니다. 주문하면서 실수로 동그란 스펀지가 아닌 네모 스펀지를 주문하는 바람에 포트에 넣었을 때 약간의 공간이 생깁니다만 크게 문제가 되지는 않습니다. 그런데 이번에 스펀지는 번들 스펀지에 비해서 밀도가 높다라고 해야할지 스펀지에 구멍이 적은 것 같습니다. 상추 뿌리가 스펀지를 뚫고 나오는데 지난번 보다 오래 걸린것 같습니다. 다음에 주문할 때에는 이런 부분을 좀 주의해야 할 것 같습니다. 그리고, 스펀지와 함께 TDS 측정기도 함께 구매해서 양액의 농도도 측정하였습니다. 상추의 경우 560 ~ 840 정도의 TDS 범위로 양액을 맞춰주라고 하는데, 수경 재배기에 번들된 양액을 12포트 분량으로 혼합하면 이 범위를 만족합니다. 지난번 재배에서는 이 값을 몰라서 싹을 틔우는 시기와 어린 시기에 양액 농도를 낮게 했었는데 그럴 필요는 없었던 것 같습니다. 약 5주 가량 길러서 수확하기 직전의 상태입니다. 12포트를 키울 떄 보다 빛을 잘 받아서 그런지 웃자람도 없고, 상치 잎의 크기도 지난번보다 상대적으로 컸습니다. 보통 상추를 키울때, 잎이 커지면 일부를 따 먹으면서 계속 키우는데 4포트만 키우게 되면 잎을 따 먹기에는 양이 너무 적어서 다 키워서 한번에 수확을 해야 했습니다. 그래서 다음 재배는 포트수를 조금 더 늘려서 시도해보겠습니다. 

Handshake error in client (OS Error: CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate(handshake.cc:393))

현재 flutter로 개발 중인 프로젝트에서 REST API 통신을 하는데, 안드로이드 단말에서 CERTIFICATE_VERIFY_FAILED 오류가 발생하면서 서버와 통신이 이뤄지지 않는 문제가 발생하였습니다.


현재 상황은 apache 서버에 php를 이용하여 api를 만들었고, 운영서버에는 SSL 이 적용되어 있습니다. SSL 인증서는 공인 인증 기관으로 부터 발급된 인증서를 사용하고 있습니다. iOS에서는 문제없이 서버와 통신이 이뤄지지만 안드로이드에서는 오류가 발생합니다.


CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate

"CERTIFICATE_VERIFY_FAILED: unable to get local issuer certificate"로 검색을 하면 공인 기관에서 발급하지 않고 자체적으로 인증서를 발급받아서 사용하는 경우에 문제 해결 방법들이 검색됩니다. 앱 내부에서만 사용하는 서버인 경우에 자체 발급된 인증서를 많이 쓰는 모양입니다. 

자체 인증서로 인한 문제를 해결하는 방법은 두가지 정도가 있는 듯 합니다. 

1. 인증서 검증을 하지 않는 방법


	Dio dio = new Dio();
    (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = 
    	(HttpClient client) {
    		client.badCertificateCallback = (X509Certificate cert, String host, int port) = true;
        	return client;
    	};

2. 인증서를 내장하는 방법


	ByteData data = await rootBundle.load('assets/raw/certificate.pem');
	SecurityContext context = SecurityContext.defaultContext;
	context.setTrustedCertificatesBytes(data.buffer.asUint8List());

1번 방법은 저렇게 하면 굳이 돈을 지불하고 SSL을 지불하는 이유가 없고, 2번 방법은 인증서 변경될 때 마다 앱이 새로 배포되어야 하는 문제가 있습니다.

그리고, iOS에서는 문제가 없고, 공인된 기관에서 발급받는 인증서인데 자체 발급된 인증서와 같이 취급된다는것이 이해가 되지 않았습니다. 또한 동일 앱 내에서 외부 서버로 부터 파일을 받아오고 하는 것에는 문제가 발생하지 않고 있기 때문에 이 문제는 해결책이 아닌 것으로 보여서 좀 더 찾아보고 그래도 답이 없으면 1번 방법으로 진행하자라고 결론을 내렸습니다.

LetsEncrypt SSL 에서 발급받은 인증서의 경우에 Android 7 이상에서 유사한 문제가 발생한다는 내용이 있으나 LetsEncrypt SSL 통해서 발급된 인증서가 아니고 에러 메시지도 달라서 참고만 하는 걸로 결정합니다. (참고 : #)

그리고, System의 CA 저장소에 대한 접근이 되지 않는 경우에 동일한 문제가 발생할 수 있는 것으로 보입니다. 이것은 network-security-config 설정을 통해서 해결 할 수 있다고 합니다. 
아래와 같이 xml을 만들고 manifest에 추가하면 됩니다. (참고 : #android, #flutter

  <network-security-config>
      <base-config>
          <trust-anchors>
              <!-- Trust preinstalled CAs -->
              <certificates src="system" />
              <!-- Additionally trust user added CAs -->
              <certificates src="user" />
          </trust-anchors>
      </base-config>
  </network-security-config>
그러나 기본값은 허용이기 때문에 이것도 원인은 아닌듯 합니다. 이것이 허용되지 않았다면 당연히 다른 서버에서 파일 가져오는 것도 실패하는게 정상입니다. 

계속해서 검색하던 중 동일한 문제를 제기한 을 보았고, 등록된 코멘트에서 답을 찾게 되었습니다.

SSLCertificateChainFile

답은 아파치 서버에 SSL 인증서를 적용하면서 인증서 체인 파일 지정(SSLCertificateChainFile)이 되지 않았을 때 발생하는 문제였습니다. 저의 경우에는 인증서 체인 파일을 복사 해놓았으나 지정하는 과정에서 오류가 있었습니다.

이렇게 지정되었을 때 일반 브라우저(안드로이드에서 동작하는 브라우저 포함)에서는 문제없이 접근이 가능합니다. 심지어 브라우저에서 인증서 정보를 조회하면 정상적으로 루트 인증서까지 정보 조회가 가능합니다. 그리고 위에서 말했듯이 iOS에서는 동일한 코드에서 문제가 발생하지 않습니다.

사소한 실수로 인해서 내가 발생시킨 오류이지만 flutter에서 에러 메시지라도 좀 다르게 해줬으면 문제해결이 빨랐지 않을까하는 생각이 듭니다.

댓글

이 블로그의 인기 게시물

Admob UMP(Google User Messaging Platform) SDK를 이용한 GDPR(General Data Protection Regulation) 대응

얼마 전 부터 운영중인 앱의 Admob 계정을 들어가면 화면 상단에 아래와 같은 눈에 거슬리는 공지가 표시되기 시작했습니다. "올해 안에 EEA 및 영국 사용자에게 광고를 게재하는 모든 게시자는 Google에서 인증한 동의 관리 플랫폼(CMP)을 사용해야 합니다. Google의 자체 동의 관리 솔루션을 포함하여 Google에서 인증한 CMP 이면 어떤 것이든 이 목적으로 사용할 수 있습니다. Google의 동의 관리 솔루션을 사용하는 데 관심이 있으면 먼저 GDPR 메시지를 설정하고 UMP SDK를 구현하세요." 유럽쪽 사용자에 대해서 GDPR(General Data Protection Regulation) 동의 를 받을 수 있도록 하라는 것이다. GDPR 동의에 대해서 처리해야할 법적인 절차를 잘 모르니 친절한(?) Google의 도움을 받을 수 있다고 하니 받는 것으로 했습니다. 메시지를 보면 구글에서 인증한 동의 관리 플랫폼(CMP)를 사용하거나, 구글에서 제공하는 UMP SDK를 이용해서 구현 하면 된다는 내용입니다. 구글에서 UMP SDK를 제공한다고 하니, 이용하기로 합니다. UMP SDK 는 별도의 SDK 형태로 배포되지 않고, Admob SDK에 포함되어 있고, UMP SDK를 이용하여 구현하는 것은 가이드 페이지에 있는 것을 따라가면 되는 수준이라 여기에서는 생략하도록 합니다. # 참고 : - https://support.google.com/admob/answer/10113207 - https://developers.google.com/admob/ios/privacy - https://developers.google.com/admob/android/privacy - https://developers.google.com/admob/flutter/eu-consent 저의 경우에는 구현은 어렵지 않게 했으나, 이 것의 동작을 이해하는데 오랜 시간이 필요했습니다. 그 이유는 사용자로부터 개인정보 이용에 대한 동의를 얻지 못했을 때 광...

[상추 키우기] 수경재배기에 양액 투입

 상추를 파종한지 10일이 지나서 상추들이 이만큼 자랐습니다. 상추의 뿌리가 포트 밖으로 빠져나올 정도로 길게 자랐습니다. 그래도 아직은 뿌리의 가닥 수도 작고, 가늘고 약합니다. 사무실에 사람이 있는 동안은 난방을 하니까 괜찮은데, 저녁에는 아직도 기온이 많이 내려가기 때문에 성장이 더딘것 같습니다. 이제 낮기온도 꽤 올라가고 꽃도 피기 시작하니까 멀지 않아서 폭풍 성장을 할 것 같습니다. 수경재배기 메뉴얼에서는 2주에 한 번 전체 물을 갈아주고, 그 외에는 보충을 해주라고 되어 있습니다. 아직 상추가 싹이 작기도 하고, 10일 밖에 지나지 않았지만, 그 동안 물로만 키우고 있었기 때문에 오늘은 양액을 넣어 주기로 했습니다. 그래서 전체 물갈이를 할 예정입니다. 우선 양액을 준비합니다. 국내에서 많이 판매되는 양액이 있기는 합니다만, 수경재배기에 포함되어 있는 양액을 먼저 사용하려고 합니다. 수경재배기에 포함되어 있는 양액은 액체 상태가 아닌 알갱이 상태로 두 개의 병에 담겨 있습니다. 각 병에 물 100ml 씩을 넣고 알갱이가 다 녹을 때까지 섞어 줍니다. 병에 100ml 눈금이 표시되어 있기 때문에 눈금까지 넣어 주면 됩니다. 메뉴얼 상에는 역삼투압 방식으로 정수된 물을 사용하라고 하는데, 전 그냥 수돗물을 사용했습니다. 순수한 물을 사용하면 아무래도 양액의 농도나 같은 것들이 좀 더 정확해 지지 않을까 싶긴 합니다만, 사무실에 정수기도 없고.... 그렇다고 약국에 증류수를 사러가기도 뭐하고.. 근처에 약국도 없고.. ^^;;;;;;; 여튼, 알갱이가 다 녹을 때까지 섞어 줍니다. A용액은 약간 노란빛이 드는 액체가 되고, B용액은 투명색을 그대로 유지합니다. 그리고, 2L 생수병에 물 2L를 채우고, A용액을 10ml 넣어준 다음에 B용액 10ml 를 추가하였습니다. A/B용액이 직접 만나게 되면 화학 반응이 일어날 수 있는 모양입니다. 그래서 A용액이 물에 충분히 희석된 다음에 B용액을 넣었습니다.  메뉴얼에는 12포트이면 각각 15...

[상추 키우기] 두 번째 상추...

 게으름으로 인하여 두 번째 상추 재배는 수확까지 끝난 다음에야 포스팅을 하게 되었습니다. 두 번째 상추 재배는 새로운 그로잉스펀지와 재배기에 심을 수 있는 12포트 중에서 4포트만 사용하여 상추를 재배했습니다. 그리고, TDS 측정기를 이용하여 양액의 농도 측정도 하면서 재배를 하였습니다. 수경 재배기를 살 때 포함되어 왔던 그로잉스펀지는 지난번 상추 재배로 인하여 모두 소비되어서 알리에서 새로운 스펀지를 주문했습니다. 주문하면서 실수로 동그란 스펀지가 아닌 네모 스펀지를 주문하는 바람에 포트에 넣었을 때 약간의 공간이 생깁니다만 크게 문제가 되지는 않습니다. 그런데 이번에 스펀지는 번들 스펀지에 비해서 밀도가 높다라고 해야할지 스펀지에 구멍이 적은 것 같습니다. 상추 뿌리가 스펀지를 뚫고 나오는데 지난번 보다 오래 걸린것 같습니다. 다음에 주문할 때에는 이런 부분을 좀 주의해야 할 것 같습니다. 그리고, 스펀지와 함께 TDS 측정기도 함께 구매해서 양액의 농도도 측정하였습니다. 상추의 경우 560 ~ 840 정도의 TDS 범위로 양액을 맞춰주라고 하는데, 수경 재배기에 번들된 양액을 12포트 분량으로 혼합하면 이 범위를 만족합니다. 지난번 재배에서는 이 값을 몰라서 싹을 틔우는 시기와 어린 시기에 양액 농도를 낮게 했었는데 그럴 필요는 없었던 것 같습니다. 약 5주 가량 길러서 수확하기 직전의 상태입니다. 12포트를 키울 떄 보다 빛을 잘 받아서 그런지 웃자람도 없고, 상치 잎의 크기도 지난번보다 상대적으로 컸습니다. 보통 상추를 키울때, 잎이 커지면 일부를 따 먹으면서 계속 키우는데 4포트만 키우게 되면 잎을 따 먹기에는 양이 너무 적어서 다 키워서 한번에 수확을 해야 했습니다. 그래서 다음 재배는 포트수를 조금 더 늘려서 시도해보겠습니다.