반응형
// UTC 시간을 Locale 시간으로 변환
func utcToLocale(utcDate : String, dateFormat: String) -> String
{
	let dfFormat = DateFormatter()
	dfFormat.dateFormat = dateFormat
	dfFormat.timeZone = TimeZone(abbreviation: "UTC")
	let dtUtcDate = dfFormat.date(from: utcDate)
	
	dfFormat.timeZone = TimeZone.current
	dfFormat.dateFormat = dateFormat
	return dfFormat.string(from: dtUtcDate!)
}
    
// Locale 시간을 UTC 시간으로 변환
func localeToUtc(localeDate: String, dateFormat: String) -> String
{
	let dfFormat = DateFormatter()
	dfFormat.dateFormat = dateFormat
	dfFormat.timeZone = TimeZone.current
	let dtLocaleDate = dfFormat.date(from: localeDate)
	
	dfFormat.timeZone = TimeZone(abbreviation: "UTC")
	dfFormat.dateFormat = dateFormat
	return dfFormat.string(from: dtLocaleDate!)
}
반응형
블로그 이미지

SKY STORY

,
반응형

최근 SEED 블록 암호 알고리즘 CBC 암복호화 처리를

해야할 일이 생겨 관련 클래스를 제작하게 되었습니다

혹시 같은 작업을 하시는분에게 도움이 되었으면 합니다.

아래 작업은 Swift프로젝트에서 작업되었습니다.

 

SEED 블록암호 알고리즘

seed.kisa.or.kr/kisa/Board/17/detailView.do

 

KISA 암호이용활성화 - 암호알고리즘 소스코드

한국인터넷진흥원(KISA)에서는 128비트 블록암호 SEED를 쉽게 활용할 수 있도록, ECB, CBC, CTR, CCM, GCM, CMAC 운영모드에 대한 소스코드를 배포하고 있습니다. 언어 : C/C++, Java, ASP, JSP, PHP  다음글 2019-01-3

seed.kisa.or.kr

 

KISA_SEED_CBC.h

다음 함수를 헤더에 선언해 주도록 한다.

extern int encryptSeedCBC( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszPlainText, OUT BYTE *pbszCipherText );
extern int decryptSeedCBC( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszCipherText, OUT BYTE *pbszPlainText );

 

KISA_SEED_CBC.c

다음과 같이 작성해 준다.

작성에 앞서 main()함수는 제거해주도록 하자.

int encryptSeedCBC( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszPlainText, OUT BYTE *pbszCipherText )
{
    printf("\n---------------------------------");
    printf("\nplainText : %s\n", (char *)pbszPlainText);
    
    int nPlainTextLen = (int)strlen((char *)pbszPlainText);// 평문의 Byte길이
    printf ("\n---------------------------------");
    printf ("\nSEED CBC Encryption....\n");
    // 암호문의 Byte길이 - 패딩 로직때문에 16바이트 블럭으로 처리함으로 pbszCipherText는 평문보다 16바이트 커야 한다.
    int nCipherTextLen = SEED_CBC_Encrypt( pbszUserKey, pbszIV, pbszPlainText, nPlainTextLen, pbszCipherText );
    return nCipherTextLen;
}

int decryptSeedCBC( IN BYTE *pbszUserKey, IN BYTE *pbszIV, IN BYTE *pbszCipherText, OUT BYTE *pbszPlainText )
{
    int nCipherTextLen = (int)strlen((char *)pbszCipherText);// 암호문의 Byte길이
    printf ("\n---------------------------------");
    printf ("\nSEED CBC Decryption....\n");
    // 평문의 Byte길이
    int nPlainTextLen = SEED_CBC_Decrypt( pbszUserKey, pbszIV, pbszCipherText, nCipherTextLen, pbszPlainText );
    return nPlainTextLen;
}

 

CryptoUtil  유틸 클래스 생성

//
//  CryptoUtil.h
//  
//
//  Created by netcanis on 2020/07/09.
//  Copyright © 2020 netcanis. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface CryptoUtil : NSObject

