반응형

방법 1

// Swift
let sd = self.view.window.windowScene.delegate

// Objective-C
SceneDelegate *sd = self.view.window.windowScene.delegate;

 

방법 2

Swift :

//
// UIResponder+Scene.swift
//

import UIKit

@available(iOS 13.0, *)
extension UIResponder {
    @objc var scene: UIScene? {
        return nil
    }
}

@available(iOS 13.0, *)
extension UIScene {
    @objc override var scene: UIScene? {
        return self
    }
}

@available(iOS 13.0, *)
extension UIView {
    @objc override var scene: UIScene? {
        if let window = self.window {
            return window.windowScene
        } else {
            return self.next?.scene
        }
    }
}

@available(iOS 13.0, *)
extension UIViewController {
    @objc override var scene: UIScene? {
        // Try walking the responder chain
        var res = self.next?.scene
        if (res == nil) {
            // That didn't work. Try asking my parent view controller
            res = self.parent?.scene
        }
        if (res == nil) {
            // That didn't work. Try asking my presenting view controller 
            res = self.presentingViewController?.scene
        }

        return res
    }
}

 

Objective-C :

//
// UIResponder+Scene.h
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface UIResponder (Scene)

@property (nonatomic, readonly, nullable) UIScene *scene API_AVAILABLE(ios(13.0));

@end

NS_ASSUME_NONNULL_END





// 
// UIResponder+Scene.m
//

#import "ViewController+Scene.h"

@implementation UIResponder (Scene)

- (UIScene *)scene {
    return nil;
}

@end

@implementation UIScene (Scene)

- (UIScene *)scene {
    return self;
}

@end

@implementation UIView (Scene)

- (UIScene *)scene {
    if (self.window) {
        return self.window.windowScene;
    } else {
        return self.nextResponder.scene;
    }
}

@end

@implementation UIViewController (Scene)

- (UIScene *)scene {
    UIScene *res = self.nextResponder.scene;
    if (!res) {
        res = self.parentViewController.scene;
    }
    if (!res) {
        res = self.presentingViewController.scene;
    }

    return res;
}

@end

 

원문 : 
stackoverflow.com/questions/56588843/uiapplication-shared-delegate-equivalent-for-scenedelegate-xcode11

 

반응형

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

ARC or Non-ARC Compile Flag 설정  (0) 2021.02.05
String to CGFloat  (0) 2021.01.06
앱 호출 (URL scheme)  (0) 2021.01.05
URL query 파싱 및 json string 변환  (0) 2020.12.17
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
블로그 이미지

SKY STORY

,
반응형

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

앱에서 앱으로 호출

Info.plist 설정 후 OpenURL함수를 통해 호출한다.

 

Info.plist 설정

  • 호출하는 쪽 URL Scheme 설정 (샘플앱 명 : sendApp)

 

  • 호출받는 쪽 URL Scheme 설정 (샘플앱 명 : receiveApp)

 

※ Xcode 11부터 SceneDelegate가 기본 iOS 앱 프로젝트 템플릿으로 자동으로 추가되면서 AppDelegate의 openURL 함수가 호출 되지 않으므로 SceneDelegate의 openURLContexts 함수에서 처리해야 한다.

// SceneDelegate.swift
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
    if let url = URLContexts.first?.url {
        print("url = \(url)")
    }
}
// SceneDelegate.m
- (void)scene:(UIScene *)scene openURLContexts:(NSSet *)URLContexts {
    UIOpenURLContext *context = URLContexts.anyObject;
    NSURL *url = context.URL;
    NSLog(@"url = %@",url);
}
// Swift 앱 호출 샘플코드
if UIApplication.shared.canOpenURL(url) {
    if #available(iOS 10.0, *) {
        UIApplication.shared.open(url, options: [:], completionHandler: { (success) in

        })
    } else {
        UIApplication.shared.openURL(url)
    }
}
        
// Objective-C 앱 호출 샘플코드
if (YES == [[UIApplication sharedApplication] canOpenURL:url]) {
    if (@available(iOS 10.0, *)) {
        [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) {}];
    } else {
        [[UIApplication sharedApplication] openURL:url];
    }
    return;
}

 

 

모바일 웹에서 앱 호출

  • 웹 브라우저(사파리,크롬 등)을 통한 웹사이트에서 앱 호출
