반응형
UIImage *image1 = [UIImage imageNamed:@"image1.png"];
UIImage *image2 = [UIImage imageNamed:@"image2.png"];

CGSize size = CGSizeMake(image1.size.width, image1.size.height + image2.size.height);

UIGraphicsBeginImageContext(size);

[image1 drawInRect:CGRectMake(0,0,size.width, image1.size.height)];
[image2 drawInRect:CGRectMake(0,image1.size.height,size.width, image2.size.height)];

UIImage *finalImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

//Add image to view
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, finalImage.size.width, finalImage.size.height)];
imageView.image = finalImage;
[self.view addSubview:imageView];

 

2020/05/29 - [프로그래밍/C, C++] - Base64 encode / decode in C++

2020/05/29 - [OS/Mac OS X] - iPhone SDK location on hard drive

2020/05/29 - [iOS/Objective-C] - NSString <-> CBUUID 변환

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

반응형

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

WKWebView에서 history back 처리  (0) 2020.05.29
OpenGL ES View Snapshot  (0) 2020.05.29
NSString <-> CBUUID 변환  (0) 2020.05.29
SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제 (1/2)  (0) 2020.05.28
Array <-> Data 변환  (0) 2020.05.26
블로그 이미지

SKY STORY

,
반응형

NSString -> CBUUID

NSString *string = [@"233R194013780790" toUUID];
CBUUID *harexUUID = [CBUUID UUIDWithString:string];
// 결과 :
// 32333352-3139-3430-3133-373830373930

 

CBUUID -> NSString

// 32333352-3139-3430-3133-373830373930
NSString *uuidString = [harexUUID representativeString];
NSString *tid = [harexUUID toString];
// 결과 :
// 233R194013780790

 

관련 함수 :

// String to Hexadecimal String
-(NSString *)toHex {
    char *utf8 = (char *)[self UTF8String];
    NSMutableString *hex = [NSMutableString string];
    while ( *utf8 ) {
        [hex appendFormat:@"%02X" , *utf8++ & 0x00FF];
    }
    return [NSString stringWithFormat:@"%@", hex];
}

// Hexadecimal String to NSData
-(NSData *)hex2Data {
    NSMutableData *stringData = [[NSMutableData alloc] init];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [self length] / 2; i++) {
        byte_chars[0] = [self characterAtIndex:i*2];
        byte_chars[1] = [self characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [stringData appendBytes:&whole_byte length:1];
    }
    return stringData;
}

-(CBUUID *)toCBUUID {
    if (NO == [self isValidUUID]) {
        NSLog(@"포멧 비정상.");
        return nil;
    }
    return [CBUUID UUIDWithString:self];
}

-(BOOL)isValidUUID {
    return (BOOL)[[NSUUID alloc] initWithUUIDString:self];
}

// 문자열을 hex로 변경한뒤 UUID포멧으로 변경
-(NSString *)toUUID {
    NSString *string = self;
    if (string.length < 16) {
        NSString *spaceString = @"";
        for (NSInteger i=0; i<(16 - string.length); ++i) {
            spaceString = [spaceString stringByAppendingString:@" "];
        }
        // 길이가 작을 경우 앞쪽에 공백추가
        //string = [NSString stringWithFormat:@"%@%@", spaceString, self];

        // 길이가 작을 경우 뒤쪽에 공백추가
        string = [NSString stringWithFormat:@"%@%@", self, spaceString];
    }
    
    NSData *data = [string toData];
    NSUInteger bytesToConvert = [data length];
    const unsigned char *uuidBytes = [data bytes];
    NSMutableString *outputString = [NSMutableString stringWithCapacity:16];
    
    for (NSUInteger currentByteIndex = 0; currentByteIndex < bytesToConvert; currentByteIndex++) {
        switch (currentByteIndex) {
            case 3:
            case 5:
            case 7:
            case 9:[outputString appendFormat:@"%02X-", uuidBytes[currentByteIndex]]; break;
            default:[outputString appendFormat:@"%02X", uuidBytes[currentByteIndex]];
        }
        //SLog(@"%@", outputString);
    }

 

 

 

2020/05/29 - [개발노트] - HTTP Content-Type

2020/05/28 - [iOS/Swift] - SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data 변환

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

 

반응형

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

OpenGL ES View Snapshot  (0) 2020.05.29
Merge two different images in swift  (0) 2020.05.29
SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제 (1/2)  (0) 2020.05.28
Array <-> Data 변환  (0) 2020.05.26
UserAgent 변경/추가  (0) 2020.05.25
블로그 이미지

SKY STORY

,
반응형

KISA의 암호알고리즘을 이용한 Swift 프로젝트 셈플 입니다.

실제 프로젝트 사용 시 예제 (2/2)를 참고하세요.

 

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 *pbszPlainText, OUT BYTE *pbszCipherText );
extern int decryptSeedCBC( IN BYTE *pbszCipherText, OUT BYTE *pbszPlainText );

 

KISA_SEED_CBC.c

아래 함수를 선언해 준다. 

void main(void) 함수는 제거한다.

// 초기화 벡터 - 사용자가 지정하는 초기화 벡터(16 BYTE)
BYTE pbszIV[16] = {0x026, 0x08d, 0x066, 0x0a7, 0x035, 0x0a8, 0x01a, 0x081, 0x06f, 0x0ba, 0x0d9, 0x0fa, 0x036, 0x016, 0x025, 0x001};

// 사용자가 지정하는 입력 키(16bytes), 암호화 대칭키
BYTE pbszUserKey[16] = {0x088, 0x0e3, 0x04f, 0x08f, 0x008, 0x017, 0x079, 0x0f1, 0x0e9, 0x0f3, 0x094, 0x037, 0x00a, 0x0d4, 0x005, 0x089};


int encryptSeedCBC( 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 *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;
}

 

Swift에서 사용하기 위해 KISA_SEED_CBC.h, KISA_SEED_CBC.c 파일들을 프로젝트에 추가한다.

SEED.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SEED : NSObject

+(NSString *)encrypt:(NSString *)plainText;
+(NSString *)decrypt:(NSString *)cipherText;

@end

NS_ASSUME_NONNULL_END

 

SEED.mm

#import "SEED.h"

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


@implementation SEED

