개발자 dexter.hdj 은 안드로이드 앱 이용자의 개인정보를 매우 중요하게 생각하며 각별히 주의를 기울여 처리하고 있습니다.
앱 내에서 사용되는 정보들과, 사용자의 기기에 저장되는 데이터들은 앱 내에서 사용될 뿐 개발자가 따로 수집하거나 관리, 저장, 확인하지 않습니다.

 

1. 개인정보의 처리 목적
- 타이머 시간 기록을 위한 설정값 저장 (필수적) 기능 (사용자님의 기기에 데이터가 저장됩니다)
각각 타이머의 별칭과 시간 정보를 사용자님의 기기에 저장해놓았다가, 앱에서 불러들여 적용합니다.

 

2. 개인정보의 처리 및 보유 기간

개발자가 데이터를 수집하거나 저장하지 않습니다.

광고 및 광고분석 서비스에서(이하 Google) 수집하는 광고ID에 관한 자세한 사항은 해당 서비스의 개인정보처리방침(https://policies.google.com/privacy?hl=ko)을 참고해 주시길 바랍니다.

 

3. 개인정보처리의 위탁에 관한 사항
개발자가 광고ID를 직접 수집하지 않고, 담당하지않기 때문에 수집될 광고ID를 처리는 광고서비스가 담당합니다.
- 광고ID 수집
위탁받는 자 : 구글(Google)
위탁하는 업무의 내용 : 광고 및 광고 분석 서비스
Google 개인정보처리방침 (https://policies.google.com/privacy?hl=ko)

Google 광고 개인정보 보호 및 약관 (https://policies.google.com/technologies/ads?hl=ko)

+ Android 설정 메뉴에서 광고 ID 설정을 사용하여 사용자가 광고 ID를 재설정하거나 삭제할 수 있습니다.
※ Google은 사용자의 개인정보를 절대 판매하지 않습니다

 

4. 정보주체와 법정대리인의 권리․의무 및 그 행사방법에 관한 사항
- 개인정보의 정정 및 삭제 요구는 다른 법령에서 그 개인정보가 수집 대상으로 명시되어 있는 경우에는 그 삭제를 요구할 수 없습니다. 

5. 처리하는 개인정보의 항목
- 타이머 기능 설정값(사용자님의 기기에 데이터가 저장됩니다. 마찬가지로 개발자가 사용자 데이터에 절대 관여하지 않습니다.)

 

6. 개인정보의 파기에 관한 사항
개발자가 데이터를 수집하거나 저장하지 않습니다.
광고 및 광고분석 서비스에서(이하 Google) 수집하는 광고ID에 관한 자세한 사항은 해당 서비스의 개인정보처리방침(https://policies.google.com/privacy?hl=ko)을 참고해 주시길 바랍니다.

 

7. 개인정보 보호책임자에 관한 사항
개발자 : dexter.hdj
이름 : 황동준
이메일 : hehdwns@gmail.com

8. 개인정보 처리방침의 변경에 관한 사항
런인터벌은 서비스의 변경사항이나 정책을 반영하기 위해 개인정보취급방침을 변경할 수 있습니다.

 

9. 개인정보의 안전성 확보조치에 관한 사항
개발자가 데이터를 수집하거나 저장하지 않습니다.
광고ID 수집 관련 개인정보 처리방침 : Google 개인정보처리방침(https://policies.google.com/privacy?hl=ko)

 

10. 개인정보 자동 수집 장치의 설치∙운영 및 그 거부에 관한 사항
모바일 애플리케이션과 같이 쿠키 기술을 사용할 수 없는 서비스에 광고를 게재하기 위해 Google은 쿠키와 유사한 기능을 수행하는 기술(모바일 인앱 광고 ID)을 사용할 수도 있습니다. 모바일 인앱 광고 ID를 사용하면 개발자와 마케팅 담당자가 광고 목적에 따라 활동을 추적할 수 있습니다.
또한 모바일 광고 ID는 게재 및 타겟팅 기능을 개선하는 데에도 사용됩니다.
이는 기기의 설정(‘Google 설정앱->Google->광고’ 또는 ‘설정->계정->Google->광고’) 을 변경함으로 사용을 거부할 수 있습니다.
자세히 (https://policies.google.com/technologies/ads?hl=ko)

 

변경일자 : 2023.09.14

개인정보 처리방침 변경사항은 즉시 적용됩니다.

1. 개요

지난 블로그에 이어 ionic 프레임워크 소스를 실제 기기에 빌드하는 법에 대해 알아보도록 하겠습니다.


실 기기에 빌드하여 올리는 것이기 때문에 안드로이드의 경우 Android Studio, ios의 경우 Xcode 가 설치 완료되어 있다는 것을 전제로 합니다.

 

이전 포스트는 아래 링크를 참조 하여 주세요.

2022.01.27 - [프로그래밍/ionic framework] - ionic framework, 설치 및 프로젝트 생성

 

ionic framework, 설치 및 프로젝트 생성

1. 개요 아이오닉 프레임워크(ionic framework) 는 android, ios 에서 동작하는 앱을 생성하게 도와주는 하이브리드 앱 개발 프레임워크 입니다. Angular, React, Vue 프레임워크를 사용하여 ..

ittravelkr.tistory.com

 

2. 모바일 프로젝트 생성

모든 명령어는 cmd 에서 프로젝트 폴더로 이동 후 사용하는 것을 기본으로 합니다.
(필자의 경우 d:/ionic/myApp 폴더까지 이동 후 실행합니다.)

 

ionic cap add android
ionic cap add ios

 

명령어는 보시는 대로 직관적입니다.


위 명령어는 안드로이드 기반 모바일 소스를 생성하는 명령어 이고, 아래 명령어는 xcode 기반 소스를 생성하는 명령어 입니다.

 

안드로이드 프로젝트 생성
ios 프로젝트 생성

 

각 명령어를 실행하시면, 프로젝트 폴더 내부에 해당 os에 맞는 폴더가 생성 됩니다.

 

프로젝트 폴더 맨 위에 android / ios 폴더가 생성되었습니다.

 

물론 소스코드가 생성이 되기만 한 것일 뿐 해당 소스는 그에 맞는 IDE 를 통해 빌드하여야 합니다.
즉, MacOS 기반 PC가 아닌 경우 ios 소스는 생성만 될 뿐 실행 해 볼 수는 없습니다.

 

폴더 생성이 완료된 경우, 다음 명령어를 실행합니다.

 

ionic cap sync

 

위 명령어는 vue.js 로 작성 된 소스코드를 mobile 소스로 build 하여 주는 명령어 입니다.


ionic 으로 작성 된 vue.js 소스는 실제 모바일 기기에 업로드 시 소스코드 단축이 되기 때문에 모바일 IDE 에서 소스코드를 수정 할 수는 없습니다.


따라서 vue.js 소스 변경이 생길 때 마다 항상 위 명령어를 수행 후, 모바일 IDE 에서 build 하여 기기로 업로드 하셔야 합니다.

 

ionic cap sync 명령어 수행이 완료 된 모습

 

위 작업이 완료되면 이제 모바일 IDE 를 실행하도록 명령어를 입력 해 줍니다.

 

ionic cap open android
ionic cap open ios

 

각 명령어는 Android Studio / Xcode 를 실행해 주는 명령어 입니다.


해당 명령어로 실행 시 IDE 가 실행되며 각 프로젝트 폴더가 자동으로 open 되기 때문에 편리합니다.
(최초 실행 시 프로젝트 링크 및 gradle build 등에 시간이 걸립니다.)

 

해당 명령어 실행 시 Android Studio 가 실행됩니다. PC 성능에 따라 IDE 실행에 시간이 걸립니다.

 

IDE 실행 후 프로젝트 폴더가 자동으로 open 됩니다.

 

app 폴더를 제외한 나머지 폴더들은 vue.js <--> 모바일 기기 간 cross-platform 을 지원하기 위한 cordova 소스들입니다.

 

 

이후부터는 IDE 의 소스코딩 방법 및 빌드 방법에 따르므로 따로 기술하지는 않습니다.

 

3. 실행

앱 실행 아이콘

 

필자의 Fold 1 기기에 업로드하여 실행한 모습

 

다음 시간에는 모바일 기기의 카메라를 활용하여 QR코드를 스캔하여 인식하는 앱을 만들어 보도록 하겠습니다.

 

'프로그래밍 > ionic framework' 카테고리의 다른 글

ionic framework, 설치 및 프로젝트 생성  (1) 2022.01.27

1. 개요

아이오닉 프레임워크(ionic framework) 는 android, ios 에서 동작하는 앱을 생성하게 도와주는 하이브리드 앱 개발 프레임워크 입니다.

Angular, React, Vue 프레임워크를 사용하여 앱 View 를 구성하는 것을 기본으로 스마트폰 디바이스의 API 를 사용하기 위해 ionic 에서 자체 개발한 capacitor 라는 cross-platform 지원 도구로 이루어져 있습니다.

아이오닉 프레임워크에 대해 더 자세히 알고 싶으신 분은 프레임워크 홈페이지(https://ionicframework.com/) 를 참고 하시면 됩니다.

본 블로그는 ionic framework 의 현재(2022.01.27) 가장 최신 버전인 ionic 6 에 기반합니다.

 

2. 설치

ionic 을 사용하기 위해서는 우선 npm 이 설치되어 있어야 합니다. (하여 본 블로그는 npm 이 설치되어 있는 것을 전제로 작성되었습니다.)

우선, 아이오닉 프로젝트 생성을 위한 도구를 설치합니다.

npm install -g @ionic/cli@latest native-run cordova-res

설치가 다 끝날 때까지 기다리시면 됩니다.

매우 쉽죠?

 

 

3. 프로젝트 생성

ionic framework 를 사용하기 위한 기반 설치가 완료 되었으니, 이제 프로젝트를 생성해 보도록 합니다.
윈도우의 경우, cmd 창을 열고 본인이 프로젝트를 생성하기 원하는 폴더로 이동 합니다. (저는 d:\ionic 이라는 폴더 안에 프로젝트를 생성해 보겠습니다.)

프로젝트 생성 명령어는 다음과 같습니다.

ionic start [앱 명칭] [프로젝트 탬플릿] [option]

각 항목 간에는 공백(스페이스)으로 구분되며 프로젝트 탬플릿은 2가지(탬플릿 명령어는 3가지가 있으나 하나는 있으나 마나 하므로..)가 있습니다.

 

[프로젝트 탬플릿]

  • tabs : 탭 기반 레이아웃
  • sidemenu : 사이드 메뉴 기반 레이아웃
  • blank : 한 페이지의 빈 프로젝트

옵션은 js탬플릿 선택과 native 선택으로 구성되어 있습니다.


[JS 탬플릿 선택]

  • --type 값이 없으면 기본 angular.js 로 시작 됨
  • --type vue : vue.js 기반
  • --type react : react.js 기반

[Native 선택]

  • --cordova : cordova Native API (vue 기반에서는 실행 안됨)
  • --capacitor : ionic 에서 만든 Native API

위 명령어 구문을 사용하여 프로젝트를 생성 하도록 합니다.

ionic start myApp tabs --type vue --capacitor

제가 사용한 명령어는 myApp 이라는 프로젝트를 탭 기반 레이아웃(tabs)로 하여, View 를 구성하기 위해 vue.js 탬플릿을 사용하며, cross-platform 으로는 capacitor 를 사용한다고 지정하였습니다.

 

프로젝트 생성에는 제법 오랜 시간이 걸립니다.

명령어 입력 시 npm 을 통해 필수 패키지 들이 프로젝트 폴더에 자동 설치 됩니다.

 

설치 마지막 과정입니다. 엔터 입력하시면 됩니다.

 

설치가 완료 되었습니다.

자, 드디어 프로젝트 생성이 완료되었습니다.

 

4. 프로젝트 실행

프로젝트를 기동하기 위해서는 다음의 명령어를 사용합니다.

ionic serve

해당 명령어를 사용하기 위해서는 cmd 창에서 생성 된 프로젝트 폴더 안으로 들어가야 합니다.
필자의 경우 d:\ionic\myApp 폴더로 이동하여 명령어를 실행하도록 합니다.

기동 명령어 입력 후 위와 같은 화면이 나올 때까지 기다려 주세요.
cmd 창에 나와있는 주소로 접속하였을 때 나오는 화면

제대로 기동이 완료 된 경우 위 이미지와 같은 화면을 볼 수 있습니다.

필자는 tabs 기반 레이아웃을 사용하였기 때문에 하단에 Tab Navigation 이 포함 된 프로젝트가 생성되었습니다.

 

소스코드는 모두 src 폴더 안에 있습니다.

 

화면을 구성하는 소스들은 src/views 안에 있으며, 탭 기반 레이아웃 이기 때문에 하단 탭 네비게이션을 구성하는 TabPage.vue 파일과 각 탭의 페이지를 담당하는 Tab1Page.vue 등으로 구성되어 있습니다.

 

5. 스마트폰에서 구동

지금까지의 과정은 ionic 프로젝트를 생성하기만 한 것일 뿐, 실제 이것만 가지고는 스마트폰에 build 할 수 없습니다.


다음 시간에는 해당 프로젝트를 android / ios 용으로 빌드하여 실제 기기에서 실행하는 법을 알아보도록 하겠습니다.

'프로그래밍 > ionic framework' 카테고리의 다른 글

ionic framework, 스마트폰 빌드 가이드  (0) 2022.02.04



서평 이벤트 : https://cafe.naver.com/aphone/93447



오랜만에 손 놓고 있던 안드로이드 개발을 하게 되었는데..


코틀린이란 것이 있다는 것을 알게 되었네요.


안드로이드는 언제나 자바로만 짜는 줄 알고 있었는데...


새로운 것을 배우는 것은 언제나 신기하기만 합니다.

1. 개요


안드로이드 6.0 이상 버전에서 사용자에 의해 권한을 부여 받아야 사용 가능한 기능 (카메라, 파일 접근 등)을 이용하려면 런타임 퍼미션( runtime permissions)이 필요합니다.


본 포스팅에서는 퍼미션을 체크하고 요청하는 방법에 대해 기술합니다.


핵심 함수는 다음과 같습니다.


퍼미션 체크 ActivityCompat.checkSelfPermission(Context, String)

퍼미션 요청 ActivityCompat.requestPermissions(Activity, String[], int)

퍼미션 요청 콜백함수 ActivityCompat.OnRequestPermissionsResultCallback


콜백함수(OnRequestPermissionsResultCallback) 의 경우 AppCompatActivity 에 오버라이드 (Override) 되어 있는 함수이기 때문에 실제 권한 요청을 수행하는 Activity 에 코드가 포함되지만 그 외 나머지 함수들은 별도의 CustomClass 를 작성하여 호출하도록 구성하였습니다.


2. 소스 코드


1) AndroidManifest.xml


실제 사용하고자 하는 요청 권한을 명기 합니다.


<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


2) PermissionUtil.java


퍼미션 체크(checkSelfPermission) 와 퍼미션 요청(requestPermissions) 을 실제로 호출하는 CustomClass 입니다.


해당 부분은 내용이 길어 첨부한 소스코드 파일의 주석으로 대체 합니다.


PermissionUtil.java


3) MainActivity.java


앱 최초 실행 시 권한을 받아 결과에 따라 앱을 실행할지 말지 여부를 결정하기 위해 최초 실행 되는 Activity의 onCreate 에서 호출하도록 합니다.


만약 해당 기능 사용과 별개로 앱을 사용하다가 실제 기능 동작이 필요한 경우에 권한을 요청하려면 (예를 들어 사진 앨범에 접근하기 위해 가져오기 버튼을 클릭하는 순간 권한을 묻기를 원한다면) 해당 기능 동작 중 (OnClickListener 내부)에 호출하도록 합니다.



private PermissionUtil m_PermissionTool;
private String strPermissions[] = {
	Manifest.permission.READ_EXTERNAL_STORAGE
};

@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);

	// 권한 검사
	m_PermissionTool = new PermissionUtil(this, strPermissions);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
	super.onRequestPermissionsResult(requestCode, permissions, grantResults);

	switch (requestCode) {
		case PermissionUtil.MY_PERMISSIONS_REQUEST_READ_CONTACTS:
			if (m_PermissionTool.verifyPermission(permissions, grantResults) == false) {
				// 권한 얻기 실패
				m_PermissionTool.showRequestAgainDialog();
			}
			break;
	}
}


3. 참조


https://developer.android.com/training/permissions/requesting?hl=ko#java



1. 개요


프로그래밍을 하다 보면, 이 기종 간에 데이터를 주고 받아야 하는 일이 참 많이 발생한다.


대체로 온라인을 통해 데이터를 주고 받는 경우가 흔한데, 이 경우 유출될 수 있는 데이터를 보호하기 위해서는 반드시 암호화/복호화 과정을 통해 데이터를 잠궈야 하는데 이때 많이 사용되는 암호화 알고리즘이 AES 방식일 것이다.


2. AES


데이터를 암호화 하는 키의 길이에 따라 AES-128, AES-192, AES-256 의 형태로 사용 가능하다.


단순히 키의 길이만 바뀌는 것이 아니라, 키의 길이에 맞춰 암호화를 진행하는 횟수 (이를 라운드라 함) 도 다르고 또 암호화 하고자 하는 데이터 길이에 따라서 CBC 방식이니 ECB, CFB 등등.. 여러 방식이 있지만 여기서 암호화 알고리즘에 대해 논하자는 것은 아니고 실제 선구자 들이 만들어 놓은 암호화 알고리즘을 사용하는 방법을 기술하고자 한다.


3. PHP


최신 PHP 에서는 openssl 확장 DLL을 통한 암호화 방식을 많이 사용한다.

openssl_encrypt, openssl_decrypt 함수를 사용하며 key, iv, 암호화 방식을 선택하기만 하면 간단하게 암호화가 가능해 진다.


openssl_encrypt($str, "AES-256-CBC", $secret_key, OPENSSL_RAW_DATA, $secret_iv);
openssl_decrypt($str, "AES-256-CBC", $secret_key, OPENSSL_RAW_DATA, $secret_iv);

자세한 사용 방법은 첨부 된 php 파일을 참고 하시길






4. JAVA


오늘 본 글을 블로그에 게재 하게 만든 원인. 이 녀석이다.


구글 등에서 JAVA AES 256 암호화로 검색하면 가장 많이 보이는 소스가 바로 다음과 같은 형식이다.


public AES256Util(String key) {
		this.iv = key.substring(0, 16);
		byte[] keyBytes = new byte[16];
		byte[] b = key.getBytes("UTF-8");
		int len = b.length;
		if (len > keyBytes.length) {
			len = keyBytes.length;
		}
		System.arraycopy(b, 0, keyBytes, 0, len);
		SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

		this.keySpec = keySpec;
	}

AES-CBC 방식의 경우 초기화 벡터(IV) 값으로 16 byte의 공유(암호화 복호화 하고자 하는 사람 간에)되는 값을 사용한다.


대게 해당 값은 암호화에 사용하는 마스터 키(역시 암복호화 사이에 공유 되는 값) 에서 16 byte를 추출해서 사용하는 것이 보통이기에 위 소스 첫 째 줄처럼 사용하곤 한다.


여기까지는 문제가 없다.

다음을 보자


byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");

...
...
...

System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

위 코드를 분석해 보면, keyBytes 라는 16 byte (중요하다. 강조!) 배열을 생성하고 입력받은 마스터 키(key) 값 중에서 에서 16 byte 를 뽑아와서 keyBytes 에 채워넣고 있다.


그리고, 이 값을 가지고 SecretKeySpec 이라는 함수를 통해 암복호화에 사용할 비밀키를 설정하고 있다.


여기서 이상한 점을 느낄 수 있는가?

사실 보안교육이나 암호화에 대해 따로 배운 적이 있지 않고는 위 코드만 보고서는 문제점을 찾기란 쉽지 않을 것이다.


본 글 2항에서, AES는 키의 길이에 따라 암호화 방식이 128, 192, 256 으로 나뉜다고 기술하였다.


하지만 대부분의 소스를 검색해 보면 SeceretKeySpec 함수를 사용하는데 있어 16 byte 의 키를 넣어 놓고는 AES-256 암호화를 사용하고 있다고 말하는 경우가 비일비재 하다.


위의 소스 코드는 다음과 같이 변경되어야 한다.


public AESCrypto(final String key, final int keySize) throws Exception { byte[] keyBytes=null; byte[] b = key.getBytes(StandardCharsets.UTF_8); String strCipher=null; switch (keySize) { case 16: // 128 bit strCipher = "AES-128"; keyBytes = new byte[keySize]; break; case 24: // 192 bit strCipher = "AES-192"; keyBytes = new byte[keySize]; break; case 32: // 256 bit strCipher = "AES-256"; keyBytes = new byte[keySize]; break; } if (keyBytes == null) { throw new Exception("암호화 방식이 올바르지 않습니다."); } System.out.println("Encrypt Type : "+strCipher); int inputKeyLength = key.length(); if (inputKeyLength > keySize) { // 입력 받은 key string 길이가 실제 암호화 할 대상 key 길이보다 큰 경우, 암호화 키 길이에 맞게 조정 System.arraycopy(b, 0, keyBytes, 0, keySize); } else if (inputKeyLength < keySize) { throw new Exception("Key 길이가 올바르지 않습니다."); } else { // 입력 받은 key string 길이가, 실제 암호화 할 대상 key 길이와 동일한 경우 System.arraycopy(b, 0, keyBytes, 0, keySize); } // AES 암호화는 IV 값으로 16 byte 사용 this.iv = key.substring(0, 16); // KeySpec 생성 시 입력하는 키 길이에 따라 AES-128,192,256 방식으로 자동 설정 됨 this.keySpec = new SecretKeySpec(keyBytes, "AES"); System.out.println("KEY : "+new String(keyBytes, "UTF-8")); System.out.println("IV : "+this.iv); }


JAVA 소스코드 역시 첨부하였으니 자세한 사용 방법은 코드를 확인 하시길..


5. 결과


<PHP 호출 결과>



<JAVA 호출 결과>




6. 맺음


부디 본 글이 이 기종 연동 간에 서로가 원인을 못 찾아 허덕이는 이들을 구원해 주기를...


AES.zip





 

1. 개요

 

 

MFC 에서 사용 가능한 libcurl DLL 파일 및 LIB 파일 묶음 입니다.

 

SSL 미 사용 버전으로 최신 버전 CURL 유지를 위하여 공유 합니다.

 

정적 라이브러리에서 MFC 사용 가능한 환경으로 작성 된 파일이며 사용 시, CURL_STATICLIB 를 전처리기에 추가해 주어야 합니다.

(참조 : https://ittravelkr.tistory.com/24?category=406899)

 

 

 

 

 

 

libcurl-7.65.1.zip

 

 

1. 개요

 

MFC 에서 Json 포맷의 스트링을 파싱할 경우 사용 할 수 있는 open source

 

2. 설치

 

공식 git 페이지(https://github.com/open-source-parsers/jsoncpp) 에서 소스 코드를 다운로드 받아, Visual Studio IDE에서 프로젝트를 Import 및 Compile 하여 사용

 

이때, lib 형식과 dll 형식의 2가지 방식으로 컴파일 가능

 

3. 오류 대처

 

jsoncpp를 컴파일 하여 나온 결과물(lib, dll)을 프로젝트에 import 하여 사용하는 경우 debug 모드에서는 별 문제가 없으나, release 모드로 컴파일 시 [json_value.cpp : fatal error C1083: 컴파일러 생성 파일 파일을 열 수 없습니다. '../../build/vs71/release/lib_json/json_value.asm': No such file or directory] 와 같은 에러가 생기는 경우 다음과 같이 설정 값을 수정 하는 것으로 해결 가능

 

 

붉은 박스로 표시한 영역의 값을 목록 없음(No listing)으로 변경

 

 

비트 연산자를 통한 각 비트의 설정 값(1, 0) 얻어오기

int getAbit(unsigned short x, int n) 
{
 return (x & (1 << n)) >> n;
}

 

각 비트 값 설정

unsigned short setAbit(unsigned short x, int n, int value) 
{
 if (value == 1)
  return (unsigned short) (x | (1 << n));
 else
  return (unsigned short) (x & (~(1 << n)));
}

 

참조용 소스 업로드

 

TryIconAgent.zip

 

+ Recent posts