window.location = "receiveApp://";

 

  • 웹뷰(WKWebView)를 통한 웹사이트에서 앱 호출

      ※ 주의 : 이 경우 해당 URL scheme이 호출될 때 직접 코드로 호출 해 주어야 한다. 

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    guard let url = navigationAction.request.url else {
        decisionHandler(.cancel)
        return
    }
    
    if (url.absoluteString.hasPrefix("receiveApp://")) {
        if UIApplication.shared.canOpenURL(url) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(url, options: [:], completionHandler: { (success) in
                    
                })
            } else {
                UIApplication.shared.openURL(url)
            }
        }
        decisionHandler(.cancel)
        return
    }
    
    ... 중간생략 ...
}

 

스마트폰 BTC 채굴앱

https://get.cryptobrowser.site/34473645

 

Earn coins while browsing the web

Earn bitcoins while watching videos, chatting, or playing online. It has never been so easy to increase your income! Tell your friends about CryptoTab Browser, invite them to join, and earn more together. Grow your network—get more profit!

get.cryptobrowser.site

 

2021/01/06 - [iOS/Swift] - String to CGFloat

2021/01/05 - [iOS/Tips] - SceneDelegate 포인터 구하기

2021/01/05 - [iOS/Tips] - 앱 호출 (URL scheme)

2020/12/24 - [개발노트] - 라이선스 종류

2020/12/24 - [OS/Mac OS X] - MacBook을 AP로 설정하는 방법

2020/12/18 - [Arduino] - Bit Rate, Baud Rate

2020/12/18 - [Arduino] - RS232 Serial 통신 불량체크

2020/12/17 - [프로그래밍/Java] - Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

2020/12/17 - [OS/Mac OS X] - OpenSSL을 이용한 Key 정보 Text 변환

2020/12/17 - [프로그래밍/Java] - RSA 암복호화

2020/12/17 - [iOS/Tips] - URL query 파싱 및 json string 변환

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

반응형

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

String to CGFloat  (0) 2021.01.06
SceneDelegate 포인터 구하기  (0) 2021.01.05
URL query 파싱 및 json string 변환  (0) 2020.12.17
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
bundle id 알아내기  (0) 2020.12.14
블로그 이미지

SKY STORY

,

라이선스 종류

개발/Note 2020. 12. 24. 11:33
반응형