+(NSString *)encrypt:(NSString *)plainText {

    BYTE pbszPlainText[2048] = {0,};
    memset(pbszPlainText, 0, [plainText length]);
    const char *byteBuff = [msg UTF8String];
    memcpy(pbszPlainText, (BYTE *)byteBuff, strlen(byteBuff));
    
    // 암호문 출력 버퍼
    BYTE pbszCipherText[2048] = {0,};
    int nCipherTextLen = encryptSeedCBC( 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]);
    
    // log
    [SEED printHexaLog:pbszCipherText length:nCipherTextLen];

    return base64String;
}

+(NSString *)decrypt:(NSString *)cipherText {

    // base64 decode
    NSData *data = [[NSData alloc] initWithBase64EncodedString:cipherText options:0];

    BYTE pbszCipherText[2048] = {0,};
    memcpy(pbszCipherText, [data bytes], [data length]);
    
    // 사용자 입력 평문
    BYTE pbszPlainText[2048] = {0,};
    int nPlainTextLen = decryptSeedCBC( pbszCipherText, pbszPlainText );
    
    NSString *plainText = [[NSString alloc] initWithBytes:pbszPlainText length:nPlainTextLen encoding:NSUTF8StringEncoding];
    
    // memory clean
    memset(pbszCipherText, 0, nPlainTextLen);
    
    // log
    [SEED printHexaLog:pbszPlainText length:nPlainTextLen];
    
    return plainText;
}

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

@end

 

Swift 프로젝트에 추가하고 Bridging Header 생성

#import "SEED.h"

 

사용방법 :

let str = "hello world"
let enc = SEED.encrypt(str)
print("\nenc = \(enc)")
let dec = SEED.decrypt(enc)
print("\ndec = \(dec)")

 

결과 :

---------------------------------
plainText : hello world

---------------------------------
SEED CBC Encryption....

Length (16)  : 53 81 F3 E0 18 41 85 70 29 3F 98 8F 9A A1 84 06 
enc = U4Hz4BhBhXApP5iPmqGEBg==

---------------------------------
SEED CBC Decryption....

Length (11)  : 68 65 6C 6C 6F 20 77 6F 72 6C 64 
dec = hello world

 

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

2020/05/28 - [개발노트] - HMAC SHA256

2020/05/26 - [iOS/Swift] - Array <-> Data

2020/05/25 - [분류 전체보기] - UserAgent 추가

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (1/3) - iOS디바이스 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump, Tcpdump, OpenSSL Quick Guide

2020/05/19 - [OS/Mac OS X] - gdb 사용

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형

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

Merge two different images in swift  (0) 2020.05.29
NSString <-> CBUUID 변환  (0) 2020.05.29
Array <-> Data 변환  (0) 2020.05.26
UserAgent 변경/추가  (0) 2020.05.25
RSA 암호화 / 복호화  (0) 2020.05.25
블로그 이미지

SKY STORY

,

Array <-> Data 변환

개발/iOS 2020. 5. 26. 16:41
반응형
반응형

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

NSString <-> CBUUID 변환  (0) 2020.05.29
SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제 (1/2)  (0) 2020.05.28
UserAgent 변경/추가  (0) 2020.05.25
RSA 암호화 / 복호화  (0) 2020.05.25
Base64 인코딩/디코딩  (0) 2020.05.25
블로그 이미지

SKY STORY

,

UserAgent 변경/추가

개발/iOS 2020. 5. 25. 17:58
반응형
let webConfiguration = WKWebViewConfiguration()
webConfiguration.applicationNameForUserAgent = "customize User-Agent"
let webView = WKWebView(frame: .zero, configuration: webConfiguration)

Output : Mozilla/5.0 (iPhone; CPU iPhone OS 11_2 like Mac OS X) AppleWebKit/604.4.7

(KHTML, like Gecko) customize User-Agent

 

let webView = WKWebView()
webView.evaluateJavaScript("navigator.userAgent") { (userAgent, error) in
    if let ua = userAgent {
        print("default WebView User-Agent > \(ua)")
    }

    // User-Agent에 '(my test)' 추가할 경우
    webView.customUserAgent = "\(ua) (my test)"
}

UserDefaults.standard.register(defaults: ["UserAgent": userAgentValue])

 

Output : Mozilla/5.0 (iPhone; CPU iPhone OS 11_2 like Mac OS X) AppleWebKit/604.4.7

(KHTML, like Gecko) customize User-Agent (my test)

 

 

 

반응형

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

SEED 블록암호 알고리즘 CBC (Cipher Block Chaining) 예제 (1/2)  (0) 2020.05.28
Array <-> Data 변환  (0) 2020.05.26
RSA 암호화 / 복호화  (0) 2020.05.25
Base64 인코딩/디코딩  (0) 2020.05.25
Bitbucket Carthage 사용  (0) 2020.05.19
블로그 이미지

SKY STORY

,
반응형

RsaUtils 클래스를 생성하여 프로젝트에 추가한다.

//  RsaUtils.swift

import Foundation
import Security

public class RSAUtils {

    private static let PADDING_FOR_DECRYPT = SecPadding()

    @available(iOS, introduced: 1.2.0)
    public class RSAUtilsError: NSError {
        init(_ message: String) {
            super.init(domain: "com.ubpay.RSAUtils", code: 500, userInfo: [
                NSLocalizedDescriptionKey: message
            ])
        }

        @available(*, unavailable)
        required public init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    }

    // Base64 encode a block of data
    @available(iOS, introduced: 1.2.0)
    private static func base64Encode(_ data: Data) -> String {
        return data.base64EncodedString(options: [])
    }

    // Base64 decode a base64-ed string
    @available(iOS, introduced: 1.2.0)
    private static func base64Decode(_ strBase64: String) -> Data {
        let data = Data(base64Encoded: strBase64, options: [])
        return data!
    }

    /**
     * Deletes an existing RSA key specified by a tag from keychain.
     *
     * - Parameter tagName: tag name to query for RSA key from keychain
     */
    @available(iOS, introduced: 1.2.0)
    public static func deleteRSAKeyFromKeychain(_ tagName: String) {
        let queryFilter: [String: AnyObject] = [
            String(kSecClass)             : kSecClassKey,
            String(kSecAttrKeyType)       : kSecAttrKeyTypeRSA,
            String(kSecAttrApplicationTag): tagName as AnyObject
        ]
        SecItemDelete(queryFilter as CFDictionary)
    }