+(NSString *)encrypt:(NSString *)masterKey msg:(NSString *)msg;
+(NSString *)encrypt:(Byte *)key iv:(Byte *)iv msg:(NSString *)msg;

+(NSString *)decrypt:(NSString *)masterKey msg:(NSString *)base64Str;
+(NSString *)decrypt:(Byte *)key iv:(Byte *)iv msg:(NSString *)base64Str;

+(NSData *)getSHA256:(NSString *)msg;
+(NSString *)hash:(NSString *)secret payload:(NSString *)payload;

@end

NS_ASSUME_NONNULL_END

 

//
//  CryptoUtil.m
//  
//
//  Created by netcanis on 2020/07/09.
//  Copyright © 2020 netcanis. All rights reserved.
//

#import "CryptoUtil.h"
#import "CocoaSecurity.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "KISA_SEED_CBC.h"


@implementation CryptoUtil



+(NSString *)encrypt:(NSString *)masterKey msg:(NSString *)msg {
    NSData *sha256 = [self getSHA256:masterKey];
    NSData *key = [sha256 subdataWithRange:NSMakeRange(0, 16)];
    NSData *iv = [sha256 subdataWithRange:NSMakeRange(16, 16)];
    
    BYTE pbszPlainText[2048] = {0,};
    memset(pbszPlainText, 0, [msg length]);
    const char *byteBuff = [msg UTF8String];
    memcpy(pbszPlainText, (BYTE *)byteBuff, strlen(byteBuff));
    
    // 암호문 출력 버퍼
    BYTE pbszCipherText[2048] = {0,};
    int nCipherTextLen = encryptSeedCBC( (BYTE *)[key bytes], (BYTE *)[iv bytes], pbszPlainText, pbszCipherText );

    // base64 encode
    NSData *data = [[NSData alloc] initWithBytes:pbszCipherText length:nCipherTextLen];
    NSString *base64String = [data base64EncodedStringWithOptions:0];

    // memory clean
    memset(pbszPlainText, 0, nCipherTextLen);
    memset((void *)[data bytes], 0, [data length]);

#ifdef DEBUG
    // log
    [CryptoUtil printHexaLog:pbszCipherText length:nCipherTextLen];
#endif//DEBUG
    
    return base64String;
}

+(NSString *)encrypt:(Byte *)key iv:(Byte *)iv msg:(NSString *)msg {
    
    BYTE pbszPlainText[2048] = {0,};
    memset(pbszPlainText, 0, [msg length]);
    const char *byteBuff = [msg UTF8String];
    memcpy(pbszPlainText, (BYTE *)byteBuff, strlen(byteBuff));
    
    // 암호문 출력 버퍼
    BYTE pbszCipherText[2048] = {0,};
    int nCipherTextLen = encryptSeedCBC( key, iv, pbszPlainText, pbszCipherText );

    // base64 encode
    NSData *data = [[NSData alloc] initWithBytes:pbszCipherText length:nCipherTextLen];
    NSString *base64String = [data base64EncodedStringWithOptions:0];

    // memory clean
    memset(pbszPlainText, 0, nCipherTextLen);
    memset((void *)[data bytes], 0, [data length]);
    
#ifdef DEBUG
    // log
    [CryptoUtil printHexaLog:pbszCipherText length:nCipherTextLen];
#endif//DEBUG
    
    return base64String;
}

+(NSString *)decrypt:(NSString *)masterKey msg:(NSString *)base64Str {
    NSData *sha256 = [self getSHA256:masterKey];
    NSData *key = [sha256 subdataWithRange:NSMakeRange(0, 16)];
    NSData *iv = [sha256 subdataWithRange:NSMakeRange(16, 16)];
    
    // base64 decode
    NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Str options:0];

    BYTE pbszCipherText[2048] = {0,};
    memcpy(pbszCipherText, [data bytes], [data length]);

    // 사용자 입력 평문
    BYTE pbszPlainText[2048] = {0,};
    int nPlainTextLen = decryptSeedCBC( (BYTE *)[key bytes], (BYTE *)[iv bytes], pbszCipherText, pbszPlainText );

    NSString *plainText = [[NSString alloc] initWithBytes:pbszPlainText length:nPlainTextLen encoding:NSUTF8StringEncoding];

    // memory clean
    memset(pbszCipherText, 0, nPlainTextLen);