라이선스 종류

  • Apache License
     
    아파치 라이선스는 아파치소프트웨어재단이 자기네 SW에 적용하기 위해 자체적으로 만 든 라이선스다. 소스코드 공개 의무 같은 의무사항은 없지만, 아파치 라이선스 소스코드를 수정해 배포하는 경우 아파치 라이선스 버전 2.0을 꼭 포함시켜야 하며 아파치재단에서 만 든 소프트웨어임을 밝혀야 한다.
     
    적용 사례 : 안드로이드(v2.0), 하둡(v2.0)

  • GNU(Gnu is Not Unix) General Public License(GPL)
     
    자유소프트웨어재단에서 만든 라이선스다. GNU 프로젝트로 배포하는 소프트웨어 (Emacs, GNU 디버거(GDB), GNU 컴파일러 모음(GCC) )에 적용하기 위해 리처드 스톨만이 만들었다. 가장 큰 특징은 자유소프트웨어재단답게 가장 강력한 제약 조건을 포함 하고 있는 카피레프트 조항이다. GPL 프로그램은 어떤 목적으로, 어떤 형태로든 사용할 수 있지만 사용하거나 변경된 프로그램을 배포하는 경우 무조건 동일한 라이선스 즉, GPL로 공 개해야 한다.
     
    적용 사례 : 모질라 파이어폭스(v2.0), 리눅스 커널(v2.0), (v2.0), 마리아
    DB(v2.0), 워드프레스(v2.0), 드루팔(v2.0)

  • GNU Affero GPL(AGPL)
    – GPL
    을 기반으로 만든 라이선스로 버전1, 2는 아페로, 가장 최신 버전인 버전3은 자유소 프트웨어재단에 의해 개발됐다. 수정한 소스코드를 서버에서만 사용하는 개발자가 그 프로 그램을 배포하지 않을 경우 사용자는 소스코드를 가질 수가 없는 문제를 해결하기 위해 마련 됐다. 서버에서 프로그램을 실행해 다른 사용자들과 통신하면, 실행되고 있는 프로그램의 소 스코드를 사용자들이 다운로드할 수 있게 해야 한다는 독특한 조항을 담고 있다.
     
    적용 사례 : 몽고DB(v3.0)

  • GNU Lesser GPL(LGPL)
     
    자유소프트웨어재단의 강력한 철학이 담긴 GPL의 카피레프트 조항을 보완하기 위해 만든 라이선스다. GPL은 단순히 소프트웨어를 사용하기만 하더라도 해당 소스코드를 GPL로 공 개해야 하는 부담감 때문에 상용 소프트웨어로 쓰기 부담스럽다는 단점이 있다. 그래서 좋은 자유 소프트웨어 제품이 더 많이 쓰이고 표준이 되도록 유도하기 위해 단순한 라이브러리·모 듈 링크를 허용한 라이선스이다. 원래는 한정된 라이브러리에만 적용하려는 의도로 ‘Library GPL’이라는 이름을 붙였으나, 모든 라이브러리에 적용된다는 오해를 사 ‘Lesser GPL’로 변경됐다.
     
    적용 사례 : 모질라 파이어폭스(v2.1)

  • MIT License
    – MIT 
    라이선스는 미국 매사추세츠공과대학교(MIT)에서 해당 대학 SW 공학도들을 돕기 위해 개발한 라이선스다. 라이선스와 저작권 관련 명시만 지켜주면 되는 라이선스로, 가장 느슨한 조건을 가진 라이선스 중 하나이기 때문에 인기가 많다.
     
    적용 사례 : 부트스트랩 , Angular.js, Backbone.js, jQuery

  • Artistic License
     
    펄 프로그래밍 언어를 사용하던 래리 월이 표준 펄 기능을 위해 만든 라이선스다. 이 단어의 어원은 문학에서 문법상 틀린 표현이라도 시적인 효과를 위해 허용한다는 걸 의미하는 ‘Articstic License'(시적 허용)를 참조해 만들어졌다.
    – 적용 사례 NPM(Node Package Manager)(v2.0)

  • Eclipse License
     
    이클립스사에서 비즈니스 환경에 적합하도록 만든 기업 친화적인 라이선스로, 강력한 카피 레프트 조항이 담긴 GPL보다 제약 조건이 완화된 라이선스이다.
     
    적용 사례 : 이클립스(v1.0)

  • Berkeley Software Distribution(BSD) License
     
    버클리의 캘리포니아대학에서 배포하는 공개 SW 라이선스다. BSD 자체가 공공기관에서 만들어낸 것이므로 공공의 몫으로 돌려주자는 의미가 강하므로, 라이선스 자체에는 아무런 제한 없이 누구나 자신의 용도로 사용할 수 있다. 라이선스 및 저작권 표시 조건 외엔 제약이 없는, 굉장히 자유로운 라이선스 중 하나이다.
     
    적용 사례 : Nginx(The BSD 2-Clause License)

  • Mozilla Public License(MPL)
     
    모질라 공용 허가서는 과거 넷스케이프 웹브라우저의 소스코드를 공개하기 위해 개발된 라 이선스다. 초기 1.0버전은 넷스케이프 커뮤니케이션의 변호사였던 밋첼 베이커가 작성했고, 1.1 2.0버전은 모질라재단이 작성했다. MPL의 특징은 소스코드와 실행파일의 저작권을 분리했다는 점이다. 수정한 소스코드는 MPL로 공개하고 원저작자에게 수정한 부분에 대해 알려야 하지만, 실행파일은 독점 라이선스로 배포할 수 있다. 즉 사용한 MPL 소프트웨어와 수정한 MPL 소프트웨어에 대한 공개 의무만 가지며, 별도의 소스코드와 실행파일은 독점 라이선스를 가질 수 있다.
     
    적용 사례 : 모질라 파이어폭스(v1.1), 모질라 썬더버드(v1.1)

 

조건표

라이선스

필수 사항(Required)

허락 조건(Permitted)

금지 조건(Forbidden)

Apache License

제약조건:

라이선스 저작권 명시

변경사항 안내

상업적 이용 가능

배포 가능

수정 가능

특허 신청 가능

사적 이용 가능

2 라이선스

보증책임 없음

상표권 침해 금지

GPL

v2.0/v3.0

제약조건:

수정한 소스코드 혹은 GPL 소스코드를 활용한 소프트웨어 모두 GPL 공개

라이선스 저작권 명시

변경사항 안내

상업적 이용 가능

배포 가능

수정 가능

특허 신청 가능

사적 이용 가능

보증책임 없음

2 라이선스