    /**
     * Gets an existing RSA key specified by a tag from keychain.
     *
     * - Parameter tagName: tag name to query for RSA key from keychain
     *
     * - Returns: SecKey reference to the RSA key
     */
    @available(iOS, introduced: 1.2.0)
    public static func getRSAKeyFromKeychain(_ tagName: String) -> SecKey? {
        let queryFilter: [String: AnyObject] = [
            String(kSecClass)             : kSecClassKey,
            String(kSecAttrKeyType)       : kSecAttrKeyTypeRSA,
            String(kSecAttrApplicationTag): tagName as AnyObject,
            //String(kSecAttrAccessible)    : kSecAttrAccessibleWhenUnlocked,
            String(kSecReturnRef)         : true as AnyObject
        ]

        var keyPtr: AnyObject?
        let result = SecItemCopyMatching(queryFilter as CFDictionary, &keyPtr)
        if ( result != noErr || keyPtr == nil ) {
            return nil
        }
        return keyPtr as! SecKey?
    }

    /**
     * Adds a RSA private key (PKCS#1 or PKCS#8) to keychain and returns its SecKey reference.
     *
     * On disk, a PEM RSA PKCS#8 private key file starts with string "-----BEGIN PRIVATE KEY-----", and ends with string "-----END PRIVATE KEY-----"; PKCS#1 private key file starts with string "-----BEGIN RSA PRIVATE KEY-----", and ends with string "-----END RSA PRIVATE KEY-----".
     *
     * - Parameter privkeyBase64: RSA private key (PKCS#1 or PKCS#8) in base64
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the input key is not a valid PKCS#8 private key
     *
     * - Returns: SecKey reference to the RSA private key.
     */
    @available(iOS, introduced: 1.2.0)
    @discardableResult public static func addRSAPrivateKey(_ privkeyBase64: String, tagName: String) throws -> SecKey? {
        let fullRange = NSRange(location: 0, length: privkeyBase64.lengthOfBytes(using: .utf8))
        let regExp = try! NSRegularExpression(pattern: "(-----BEGIN.*?-----)|(-----END.*?-----)|\\s+", options: [])
        let myPrivkeyBase64 = regExp.stringByReplacingMatches(in: privkeyBase64, options: [], range: fullRange, withTemplate: "")
        return try addRSAPrivateKey(base64Decode(myPrivkeyBase64), tagName: tagName)
    }

    /**
     * Adds a RSA private key to keychain and returns its SecKey reference.
     *
     * - Parameter privkey: RSA private key (PKCS#1 or PKCS#8)
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the input key is not a valid PKCS#8 private key
     *
     * - Returns: SecKey reference to the RSA private key.
     */
    @available(iOS, introduced: 1.2.0)
    @discardableResult private static func addRSAPrivateKey(_ privkey: Data, tagName: String) throws -> SecKey? {
        // Delete any old lingering key with the same tag
        deleteRSAKeyFromKeychain(tagName)

        let privkeyData = try stripPrivateKeyHeader(privkey)
        if ( privkeyData == nil ) {
            return nil
        }

        // Add persistent version of the key to system keychain
        let queryFilter: [String : Any] = [
            (kSecClass as String)              : kSecClassKey,
            (kSecAttrKeyType as String)        : kSecAttrKeyTypeRSA,
            (kSecAttrApplicationTag as String) : tagName,
            //(kSecAttrAccessible as String)     : kSecAttrAccessibleWhenUnlocked,
            (kSecValueData as String)          : privkeyData!,
            (kSecAttrKeyClass as String)       : kSecAttrKeyClassPrivate,
            (kSecReturnPersistentRef as String): true
            ] as [String : Any]
        let result = SecItemAdd(queryFilter as CFDictionary, nil)
        if ((result != noErr) && (result != errSecDuplicateItem)) {
            NSLog("Cannot add key to keychain, status \(result).")
            return nil
        }

        return getRSAKeyFromKeychain(tagName)
    }

    /**
     * Verifies that the supplied key is in fact a PEM RSA private key, and strips its header.
     *
     * If the supplied key is PKCS#8, its ASN.1 header should be stripped. Otherwise (PKCS#1), the whole key data is left intact.
     *
     * On disk, a PEM RSA PKCS#8 private key file starts with string "-----BEGIN PRIVATE KEY-----", and ends with string "-----END PRIVATE KEY-----"; PKCS#1 private key file starts with string "-----BEGIN RSA PRIVATE KEY-----", and ends with string "-----END RSA PRIVATE KEY-----".
     *
     * - Parameter privkey: RSA private key (PKCS#1 or PKCS#8)
     *
     * - Throws: `RSAUtilsError` if the input key is not a valid RSA PKCS#8 private key
     *
     * - Returns: the RSA private key with header stripped.
     */
    @available(iOS, introduced: 1.2.0)
    private static func stripPrivateKeyHeader(_ privkey: Data) throws -> Data? {
        if ( privkey.count == 0 ) {
            return nil
        }

        var keyAsArray = [UInt8](repeating: 0, count: privkey.count / MemoryLayout<UInt8>.size)
        (privkey as NSData).getBytes(&keyAsArray, length: privkey.count)

        //PKCS#8: magic byte at offset 22, check if it's actually ASN.1
        var idx = 22
        if ( keyAsArray[idx] != 0x04 ) {
            return privkey
        }
        idx += 1

        //now we need to find out how long the key is, so we can extract the correct hunk
        //of bytes from the buffer.
        var len = Int(keyAsArray[idx])
        idx += 1
        let det = len & 0x80 //check if the high bit set
        if (det == 0) {
            //no? then the length of the key is a number that fits in one byte, (< 128)
            len = len & 0x7f
        } else {
            //otherwise, the length of the key is a number that doesn't fit in one byte (> 127)
            var byteCount = Int(len & 0x7f)
            if (byteCount + idx > privkey.count) {
                return nil
            }
            //so we need to snip off byteCount bytes from the front, and reverse their order
            var accum: UInt = 0
            var idx2 = idx
            idx += byteCount
            while (byteCount > 0) {
                //after each byte, we shove it over, accumulating the value into accum
                accum = (accum << 8) + UInt(keyAsArray[idx2])
                idx2 += 1
                byteCount -= 1
            }
            // now we have read all the bytes of the key length, and converted them to a number,
            // which is the number of bytes in the actual key.  we use this below to extract the
            // key bytes and operate on them
            len = Int(accum)
        }
        return privkey.subdata(in: idx..<idx+len)
        //return privkey.subdata(in: NSMakeRange(idx, len).toRange()!)
    }