#ifdef DEBUG
    // log
    [CryptoUtil printHexaLog:pbszPlainText length:nPlainTextLen];
#endif//DEBUG
    
    return plainText;
}

+(NSString *)decrypt:(Byte *)key iv:(Byte *)iv msg:(NSString *)base64Str {
    
    // base64 decode
    NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Str options:0];

    BYTE pbszCipherText[2048] = {0,};
    memcpy(pbszCipherText, [data bytes], [data length]);

    // 사용자 입력 평문
    BYTE pbszPlainText[2048] = {0,};
    int nPlainTextLen = decryptSeedCBC( key, iv, pbszCipherText, pbszPlainText );

    NSString *plainText = [[NSString alloc] initWithBytes:pbszPlainText length:nPlainTextLen encoding:NSUTF8StringEncoding];

    // memory clean
    memset(pbszCipherText, 0, nPlainTextLen);
    
#ifdef DEBUG
    // log
    [CryptoUtil printHexaLog:pbszPlainText length:nPlainTextLen];
#endif//DEBUG
    
    return plainText;
}

+(NSData *)getSHA256:(NSString *)msg {
    NSData *data = [CocoaSecurity sha256:msg].data;
    return data;
}

+(NSString *)hash:(NSString *)secret payload:(NSString *)payload {
    NSString *result = [CocoaSecurity hmacSha256:payload hmacKey:secret].base64;
    return result;
}


+(void)printHexaLog:(BYTE *)pbBytes length:(NSInteger)length {
    printf ("\nLength (%ld)  : ", (long)length);
    for (int i=0;i<length;i++) {
        printf("%02X ",pbBytes[i]);
    }
}

@end

 

암호화 처리를 위해 CocoaSecurity 클래스를 사용했다.

https://github.com/kelp404/CocoaSecurity/tree/master/CocoaSecurity

 

kelp404/CocoaSecurity

Encrypt/Decrypt: AES. Hash: MD5, SHA(SHA1, SHA224, SHA256, SHA384, SHA512). Encode/Decode: Base64, Hex. - kelp404/CocoaSecurity

github.com

 

해당 클래스도 프로젝트에 추가해 준다.

 

[ 사용방법 ] 

// encode
let msg = "2020070917085299920190520000001abcdefghijklmn"
let masterKey = "1234567890";
let enc = CryptoUtil.encrypt(masterKey, msg: msg)
print("\(enc)")

// output :
3JomiSXGgIuC6vbFELbIa3+5QyJlpv6cFgy6JDcPmRryk2V+y2sueCivAymkra6D


// decode
let dec = CryptoUtil.decrypt(masterKey, msg: enc)

// output :
2020070917085299920190520000001abcdefghijklmn

 

 

2020/07/11 - [분류 전체보기] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제2

2020/07/11 - [Android/Java] - Webview에서 새로운창 출력

2020/07/11 - [Android/Tips] - Could not find com.android.tools.build:aapt2:4.0.0-6051327.

2020/07/11 - [Android/Kotlin] - byte array to hex string

2020/07/11 - [Android/Tips] - Android API Level 및 명칭

2020/07/11 - [Android/Tips] - ERROR: Could not get unknown property 'com' for root project 'myApp' of type org.gradle.api.Project

2020/07/11 - [Android/Tips] - error: cannot find symbol this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);