GNU AGPL

(Affero GPL)

v3.0

제약조건:최상

수정한 소스코드 혹은 AGPL 소스코드를 활용한 소프트웨어 모두 AGPL 공개

라이선스 저작권 명시

변경사항 안내

네트워크상 소프트웨어 사용자에게 소스코드 공개

상업적 이용 가능

배포 가능

수정 가능

특허 신청 가능

사적 이용 가능

보증책임 없음

2 라이선스

GNU LGPL

(Lesser GPL)

v2.1/v3.0

제약조건:

수정한 소스코드 LGPL 공개(단순 활용시 공개 의무 없음)

라이선스 저작권 명시

상업적 이용 가능

배포 가능

수정 가능

특허 신청 가능

사적 이용 가능

2 라이선스

보증책임 없음

MIT

License

제약조건:

라이선스 저작권 명시

상업적 이용 가능

배포 가능

수정 가능

사적 이용 가능

2 라이선스

보증책임 없음

Artistic

License

제약조건:

라이선스 저작권 명시

변경사항 안내

상업적 이용 가능

배포 가능

수정 가능

사적 이용 가능

2 라이선스

보증책임 없음

상표권 침해 금지

Eclipse

License

제약조건:

수정한 소스코드 Eclipse 공개(단순 활용시 공개 의무 없음)

라이선스 저작권 명시

상업적 이용 가능

배포 가능

수정 가능

특허 신청 가능

사적 이용 가능

2 라이선스

보증책임 없음

BSD

License

제약조건:

라이선스 저작권 명시

상업적 이용 가능

배포 가능

수정 가능

사적 이용 가능

2 라이선스

보증책임 없음

MPL v2.0

(Mozilla Public License)

제약조건:

수정한 소스코드 MPL 공개(단순 활용시 공개 의무 없음)

라이선스 저작권 명시

특허기술이 구현된 프로그램의 경우 관련 사실을 ‘LEGAL’파일에 기록하여 배포

상업적 이용 가능

배포 가능

수정 가능

특허 신청 가능

사적 이용 가능

2 라이선스

 

 

 

2020/12/24 - [OS/Mac OS X] - MacBook을 AP로 설정하는 방법

2020/12/18 - [Arduino] - Bit Rate, Baud Rate

2020/12/18 - [Arduino] - RS232 Serial 통신 불량체크

2020/12/17 - [프로그래밍/Java] - Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

2020/12/17 - [OS/Mac OS X] - OpenSSL을 이용한 Key 정보 Text 변환

2020/12/17 - [프로그래밍/Java] - RSA 암복호화

2020/12/17 - [iOS/Tips] - URL query 파싱 및 json string 변환

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

 

반응형
블로그 이미지

SKY STORY

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

SKY STORY

,
반응형

다음과 같은 경고메시지 출력 안되도록 설정하는 방법은 다음과 같다.

Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

 

‘Preferences…’ 선택

 

‘Aync Stack Traces’ 선택

 

‘Instrumenting agent (requires debugger restart)’ 체크 없앰 

 

반응형

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

라이선스 종류  (0) 2020.12.24
MacBook을 AP로 설정하는 방법  (0) 2020.12.24
OpenSSL을 이용한 Key 정보 Text 변환  (0) 2020.12.17
RSA 암복호화  (0) 2020.12.17
Code 128 Barcode의 Check Digit 계산방법  (0) 2020.12.16
블로그 이미지

SKY STORY

,
반응형

rsa공개키 생성후 파일로 전달하므로 파일을 변환하여 공개/개인 키 구하는 방법을 알아보자.

 

openssl rsa -text -in public.key -inform DER -pubin

(base) netcanis@netcanis-MacBook-Pro KeyPair % openssl rsa -text -in public.key -inform DER -pubin
RSA Public-Key: (1024 bit)
Modulus:
    00:9f:41:52:c2:d0:82:17:18:29:6e:17:3a:ac:a2:
    1a:8c:de:17:5c:89:c1:15:18:78:90:88:53:03:92:
    7e:36:ab:83:26:7d:f5:4b:37:8e:2e:d9:f3:d9:7e:
    e1:b9:0b:fd:99:c9:f4:67:06:c0:df:9f:29:51:2f:
    2b:40:0b:9d:32:4c:47:38:02:f7:6c:d9:d1:72:b1:
    cb:f1:11:90:18:ca:28:dc:00:e3:f8:ce:a9:f9:b7:
    5b:d1:62:ae:5b:06:f8:b2:40:93:bb:31:c1:3a:63:
    76:82:65:11:76:67:db:8a:5d:76:2b:b0:42:ed:31:
    24:a1:76:4b:cb:53:ed:a8:7b