    /**
     * Adds a RSA public key to keychain and returns its SecKey reference.
     *
     * - Parameter pubkeyBase64: X509 public key in base64 (data between "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----")
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the input key is indeed not a X509 public key
     *
     * - Returns: SecKey reference to the RSA public key.
     */
    @available(iOS, introduced: 1.2.0)
    public static func addRSAPublicKey(_ pubkeyBase64: String, tagName: String) throws -> SecKey? {
        let fullRange = NSRange(location: 0, length: pubkeyBase64.lengthOfBytes(using: .utf8))
        let regExp = try! NSRegularExpression(pattern: "(-----BEGIN.*?-----)|(-----END.*?-----)|\\s+", options: [])
        let myPubkeyBase64 = regExp.stringByReplacingMatches(in: pubkeyBase64, options: [], range: fullRange, withTemplate: "")
        return try addRSAPublicKey(base64Decode(myPubkeyBase64), tagName: tagName)
    }

    /**
     * Adds a RSA pubic key to keychain and returns its SecKey reference.
     *
     * - Parameter pubkey: X509 public key
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the input key is not a valid X509 public key
     *
     * - Returns: SecKey reference to the RSA public key.
     */
    @available(iOS, introduced: 1.2.0)
    private static func addRSAPublicKey(_ pubkey: Data, tagName: String) throws -> SecKey? {
        // Delete any old lingering key with the same tag
        deleteRSAKeyFromKeychain(tagName)

        let pubkeyData = try stripPublicKeyHeader(pubkey)
        if ( pubkeyData == nil ) {
            return nil
        }

        // Add persistent version of the key to system keychain
        //var prt1: Unmanaged<AnyObject>?
        let queryFilter: [String : Any] = [
            (kSecClass as String)              : kSecClassKey,
            (kSecAttrKeyType as String)        : kSecAttrKeyTypeRSA,
            (kSecAttrApplicationTag as String) : tagName,
            (kSecValueData as String)          : pubkeyData!,
            (kSecAttrKeyClass as String)       : kSecAttrKeyClassPublic,
            (kSecReturnPersistentRef as String): true
            ] as [String : Any]
        let result = SecItemAdd(queryFilter as CFDictionary, nil)
        if ((result != noErr) && (result != errSecDuplicateItem)) {
            return nil
        }

        return getRSAKeyFromKeychain(tagName)
    }

    /**
     * Verifies that the supplied key is in fact a X509 public key, and strips its header.
     *
     * On disk, a X509 public key file starts with string "-----BEGIN PUBLIC KEY-----", and ends with string "-----END PUBLIC KEY-----"
     *
     * - Parameter pubkey: X509 public key
     *
     * - Throws: `RSAUtilsError` if the input key is not a valid X509 public key
     *
     * - Returns: the RSA public key with header stripped.
     */
    @available(iOS, introduced: 1.2.0)
    private static func stripPublicKeyHeader(_ pubkey: Data) throws -> Data? {
        if ( pubkey.count == 0 ) {
            return nil
        }

        var keyAsArray = [UInt8](repeating: 0, count: pubkey.count / MemoryLayout<UInt8>.size)
        (pubkey as NSData).getBytes(&keyAsArray, length: pubkey.count)

        var idx = 0
        if (keyAsArray[idx] != 0x30) {
            throw RSAUtilsError("Provided key doesn't have a valid ASN.1 structure (first byte should be 0x30).")
            //return nil
        }
        idx += 1

        if (keyAsArray[idx] > 0x80) {
            idx += Int(keyAsArray[idx]) - 0x80 + 1
        } else {
            idx += 1
        }

        /*
         * If current byte is 0x02, it means the key doesn't have a X509 header (it contains only modulo & public exponent). In this case, we can just return the provided DER data as is
         */
        if (Int(keyAsArray[idx]) == 0x02) {
            return pubkey
        }

        let seqiod = [UInt8](arrayLiteral: 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00)
        for i in idx..<idx+seqiod.count {
            if ( keyAsArray[i] != seqiod[i-idx] ) {
                throw RSAUtilsError("Provided key doesn't have a valid X509 header.")
                //return nil
            }
        }
        idx += seqiod.count

        if (keyAsArray[idx] != 0x03) {
            throw RSAUtilsError("Invalid byte at index \(idx) (\(keyAsArray[idx])) for public key header.")
            //return nil
        }
        idx += 1

        if (keyAsArray[idx] > 0x80) {
            idx += Int(keyAsArray[idx]) - 0x80 + 1;
        } else {
            idx += 1
        }

        if (keyAsArray[idx] != 0x00) {
            throw RSAUtilsError("Invalid byte at index \(idx) (\(keyAsArray[idx])) for public key header.")
            //return nil
        }
        idx += 1
        return pubkey.subdata(in: idx..<keyAsArray.count)
        //return pubkey.subdata(in: NSMakeRange(idx, keyAsArray.count - idx).toRange()!)
    }