2020/07/11 - [Android/Rooting] - LG 펌웨어 추출 및 OS 다운그레이드 (kdz file)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (4/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (3/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (2/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (1/4)

2020/06/16 - [OS/Mac OS X] - duplicate symbol 에러 해결

2020/06/12 - [iOS/Jailbreak] - Fridump 사용법 (4/4) - 결과물 바이너리 검색

2020/06/03 - [iOS/Objective-C] - NSString <-> CBUUID

반응형

'개발 > iOS' 카테고리의 다른 글

Dictionary sort  (0) 2020.07.11
UTC시간, Locale시간 변경  (0) 2020.07.11
Fridump 사용법 (4/4) - 결과물 바이너리 검색  (0) 2020.06.12
NSString <-> CBUUID  (0) 2020.06.03
위치서비스(location service) 활성화 여부 체크  (0) 2020.06.03
블로그 이미지

SKY STORY

,
반응형

android webview로 작업된 프로젝트에서 간혹 ipin 인증이나 결제 모듈 팝업, sms 인증 팝업을 띄워야 할 때가 있다.

이 경우 webChromeClient의 onCreateWindow를  Override하여야 하며 webview setting을 다음과 같이 변경해야 한다.

 

1. Webview Setting 변경

WebSettings settings = webView.getSettings();

 

settings.setJavaScriptEnabled(true);

settings.setJavaScriptCanOpenWindowsAutomatically(true);

settings.setSupportMultipleWindows(true);

 

2. WebChromeClient에 onCreateWindow Override

@Override

public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {

    WebView newWebView = new WebView(MainActivity.this);

    WebSettings webSettings = newWebView.getSettings();

    webSettings.setJavaScriptEnabled(true);



    final Dialog dialog = new Dialog(MainActivity.this);

    dialog.setContentView(newWebView);

    dialog.show();



    newWebView.setWebChromeClient(new WebChromeClient() {

        @Override

        public void onCloseWindow(WebView window) {

            dialog.dismiss();

        }

    });



    ((WebView.WebViewTransport)resultMsg.obj).setWebView(newWebView);

    resultMsg.sendToTarget();

    return true;

}

 

2020/07/11 - [Android/Tips] - Could not find com.android.tools.build:aapt2:4.0.0-6051327.

2020/07/11 - [Android/Kotlin] - byte array to hex string

2020/07/11 - [Android/Tips] - Android API Level 및 명칭

2020/07/11 - [Android/Tips] - ERROR: Could not get unknown property 'com' for root project 'myApp' of type org.gradle.api.Project

2020/07/11 - [Android/Tips] - error: cannot find symbol this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);

2020/07/11 - [Android/Rooting] - LG 펌웨어 추출 및 OS 다운그레이드 (kdz file)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (4/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (3/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (2/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (1/4)

반응형
블로그 이미지

SKY STORY

,
반응형
반응형
블로그 이미지

SKY STORY

,
반응형
private val hexArray = "0123456789ABCDEF".toCharArray()

fun bytesToHex(bytes: ByteArray): String {
    val hexChars = CharArray(bytes.size * 2)
    for (j in bytes.indices) {
        val v = (bytes[j] and 0xFF.toByte()).toInt()

        hexChars[j * 2] = hexArray[v ushr 4]
        hexChars[j * 2 + 1] = hexArray[v and 0x0F]
    }
    return String(hexChars)
}

fun main(args: Array<String>) {

    val bytes = byteArrayOf(10, 2, 15, 11)

    val s = bytesToHex(bytes)
    println(s)
}
반응형
블로그 이미지

SKY STORY

,
반응형

https://developer.android.com/guide/topics/manifest/uses-sdk-element.html

 

 |  Android 개발자  |  Android Developers

Lets you express an application's compatibility with one or more versions of the Android platform, by means of an API Level integer. The API Level expressed by an application will be compared to the API Level of a given Android system, which may vary…

developer.android.com

 

다음 표에는 각 Android 플랫폼 버전이 지원하는 API 레벨이 지정되어 있습니다. 각 버전을 실행 중인 기기의 관련 번호에 대한 자세한 내용은 플랫폼 버전 대시보드 페이지를 참조하세요.

플랫폼 버전API 레벨버전 코드참고

Android 10.0 29 Q 플랫폼 하이라이트
Android 9 28 P 플랫폼 하이라이트
Android 8.1 27 O_MR1 플랫폼 하이라이트
Android 8.0 26 O 플랫폼 하이라이트
Android 7.1.1
Android 7.1
25 N_MR1 플랫폼 하이라이트
Android 7.0 24 N 플랫폼 하이라이트
Android 6.0 23 M 플랫폼 하이라이트
Android 5.1 22 LOLLIPOP_MR1 플랫폼 하이라이트
Android 5.0 21 LOLLIPOP
Android 4.4W 20 KITKAT_WATCH 웨어러블 기기 전용 KitKat
Android 4.4 19 KITKAT 플랫폼 하이라이트
Android 4.3 18 JELLY_BEAN_MR2 플랫폼 하이라이트
Android 4.2, 4.2.2 17 JELLY_BEAN_MR1 플랫폼 하이라이트
Android 4.1, 4.1.1 16 JELLY_BEAN 플랫폼 하이라이트
Android 4.0.3, 4.0.4 15 ICE_CREAM_SANDWICH_MR1 플랫폼 하이라이트
Android 4.0, 4.0.1, 4.0.2 14 ICE_CREAM_SANDWICH
Android 3.2 13 HONEYCOMB_MR2
Android 3.1.x 12 HONEYCOMB_MR1 플랫폼 하이라이트
Android 3.0.x 11 HONEYCOMB 플랫폼 하이라이트
Android 2.3.4
Android 2.3.3
10 GINGERBREAD_MR1 플랫폼 하이라이트
Android 2.3.2
Android 2.3.1
Android 2.3
9 GINGERBREAD
Android 2.2.x 8 FROYO 플랫폼 하이라이트
Android 2.1.x 7 ECLAIR_MR1 플랫폼 하이라이트
Android 2.0.1 6 ECLAIR_0_1
Android 2.0 5 ECLAIR
Android 1.6 4 DONUT 플랫폼 하이라이트
Android 1.5 3 CUPCAKE 플랫폼 하이라이트
Android 1.1 2 BASE_1_1
Android 1.0 1 BASE

 

 

2020/07/11 - [Android/Tips] - ERROR: Could not get unknown property 'com' for root project 'myApp' of type org.gradle.api.Project

2020/07/11 - [Android/Tips] - error: cannot find symbol this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);

2020/07/11 - [Android/Rooting] - LG 펌웨어 추출 및 OS 다운그레이드 (kdz file)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (4/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (3/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (2/4)

2020/07/11 - [Android/Rooting] - 안드로이드 Fridump 환경설정 (1/4)

2020/06/16 - [OS/Mac OS X] - duplicate symbol 에러 해결

2020/06/12 - [iOS/Jailbreak] - Fridump 사용법 (4/4) - 결과물 바이너리 검색

2020/06/03 - [iOS/Objective-C] - NSString <-> CBUUID

2020/06/03 - [iOS/Swift] - 위치서비스(location service) 활성화 여부 체크

2020/06/02 - [개발노트] - Luhn 알고리즘

2020/06/01 - [iOS/Swift] - The Ultimate Guide to WKWebView

2020/06/01 - [iOS/Tips] - WKWebView에서 로컬 웹 파일 및 리소스 로드

반응형
블로그 이미지

SKY STORY

,
반응형

다음과 같은 에러 발생시  다음과 같이 캐시 폴더를 삭제하도록 하자

~/.gradle/caches

 

또는 다음과 같이 gradle 의존성 업데이트 명령을 통해 해결할 수 있다.

gradle --refresh-dependencies

 

 

반응형
블로그 이미지

SKY STORY

,
반응형

아래와 같이 에러 발생시 

error: cannot find symbol

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);

 

다음과 같이 수정

this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);

반응형
블로그 이미지

SKY STORY

,