Exponent: 65537 (0x10001)
writing RSA key
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfQVLC0IIXGCluFzqsohqM3hdc
icEVGHiQiFMDkn42q4MmffVLN44u2fPZfuG5C/2ZyfRnBsDfnylRLytAC50yTEc4
Avds2dFyscvxEZAYyijcAOP4zqn5t1vRYq5bBviyQJO7McE6Y3aCZRF2Z9uKXXYr
sELtMSShdkvLU+2oewIDAQAB
-----END PUBLIC KEY-----

 

openssl rsa -text -in private.key -inform DER

(base) netcanis@netcanis-MacBook-Pro KeyPair % openssl rsa -text -in private.key -inform DER
RSA Private-Key: (1024 bit, 2 primes)
modulus:
    00:9f:41:52:c2:d0:82:17:18:29:6e:17:3a:ac:a2:
    1a:8c:de:17:5c:89:c1:15:18:78:90:88:53:03:92:
    7e:36:ab:83:26:7d:f5:4b:37:8e:2e:d9:f3:d9:7e:
    e1:b9:0b:fd:99:c9:f4:67:06:c0:df:9f:29:51:2f:
    2b:40:0b:9d:32:4c:47:38:02:f7:6c:d9:d1:72:b1:
    cb:f1:11:90:18:ca:28:dc:00:e3:f8:ce:a9:f9:b7:
    5b:d1:62:ae:5b:06:f8:b2:40:93:bb:31:c1:3a:63:
    76:82:65:11:76:67:db:8a:5d:76:2b:b0:42:ed:31:
    24:a1:76:4b:cb:53:ed:a8:7b
publicExponent: 65537 (0x10001)
privateExponent:
    25:ca:9a:99:20:61:be:99:3d:3b:a2:c7:89:af:ee:
    1c:ff:97:0b:9e:a4:f3:1c:9b:7f:b0:da:02:3f:01:
    34:77:fe:e7:63:7c:92:1c:dc:e0:c1:57:dc:84:ff:
    8b:aa:0c:c4:31:e8:8d:8a:4c:ba:c4:4a:49:b9:a7:
    c9:ca:f7:c2:57:38:df:0a:95:27:da:42:66:b0:55:
    03:75:61:53:42:57:f6:8d:f5:d5:0c:f4:81:a9:6c:
    ae:37:9f:e1:39:02:69:11:ec:55:67:31:08:0b:b8:
    66:aa:19:6c:e5:f0:87:5a:16:c5:12:98:71:df:84:
    6c:e0:1a:ac:9b:b6:96:01
prime1:
    00:e5:8c:be:c1:67:56:95:fa:6b:39:8e:43:12:5b:
    fd:e1:e6:2f:86:cb:12:87:df:6d:19:d3:a7:a9:6c:
    70:c5:6f:11:92:4a:e8:ee:d1:70:0c:5d:82:ca:6c:
    03:e6:2a:7d:ce:49:9b:fd:39:3b:71:4a:9f:75:89:
    18:a9:95:23:4d
prime2:
    00:b1:9b:07:6b:e5:a4:c2:9e:1f:eb:24:98:c1:7e:
    c2:e1:3a:5c:d7:20:c0:4e:02:24:e1:3f:15:1c:0d:
    e2:78:c9:54:7e:86:54:92:e5:88:05:f8:90:6b:3c:
    c5:be:4f:61:b7:c3:c0:88:69:7d:34:f3:16:78:bc:
    2a:ec:23:06:e7
exponent1:
    00:b4:ff:2c:2d:dd:68:85:6b:65:fe:84:f0:d7:da:
    17:2e:76:cc:c4:b0:fc:94:8c:14:3f:88:07:2c:6c:
    e7:e2:95:38:3a:ac:bc:4c:0a:72:1a:1d:e5:91:ec:
    67:8a:a5:b8:7a:de:c9:93:79:fc:27:d1:5a:38:57:
    f8:4d:46:de:05