    /**
     * Encrypts data with a RSA key.
     *
     * - Parameter data: the data to be encrypted
     * - Parameter rsaKeyRef: the RSA key
     * - Parameter padding: padding used for encryption
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAKey(_ data: Data, rsaKeyRef: SecKey, padding: SecPadding) -> Data? {
        let blockSize = SecKeyGetBlockSize(rsaKeyRef)
        let dataSize = data.count / MemoryLayout<UInt8>.size
        let maxChunkSize = padding==SecPadding.OAEP ? (blockSize - 42) : (blockSize - 11)

        var dataAsArray = [UInt8](repeating: 0, count: dataSize)
        (data as NSData).getBytes(&dataAsArray, length: dataSize)

        var encryptedData = [UInt8](repeating: 0, count: 0)
        var idx = 0
        while (idx < dataAsArray.count ) {
            var idxEnd = idx + maxChunkSize
            if ( idxEnd > dataAsArray.count ) {
                idxEnd = dataAsArray.count
            }
            var chunkData = [UInt8](repeating: 0, count: maxChunkSize)
            for i in idx..<idxEnd {
                chunkData[i-idx] = dataAsArray[i]
            }

            var encryptedDataBuffer = [UInt8](repeating: 0, count: blockSize)
            var encryptedDataLength = blockSize

            let status = SecKeyEncrypt(rsaKeyRef, padding, chunkData, idxEnd-idx, &encryptedDataBuffer, &encryptedDataLength)
            if ( status != noErr ) {
                NSLog("Error while encrypting: %i", status)
                return nil
            }
            encryptedData += encryptedDataBuffer

            idx += maxChunkSize
        }

        return Data(bytes: UnsafePointer<UInt8>(encryptedData), count: encryptedData.count)
    }

    /**
     * Decrypts data with a RSA key.
     *
     * - Parameter encryptedData: the data to be decrypted
     * - Parameter rsaKeyRef: the RSA key
     * - Parameter padding: padding used for decryption
     *
     * - Returns: the decrypted data
     */
    @available(iOS, introduced: 1.2.0)
    public static func decryptWithRSAKey(_ encryptedData: Data, rsaKeyRef: SecKey, padding: SecPadding) -> Data? {
        let blockSize = SecKeyGetBlockSize(rsaKeyRef)
        let dataSize = encryptedData.count / MemoryLayout<UInt8>.size

        var encryptedDataAsArray = [UInt8](repeating: 0, count: dataSize)
        (encryptedData as NSData).getBytes(&encryptedDataAsArray, length: dataSize)

        var decryptedData = [UInt8](repeating: 0, count: 0)
        var idx = 0
        while (idx < encryptedDataAsArray.count ) {
            var idxEnd = idx + blockSize
            if ( idxEnd > encryptedDataAsArray.count ) {
                idxEnd = encryptedDataAsArray.count
            }
            var chunkData = [UInt8](repeating: 0, count: blockSize)
            for i in idx..<idxEnd {
                chunkData[i-idx] = encryptedDataAsArray[i]
            }

            var decryptedDataBuffer = [UInt8](repeating: 0, count: blockSize)
            var decryptedDataLength = blockSize

            let status = SecKeyDecrypt(rsaKeyRef, padding, chunkData, idxEnd-idx, &decryptedDataBuffer, &decryptedDataLength)
            if ( status != noErr ) {
                return nil
            }
            let finalData = removePadding(decryptedDataBuffer)
            decryptedData += finalData

            idx += blockSize
        }

        return Data(bytes: UnsafePointer<UInt8>(decryptedData), count: decryptedData.count)
    }

    @available(iOS, introduced: 1.2.0)
    private static func removePadding(_ data: [UInt8]) -> [UInt8] {
        var idxFirstZero = -1
        var idxNextZero = data.count
        for i in 0..<data.count {
            if ( data[i] == 0 ) {
                if ( idxFirstZero < 0 ) {
                    idxFirstZero = i
                } else {
                    idxNextZero = i
                    break
                }
            }
        }
        if ( idxNextZero-idxFirstZero-1 == 0 ) {
            idxNextZero = idxFirstZero
            idxFirstZero = -1
        }
        var newData = [UInt8](repeating: 0, count: idxNextZero-idxFirstZero-1)
        for i in idxFirstZero+1..<idxNextZero {
            newData[i-idxFirstZero-1] = data[i]
        }
        return newData
    }

    /**
     * Encrypts data using a RSA key from keychain specified by `tagName`.
     *
     * Note: The RSA key must be added to keychain by calling `addRSAPublicKey()` or `addRSAPrivateKey()` period to calling this function.
     *
     * - Parameter data: data to be encrypted
     * - Parameter tagName: tag name to query for RSA key from keychain.
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAKey(data: Data, tagName: String) -> Data? {
        let keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            return nil
        }

        return encryptWithRSAKey(data, rsaKeyRef: keyRef!, padding: SecPadding.PKCS1)
    }

    /**
     * Encrypts a string using a RSA key from keychain specified by `tagName`.
     *
     * Note: The RSA key must be added to keychain by calling `addRSAPublicKey()` or `addRSAPrivateKey()` period to calling this function.
     *
     * - Parameter str: string to be encrypted
     * - Parameter tagName: tag name to query for RSA key from keychain.
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAKey(str: String, tagName: String) -> Data? {
        let keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            return nil
        }

        return encryptWithRSAKey(str.data(using: .utf8)!, rsaKeyRef: keyRef!, padding: SecPadding.PKCS1)
    }

    /**
     * Decrypts an encrypted data using a RSA key from keychain specified by `tagName`.
     *
     * Note: The RSA key must be added to keychain by calling `addRSAPublicKey()` or `addRSAPrivateKey()` period to calling this function.
     *
     * - Parameter encryptedData: data to be decrypted
     * - Parameter tagName: tag name to query for RSA key from keychain.
     *
     * - Returns: the decrypted data
     */
    @available(iOS, introduced: 1.2.0)
    public static func decryptWithRSAKey(encryptedData: Data, tagName: String) -> Data? {
        let keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            return nil
        }

        return decryptWithRSAKey(encryptedData, rsaKeyRef: keyRef!, padding: PADDING_FOR_DECRYPT)
    }

    /*----------------------------------------------------------------------*/

    /**
     * Encrypts data using RSA public key.
     *
     * Note: the public key will be stored in keychain with tag as `pubkeyBase64.hashValue`.
     *
     * - Parameter data: data to be encrypted
     * - Parameter pubkeyBase64: X509 public key in base64 (data between "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----")
     *
     * - Throws: `RSAUtilsError` if the supplied key is not a valid X509 public key
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAPublicKey(data: Data, pubkeyBase64: String) throws -> Data? {
        let tagName = "PUBIC-" + String(pubkeyBase64.hashValue)
        var keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            keyRef = try addRSAPublicKey(pubkeyBase64, tagName: tagName)
        }
        if ( keyRef == nil ) {
            return nil
        }

        return encryptWithRSAKey(data, rsaKeyRef: keyRef!, padding: SecPadding.PKCS1)
    }

    /**
     * Encrypts a string using RSA public key.
     *
     * Note: the public key will be stored in keychain with tag as `pubkeyBase64.hashValue`.
     *
     * - Parameter str: string to be encrypted
     * - Parameter pubkeyBase64: X509 public key in base64 (data between "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----")
     *
     * - Throws: `RSAUtilsError` if the supplied key is not a valid X509 public key
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAPublicKey(str: String, pubkeyBase64: String) throws -> Data? {
        let tagName = "PUBIC-" + String(pubkeyBase64.hashValue)
        var keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            keyRef = try addRSAPublicKey(pubkeyBase64, tagName: tagName)
        }
        if ( keyRef == nil ) {
            return nil
        }

        return encryptWithRSAKey(str.data(using: .utf8)!, rsaKeyRef: keyRef!, padding: SecPadding.PKCS1)
    }

    /**
     * Encrypts data using RSA public key.
     *
     * Note: the public key will be stored in keychain specified by tagName.
     *
     * - Parameter data: data to be encrypted
     * - Parameter pubkeyBase64: X509 public key in base64 (data between "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----")
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the supplied key is not a valid X509 public key
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAPublicKey(data: Data, pubkeyBase64: String, tagName: String) throws -> Data? {
        var keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            keyRef = try addRSAPublicKey(pubkeyBase64, tagName: tagName)
        }
        if ( keyRef == nil ) {
            return nil
        }

        return encryptWithRSAKey(data, rsaKeyRef: keyRef!, padding: SecPadding.PKCS1)
    }

    /**
     * Encrypts a string using RSA public key.
     *
     * Note: the public key will be stored in keychain specified by tagName.
     *
     * - Parameter str: string to be encrypted
     * - Parameter pubkeyBase64: X509 public key in base64 (data between "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----")
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the supplied key is not a valid X509 public key
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func encryptWithRSAPublicKey(str: String, pubkeyBase64: String, tagName: String) throws -> Data? {
        var keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            keyRef = try addRSAPublicKey(pubkeyBase64, tagName: tagName)
        }
        if ( keyRef == nil ) {
            return nil
        }

        return encryptWithRSAKey(str.data(using: .utf8)!, rsaKeyRef: keyRef!, padding: SecPadding.PKCS1)
    }

    /*----------------------------------------------------------------------*/

    /**
     * Decrypts an encrypted data using a RSA private key.
     *
     * Note: the private key will be stored in keychain with tag as `privkeyBase64.hashValue`.
     *
     * - Parameter encryptedData: data to be decrypted
     * - Parameter privkeyBase64: RSA PKCS#8 private key in base64 (data between "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----")
     *
     * - Throws: `RSAUtilsError` if the supplied key is not a valid RSA PKCS#8 private key
     *
     * - Returns: the decrypted data
     */
    @available(iOS, introduced: 1.2.0)
    public static func decryptWithRSAPrivateKey(encryptedData: Data, privkeyBase64: String) throws -> Data? {
        let tagName = "PRIVATE-" + String(privkeyBase64.hashValue)
        var keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            keyRef = try addRSAPrivateKey(privkeyBase64, tagName: tagName)
        }
        if ( keyRef == nil ) {
            return nil
        }

        return decryptWithRSAKey(encryptedData, rsaKeyRef: keyRef!, padding: PADDING_FOR_DECRYPT)
    }

    /**
     * Decrypts an encrypted data using a RSA private key.
     *
     * Note: the private key will be stored in keychain specified by tagName.
     *
     * - Parameter encryptedData: data to be decrypted
     * - Parameter privkeyBase64: RSA PKCS#8 private key in base64 (data between "-----BEGIN PRIVATE KEY-----" and "-----END PRIVATE KEY-----")
     * - Parameter tagName: tag name to store RSA key to keychain
     *
     * - Throws: `RSAUtilsError` if the supplied key is not a valid RSA PKCS#8 private key
     *
     * - Returns: the data in encrypted form
     */
    @available(iOS, introduced: 1.2.0)
    public static func decryptWithRSAPrivateKey(encryptedData: Data, privkeyBase64: String, tagName: String) throws -> Data? {
        var keyRef = getRSAKeyFromKeychain(tagName)
        if ( keyRef == nil ) {
            keyRef = try addRSAPrivateKey(privkeyBase64, tagName: tagName)
        }
        if ( keyRef == nil ) {
            return nil
        }

        return decryptWithRSAKey(encryptedData, rsaKeyRef: keyRef!, padding: PADDING_FOR_DECRYPT)
    }
}

 

RSA 키 생성은 아래 사이트에서 생성 및 테스트하였다.

https://8gwifi.org/RSAFunctionality?keysize=2048

 

테스트를 위해 생성된 키쌍은 다음과 같다.

Generate RSA Key Size :2048 bit

RSA Ciphers : RSA

Public Key :

-----BEGIN PUBLIC KEY-----

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk3EUep+Y0Ps8qumkNW8x

fvAEpill5SG/jBN3bJhwr6G5qpiC0g1ys4YcV9T0KKg2JBJIYFCHht4DH5GMyRxu

SWxh2lRC0mGJ38QVHBUGoJcbclCN3wsrUI9T+FhHN7TRL3YF+MzdbdMNultaCKq1

9KoPgYLo342rrfyvI9D51peed3CotaoQFAK7UqX/oggoP04OQ83fkSkZCu7T5uBG

b3ARjapwSEvvlC+A4E8WtqwjCx6YoE/XRa9iPAR5Fm0KUK2G8La0g9oUtG2dn+gL

iHkX00iI5PlIe0cFjPmKb5N75fLZNA9g0CkpVG2DrIGbdgp2CHD4Ufk3U99NSaH0

XwIDAQAB

-----END PUBLIC KEY-----

Private Key :

-----BEGIN RSA PRIVATE KEY-----

MIIEpAIBAAKCAQEAk3EUep+Y0Ps8qumkNW8xfvAEpill5SG/jBN3bJhwr6G5qpiC

0g1ys4YcV9T0KKg2JBJIYFCHht4DH5GMyRxuSWxh2lRC0mGJ38QVHBUGoJcbclCN

3wsrUI9T+FhHN7TRL3YF+MzdbdMNultaCKq19KoPgYLo342rrfyvI9D51peed3Co

taoQFAK7UqX/oggoP04OQ83fkSkZCu7T5uBGb3ARjapwSEvvlC+A4E8WtqwjCx6Y

oE/XRa9iPAR5Fm0KUK2G8La0g9oUtG2dn+gLiHkX00iI5PlIe0cFjPmKb5N75fLZ

NA9g0CkpVG2DrIGbdgp2CHD4Ufk3U99NSaH0XwIDAQABAoIBABCid28GRpV9YvDd