exponent2:
    00:aa:75:94:a5:e5:fe:40:1b:eb:9e:8f:bd:5c:d9:
    00:c9:92:6e:50:bb:4a:56:94:90:38:ef:86:9f:2a:
    64:56:71:44:fb:3a:8a:29:82:cb:0e:90:06:6c:26:
    23:d4:07:f4:4d:9f:3f:46:ad:98:52:1d:8d:4f:cb:
    a9:96:81:f7:b9
coefficient:
    0a:6e:ee:7a:01:58:9b:40:32:e0:d1:d7:d3:a1:45:
    c2:3b:60:9b:84:41:26:7d:01:bf:ec:db:bb:c9:5e:
    57:34:ef:e1:62:9b:a5:0b:b2:21:88:63:07:e5:ab:
    1d:9e:cf:f4:83:ed:5f:0c:78:6a:62:34:e8:51:f8:
    85:13:d3:7c
writing RSA key
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCfQVLC0IIXGCluFzqsohqM3hdcicEVGHiQiFMDkn42q4MmffVL
N44u2fPZfuG5C/2ZyfRnBsDfnylRLytAC50yTEc4Avds2dFyscvxEZAYyijcAOP4
zqn5t1vRYq5bBviyQJO7McE6Y3aCZRF2Z9uKXXYrsELtMSShdkvLU+2oewIDAQAB
AoGAJcqamSBhvpk9O6LHia/uHP+XC56k8xybf7DaAj8BNHf+52N8khzc4MFX3IT/
i6oMxDHojYpMusRKSbmnycr3wlc43wqVJ9pCZrBVA3VhU0JX9o311Qz0galsrjef
4TkCaRHsVWcxCAu4ZqoZbOXwh1oWxRKYcd+EbOAarJu2lgECQQDljL7BZ1aV+ms5
jkMSW/3h5i+GyxKH320Z06epbHDFbxGSSuju0XAMXYLKbAPmKn3OSZv9OTtxSp91
iRiplSNNAkEAsZsHa+Wkwp4f6ySYwX7C4Tpc1yDATgIk4T8VHA3ieMlUfoZUkuWI
BfiQazzFvk9ht8PAiGl9NPMWeLwq7CMG5wJBALT/LC3daIVrZf6E8NfaFy52zMSw
/JSMFD+IByxs5+KVODqsvEwKchod5ZHsZ4qluHreyZN5/CfRWjhX+E1G3gUCQQCq
dZSl5f5AG+uej71c2QDJkm5Qu0pWlJA474afKmRWcUT7OoopgssOkAZsJiPUB/RN
nz9GrZhSHY1Py6mWgfe5AkAKbu56AVibQDLg0dfToUXCO2CbhEEmfQG/7Nu7yV5X
NO/hYpulC7IhiGMH5asdns/0g+1fDHhqYjToUfiFE9N8
-----END RSA PRIVATE KEY-----

 

2020/12/17 - [Android/Java] - RSA 암복호화

2020/12/17 - [iOS/Tips] - URL query 파싱 및 json string 변환

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

반응형
블로그 이미지

SKY STORY

,

RSA 암복호화

개발/Note 2020. 12. 17. 16:18
반응형

결제 관련 API 연동(VAN, PG, 간편결제 등) 할 경우 RSA암복호화 과정을 거치게되는데

이 부분에 대한 샘플 코드를 작성해 보았다.

 

Apache Commons Codec 다운로드

commons.apache.org/proper/commons-codec/

 

Codec – Home

Apache Commons Codec Apache Commons Codec (TM) software provides implementations of common encoders and decoders such as Base64, Hex, Phonetic and URLs. Impetus Codec was formed as an attempt to focus development effort on one definitive implementation of

commons.apache.org

 

프로젝트 라이브러리에 추가. 

 

PublicKey와 PrivateKey 파일을 생성

package com.ubpay.keypair;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;

//
// RSA Key 파일 생성
//
// Created by netcanis on 2019/04/29.
// Copyright © 2019 netcanis. All rights reserved.
//

// Download Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/download_codec.cgi

public class GenKeys
{
	private KeyPairGenerator keyGen;
	private KeyPair pair;
	private PrivateKey privateKey;
	private PublicKey publicKey;

	// RSA 초기화 및 키 생성 
	public GenKeys(int keysize) throws NoSuchAlgorithmException, NoSuchProviderException {
		this.keyGen = KeyPairGenerator.getInstance("RSA");
		this.keyGen.initialize(keysize);
		this.pair = this.keyGen.generateKeyPair();
		this.publicKey = pair.getPublic();
		this.privateKey = pair.getPrivate();
	}

	public PublicKey getPublicKey() {
		return this.publicKey;
	}
	
	public PrivateKey getPrivateKey() {
		return this.privateKey;
	}
	
	public void writeToFile(String path, byte[] key) throws IOException {
		File f = new File(path);
		f.getParentFile().mkdirs();

		FileOutputStream fos = new FileOutputStream(f);
		fos.write(key);
		fos.flush();
		fos.close();
	}

	
	
	public static void main(String[] args) {
		GenKeys genKeys;
		try {
			// 1024bit key pair 생성  
			genKeys = new GenKeys(1024);
			
			System.out.println(genKeys.publicKey);
			System.out.println(genKeys.privateKey);
			
			// 바이너리 파일로 저장 
			genKeys.writeToFile("KeyPair/public.key", genKeys.getPublicKey().getEncoded());
			genKeys.writeToFile("KeyPair/private.key", genKeys.getPrivateKey().getEncoded());
			
		} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
			System.err.println(e.getMessage());
		} catch (IOException e) {
			System.err.println(e.getMessage());
		}
	}
}

 

생성 결과

 

생성된 키를 이용하여 암복호화 테스트

package com.ubpay.rsaTest;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;


//
// RSA 암복호화 및 테스트
//
// Created by netcanis on 2019/04/29.
// Copyright © 2019 netcanis. All rights reserved.
//

public class RSAEncryption
{
	private Cipher cipher;
	
	public RSAEncryption() throws NoSuchAlgorithmException, NoSuchPaddingException{
		this.cipher = Cipher.getInstance("RSA");
	}
	
	// 주어진 파일을 byte array로 읽기 
	public byte[] getFileInBytes(File f) throws IOException{
		FileInputStream fis = new FileInputStream(f);
		byte[] fbytes = new byte[(int) f.length()];
		fis.read(fbytes);
		fis.close();
		return fbytes;
	}
		
	// X509EncodedKey
	public PublicKey getPublic(String filename) throws Exception {
		byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
		X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		return kf.generatePublic(spec);
	}

	// PKCS8EncodedKeySpec
	public PrivateKey getPrivate(String filename) throws Exception {
		byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
		
		//byte[] decoded = Base64.getDecoder().decode(keyBytes);
		//println(new String(decoded));    // Outputs "Hello"
		
		//Base64 codec = new Base64();
		//byte[] decoded = codec.decode(keyBytes);
		//System.out.println( new String(decoded) );    // Outputs "Hello"
		
		PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
		KeyFactory kf = KeyFactory.getInstance("RSA");
		return kf.generatePrivate(spec);
	}
	
	// public key로 암호화 
	public String encrypt(String str, PublicKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException{
		this.cipher.init(Cipher.ENCRYPT_MODE, key);
		return Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
	}
	
	// private key로 복호화 
	public String decrypt(String str, PrivateKey key) throws InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException{
		this.cipher.init(Cipher.DECRYPT_MODE, key);
		return new String(cipher.doFinal(Base64.decodeBase64(str)), "UTF-8");
	}

	// hex to byte[]
	public byte[] hexStringToByteArray(String s) {
	    int len = s.length();
	    byte[] data = new byte[len / 2];
	    for (int i = 0; i < len; i += 2) {
	        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
	                             + Character.digit(s.charAt(i+1), 16));
	    }
	    return data;
	}
	
	// byte[] to hex
	public String byteArrayToHexString(byte[] bytes){ 
		StringBuilder sb = new StringBuilder(); 
		for(byte b : bytes){ 
			sb.append(String.format("%02X", b&0xff)); 
		} 
		return sb.toString(); 
	} 

	
    
	public static void main(String[] args) throws Exception {
		RSAEncryption ac = new RSAEncryption();
		
		// 공개키
		PublicKey publicKey = ac.getPublic("KeyPair/public.key");
		// 개인키 
		PrivateKey privateKey = ac.getPrivate("KeyPair/private.key");
		
		// 원문 
		String msg = "test message";
		
		
		System.out.println("----------------------------------------------------");
		System.out.println(":::: TEST 암호화 및 복호화 ::::");
		
		// 암호화 원문 BASE64
		String encryptedString = ac.encrypt(msg, publicKey);
		// 복호화
		String decryptedString = ac.decrypt(encryptedString, privateKey);
		
		System.out.println("----------------------------------------------------");
		System.out.println(
				"원문 = " + msg + "\n" +
				"공개키 암호화 = " + encryptedString + "\n" +
				"개인키 복호화 = " + decryptedString
				);
		System.out.println("----------------------------------------------------");
	}
}