f1tP+kOaDMw6a3aYgiXppFWqNTx7gJkQr+HHBqPeg6AdNJbJs6IKNgQ30bKTpcKQ

B1RBUugRxFB/pTJbMtT+KGuMq7y+j6gsEnWRqwdhxFWGkDJmwhsas73IT0suvqPB

3ryPlgvOjAVOobtnHnF4ysG9uBJPyP03hCG97OIuHCQ0wpGlQAktyh7J5jXfGBJp

+bfOLGXZCqFO+iU0CRCf6si8/owTTXOYw7sANjtzbQt69GO+Vr3hi8SC2rGf/bkq

XFrajTOf1UC2wENKZJTY2H4cxedVViCMRThjMh5K1+661gKwUbSXyqN4jF4qsy/H

iAN/hgECgYEAyyf4dFhxjnTj7UiJtljqsF9seChqjtXHjHx0yq3wMCl+UMeMZ4Df

b5zOk9n4E6ntTEom4ZkUY+zYX+K4rR4W7FV5hhH/F5n+9BfXTludyPaQDWhpnaHw

1ZjQ8i7VMiYmy393Wd5sT5d1tDs4C1bvq10yAydKFV5a3bron8PsIt8CgYEAucsf

zQGtKb7emnDW4Cg61t1Bg/HXDxhm0EunP6gmTI+SUP/zZehg23xdajKYZ3zb3npm

Lz8LxGAxFIdp2o6BGgbTjotBTNlrza9Zh2H3BnV74TKS/gag3LfBtuRdZwhKgCPs

g4kkH4D1t6hza0Nql8cVjLvJnl++J+6YX3J53oECgYEAnIfvp7V9yYXHGM0LTrS0

H7Fmoi6B7AxL9LLwSjo7FuDhstwOErH5dsYbZVBNFNmZPW7lBm4sh9G15iuKn9jP

UMmLGQJEyqqdBvZXrshoiq9vzuTke9CLAAj+9ZugKUO8II/WJih6y9inmHcId7RE

doUYQ9XB/zT0TmP1WSRcjYECgYA37vDp9QE+uhmmASaPYU0ldoLMyDfocX4yYzQ8

s9Cj5+0yuXt7SJQwP6aX3BeJwEspFUxCGQbf3d2owoOZqqEvRrLWDRJhomsUByA6

48FMjn329BTQqQowqJmHCAUeiZ50KVyA1P6tBVP0MKBewHMMsoDIV5iBN22189yn

j30lAQKBgQCZoAR0wMlhcXqMt6GwlRDCrkBURyKy29sW+77AxXALPuxUGeEV0iBS

TFc8UUgmtMt7ZmaynukPThI7qtLXsNibVYFqENy1dF64SHIa1a0Qa0fBnhDqqWdk

oDeXJrKFS38ZGNfPpbPmI9Ti/7h2ct7WWWZAEtGO1buk7nZCxiOxig==

-----END RSA PRIVATE KEY-----

 

 

RSA Encode

// RSA Encode
let publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk3EUep+Y0Ps8qumkNW8xfvAEpill5SG/jBN3bJhwr6G5qpiC0g1ys4YcV9T0KKg2JBJIYFCHht4DH5GMyRxuSWxh2lRC0mGJ38QVHBUGoJcbclCN3wsrUI9T+FhHN7TRL3YF+MzdbdMNultaCKq19KoPgYLo342rrfyvI9D51peed3CotaoQFAK7UqX/oggoP04OQ83fkSkZCu7T5uBGb3ARjapwSEvvlC+A4E8WtqwjCx6YoE/XRa9iPAR5Fm0KUK2G8La0g9oUtG2dn+gLiHkX00iI5PlIe0cFjPmKb5N75fLZNA9g0CkpVG2DrIGbdgp2CHD4Ufk3U99NSaH0XwIDAQAB"

let string = "hello world"
//let data = string.data(using: .utf8)!
let encryptedData = try! RSAUtils.encryptWithRSAPublicKey(str: string, pubkeyBase64: publicKey)// Data
let encryptedString = (encryptedData!.base64EncodedString()) as String// Base64
print("\(encryptedString)")

Output: eDXn/2IJZYiCULVYR+IvmF6FVMvgU9YLVTnzDLlaXUJKib0FJy8Zhc2gJUZTtDtg4n48zVYU/jTL9UV0mpUls9jKScEBmm5lkR8qzV80skaAPTGnknYFg7nBtrsQPy2l1EUK0W9KaK1wN47JO/Si2Lyt9po3W2ErUFo1El3Gt/PdHTVpzftC64D+3iY/JU7YeHwBllPwEHQkY3hpgcVl4BxyNfbMCZuQXw5R8qiv5PObcKVliBYO7N4+5lXJXQoldMtGXzm+5G9M8xBgJDPJXzeqxl63o4AmG0ULKvhvHirHScOn0jvT5BEXM+oCkFm5SntQRt/iHtKCeIjqLE5eUg==

 

RSA Decode

let privateKey = "MIIEpAIBAAKCAQEAk3EUep+Y0Ps8qumkNW8xfvAEpill5SG/jBN3bJhwr6G5qpiC0g1ys4YcV9T0KKg2JBJIYFCHht4DH5GMyRxuSWxh2lRC0mGJ38QVHBUGoJcbclCN3wsrUI9T+FhHN7TRL3YF+MzdbdMNultaCKq19KoPgYLo342rrfyvI9D51peed3CotaoQFAK7UqX/oggoP04OQ83fkSkZCu7T5uBGb3ARjapwSEvvlC+A4E8WtqwjCx6YoE/XRa9iPAR5Fm0KUK2G8La0g9oUtG2dn+gLiHkX00iI5PlIe0cFjPmKb5N75fLZNA9g0CkpVG2DrIGbdgp2CHD4Ufk3U99NSaH0XwIDAQABAoIBABCid28GRpV9YvDdf1tP+kOaDMw6a3aYgiXppFWqNTx7gJkQr+HHBqPeg6AdNJbJs6IKNgQ30bKTpcKQB1RBUugRxFB/pTJbMtT+KGuMq7y+j6gsEnWRqwdhxFWGkDJmwhsas73IT0suvqPB3ryPlgvOjAVOobtnHnF4ysG9uBJPyP03hCG97OIuHCQ0wpGlQAktyh7J5jXfGBJp+bfOLGXZCqFO+iU0CRCf6si8/owTTXOYw7sANjtzbQt69GO+Vr3hi8SC2rGf/bkqXFrajTOf1UC2wENKZJTY2H4cxedVViCMRThjMh5K1+661gKwUbSXyqN4jF4qsy/HiAN/hgECgYEAyyf4dFhxjnTj7UiJtljqsF9seChqjtXHjHx0yq3wMCl+UMeMZ4Dfb5zOk9n4E6ntTEom4ZkUY+zYX+K4rR4W7FV5hhH/F5n+9BfXTludyPaQDWhpnaHw1ZjQ8i7VMiYmy393Wd5sT5d1tDs4C1bvq10yAydKFV5a3bron8PsIt8CgYEAucsfzQGtKb7emnDW4Cg61t1Bg/HXDxhm0EunP6gmTI+SUP/zZehg23xdajKYZ3zb3npmLz8LxGAxFIdp2o6BGgbTjotBTNlrza9Zh2H3BnV74TKS/gag3LfBtuRdZwhKgCPsg4kkH4D1t6hza0Nql8cVjLvJnl++J+6YX3J53oECgYEAnIfvp7V9yYXHGM0LTrS0H7Fmoi6B7AxL9LLwSjo7FuDhstwOErH5dsYbZVBNFNmZPW7lBm4sh9G15iuKn9jPUMmLGQJEyqqdBvZXrshoiq9vzuTke9CLAAj+9ZugKUO8II/WJih6y9inmHcId7REdoUYQ9XB/zT0TmP1WSRcjYECgYA37vDp9QE+uhmmASaPYU0ldoLMyDfocX4yYzQ8s9Cj5+0yuXt7SJQwP6aX3BeJwEspFUxCGQbf3d2owoOZqqEvRrLWDRJhomsUByA648FMjn329BTQqQowqJmHCAUeiZ50KVyA1P6tBVP0MKBewHMMsoDIV5iBN22189ynj30lAQKBgQCZoAR0wMlhcXqMt6GwlRDCrkBURyKy29sW+77AxXALPuxUGeEV0iBSTFc8UUgmtMt7ZmaynukPThI7qtLXsNibVYFqENy1dF64SHIa1a0Qa0fBnhDqqWdkoDeXJrKFS38ZGNfPpbPmI9Ti/7h2ct7WWWZAEtGO1buk7nZCxiOxig=="
        
let decryptedData = try! RSAUtils.decryptWithRSAPrivateKey(encryptedData: encryptedData!, privkeyBase64: privateKey)// Data
let decryptedString = String(data: decryptedData!, encoding: .utf8)
print("\(decryptedString)")

Output:  hello world

 

출처 : 

https://github.com/btnguyen2k/swiftutils/blob/master/SwiftUtils/RSAUtils.swift

 

2020/05/25 - [iOS/Swift] - Base64 인코딩/디코딩

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (1/3) - iOS디바이스 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump, Tcpdump, OpenSSL Quick Guide

2020/05/19 - [OS/Mac OS X] - gdb 사용

2020/05/19 - [iOS/Jailbreak] - Frida 설치 및 사용법

2020/05/19 - [OS/Mac OS X] - gdb 설치

2020/05/19 - [OS/Mac OS X] - Mac에서 Node.js 설치

반응형

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

Array <-> Data 변환  (0) 2020.05.26
UserAgent 변경/추가  (0) 2020.05.25
Base64 인코딩/디코딩  (0) 2020.05.25
Bitbucket Carthage 사용  (0) 2020.05.19
Fridump 사용법 (3/4) - 메모리 덤프  (0) 2020.05.19
블로그 이미지

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

 

// String을 Data로 변경
let string = "hello world"
let strData = string.data(using: .utf8)!

 

 

Base64 인코딩 / 디코딩 ( String )

// Base64 인코딩 ( Data -> Base64 encoded String )
let base64EncString = strData.base64EncodedString()

// Base64 디코딩 ( Base64 encoded String -> Base64 decoded String )
let decodedData = Data(base64Encoded: base64EncString)!
let base64DecString = String(data: decodedData, encoding: .utf8)!


print("Base64인코딩(String) : \(base64EncString)")
print("Base64디코딩(String) : \(base64DecString)")

 

 

Base64 인코딩 / 디코딩 ( Data )

// Base64 인코딩 ( Data -> Base64 encoded Data )
let base64EncData = strData.base64EncodedData(options: .lineLength64Characters)

// Base64 디코딩 ( Base64 encoded Data -> Base64 decoded Data )
let base64DecData = Data(base64Encoded: base64EncData, options: [])! as Data


print("Base64인코딩(Data) : \(String(data: base64EncData, encoding: .utf8)!)")
print("Base64디코딩(Data) : \(String(data: base64DecData, encoding: .utf8)!)")

 

스마트폰 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

 

2020/05/25 - [iOS/Swift] - RSA 암호화 / 복호화

2020/05/19 - [AI/Algorithm] - Generic algorithm

2020/05/19 - [AI/Algorithm] - neural network

2020/05/19 - [AI/Algorithm] - minimax full search example

2020/05/19 - [AI/Algorithm] - minimax, alpha-beta pruning

2020/05/19 - [iOS/Tips] - Bitbucket Carthage 사용

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (3/3) - 메모리 덤프

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (2/3) - Mac OS X 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump 사용법 (1/3) - iOS디바이스 환경 구축

2020/05/19 - [iOS/Jailbreak] - Fridump, Tcpdump, OpenSSL Quick Guide

2020/05/19 - [OS/Mac OS X] - gdb 사용

2020/05/19 - [iOS/Jailbreak] - Frida 설치 및 사용법

2020/05/19 - [OS/Mac OS X] - gdb 설치

2020/05/19 - [OS/Mac OS X] - Mac에서 Node.js 설치

반응형

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

UserAgent 변경/추가  (0) 2020.05.25
RSA 암호화 / 복호화  (0) 2020.05.25
Bitbucket Carthage 사용  (0) 2020.05.19
Fridump 사용법 (3/4) - 메모리 덤프  (0) 2020.05.19
Fridump 사용법 (2/4) - Mac OS X 환경 구축  (0) 2020.05.19
블로그 이미지

SKY STORY

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

SKY STORY

,