결과 :
--------------------------------------------------------------------------
:::: TEST 암호화 및 복호화 ::::
--------------------------------------------------------------------------
원문 = test message
공개키 암호화 = gz2WQHCyHxsPV5IB0xehk8RSbGrhGR86nQRGj09CphxiIAjRsCony8myWfRGJgDVyK6ixuK13gtL/20j4K5c1GcCKxPT9xqYaa6tBxTakho9klHNAO6KhQJK0nGeIQRDpZ1qecB6pPMsRqVVO5rb81NFqbjLKMoqi2tO1f55/iM=
개인키 복호화 = test message
--------------------------------------------------------------------------

 

2020/12/17 - [OS/Mac OS X] - OpenSSL을 이용한 Key 정보 Text 변환

2020/12/17 - [iOS/Tips] - URL query 파싱 및 json string 변환

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

2020/12/10 - [개발노트] - Bluetooth UUID

 

반응형
블로그 이미지

SKY STORY

,
반응형
// 사용 방법
let url = URL(string:"https://www.test.com/myconmand?param1=ASDF&param2=1234")!
let qParams = url.queryParams().toJsonString()
let param2 = url.valueOf("param2")

print(
    """
    scheme      = \(url.scheme ?? "")
    host        = \(url.host ?? "")
    path        = \(url.path)
    query       = \(url.query ?? "")
    qParams     = \(qParams)
    param2      = \(param2 ?? "")
    """
)

// 결과 
scheme      = https
host        = www.test.com
path        = /myconmand
query       = param1=ASDF&param2=1234
qParams     = {"param1":"ASDF","param2":"1234"}
param2      = 1234
extension URL {
    
    func queryParams() -> [String:Any] {
        let queryItems = URLComponents(url: self, resolvingAgainstBaseURL: false)?.queryItems
        let queryTuples: [(String, Any)] = queryItems?.compactMap{
            guard let value = $0.value else { return nil }
            return ($0.name, value)
        } ?? []
        return Dictionary(uniqueKeysWithValues: queryTuples)
    }
    
    func valueOf(_ queryParamaterName: String) -> String? {
        guard let url = URLComponents(string: self.absoluteString) else { return nil }
        return url.queryItems?.first(where: { $0.name == queryParamaterName })?.value
    }
    
}
extension Dictionary {

    func toJsonData() -> Data {
        var jsonData: Data?
        do {
            jsonData = try JSONSerialization.data(withJSONObject: self, options: .init(rawValue: 0))
        } catch {
            print(error)
        }
        return jsonData!
    }

    func toJsonDataPrettyPrinted() -> Data {
        var jsonData: Data?
        do {
            jsonData = try JSONSerialization.data(withJSONObject: self, options: JSONSerialization.WritingOptions.prettyPrinted)
        } catch {
            print(error)
        }
        return jsonData!
    }
    
    func toJsonString() -> String {
        return toJsonData().toString()
    }
    
    func toPrettyPrintedJsonString() -> String {
        return toJsonDataPrettyPrinted().toString()
    }
    
}
extension Data {
    func hexString() -> String {
        return map { String(format: "%02hhx", $0) }.joined()
    }
    
    func toString() -> String {
        return String(data: self, encoding: String.Encoding.utf8)!
    }
}

 

2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법

2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)

2020/12/14 - [iOS/Tips] - bundle id 알아내기

2020/12/12 - [AI/Algorithm] - 2D 충돌처리

2020/12/11 - [iOS/Swift] - UIViewController 스위칭

2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)

2020/12/11 - [개발노트] - 특수문자 발음

2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)

2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)

2020/12/10 - [iOS/Tips] - Custom UserAgent 설정

2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거

2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기

2020/12/10 - [개발노트] - Bluetooth UUID

2020/12/08 - [개발노트] - 모바일 앱 메모리덤프 이슈 해결방법 

반응형

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

SceneDelegate 포인터 구하기  (0) 2021.01.05
앱 호출 (URL scheme)  (0) 2021.01.05
디버깅 차단 처리 (Anti Debug)  (0) 2020.12.15
bundle id 알아내기  (0) 2020.12.14
UIViewController 스위칭  (0) 2020.12.11
블로그 이미지

SKY STORY

,