Notice
Recent Posts
Recent Comments
Link
투케이2K
20. (TWOK/UTIL) [Ios/Swift] C_Encryption - 데이터 암호화 인코딩 (encode) , 디코딩 (decode) , URL 인코딩, 디코딩 관련 클래스 본문
투케이2K 유틸파일
20. (TWOK/UTIL) [Ios/Swift] C_Encryption - 데이터 암호화 인코딩 (encode) , 디코딩 (decode) , URL 인코딩, 디코딩 관련 클래스
투케이2K 2022. 3. 25. 18:05[설 명]
프로그램 : Ios / Swift
설 명 : 데이터 암호화 인코딩 (encode) , 디코딩 (decode) , URL 인코딩 , 디코딩 관련 클래스
[소스 코드]
import Foundation
import UIKit
class C_Encryption {
// MARK: - [클래스 설명]
/*
// -----------------------------------------
1. 데이터 암호화 인코딩, 디코딩 관련 클래스
// -----------------------------------------
*/
// MARK: - [base64 인코딩]
func getBase64EncodeString(string: String) -> String {
/*
// -----------------------------------------
[getBase64EncodeString 메소드 설명]
// -----------------------------------------
1. 호출 방법 : C_Encryption().getBase64EncodeString(string: "hello")
// -----------------------------------------
2. 리턴 결과 : Base64 암호화 문자열 반환
// -----------------------------------------
*/
// [리턴 데이터 변수 선언 실시]
var returnData = ""
if string != nil && string.count>0 && string != "" {
let strData = string.data(using: .utf8)! // Data 형식으로 만들기
returnData = strData.base64EncodedString() // Data 형식을 Base64 String 으로 변환
}
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> getBase64EncodeString() :: base64 인코딩 실시]")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// */
// [리턴 데이터 반환]
return returnData
}
// MARK: - [base64 디코딩]
func getBase64DecodeString(string: String) -> String {
/*
// -----------------------------------------
[getBase64DecodeString 메소드 설명]
// -----------------------------------------
1. 호출 방법 : C_Encryption().getBase64DecodeString(string: "aGVsbG8=")
// -----------------------------------------
2. 리턴 결과 : Base64 복호화 문자열 반환
// -----------------------------------------
*/
// [리턴 데이터 변수 선언 실시]
var returnData = ""
if string != nil && string.count>0 && string != "" {
let decodeData = Data(base64Encoded: string)! // Data 형식으로 만들기
returnData = String(data: decodeData, encoding: .utf8)! // Data 형식을 Base64 String 으로 변환
}
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> getBase64DecodeString() :: base64 디코딩 실시]")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// */
// [리턴 데이터 반환]
return returnData
}
// MARK: - [AES256 인코딩]
func getAES256EncodeString(secretKey:String, iv:String, string:String) -> String {
/*
// -----------------------------------------
[getAES256EncodeString 메소드 설명 : CBC 모드]
// -----------------------------------------
1. AES 암호화 란 비밀키를 사용해 인코딩 , 디코딩을 수행하는 암호화 기법입니다
// -----------------------------------------
2. AES 128 [secret key] : 16 byte
// -----------------------------------------
3. AES 192 [secret key] : 24 byte
// -----------------------------------------
4. AES 256 [secret key] : 32 byte
// -----------------------------------------
5. AES Iv [공통] : 16 byte
// -----------------------------------------
6. 필수 사항 [브릿지 헤더에 import 추가] : #import <CommonCrypto/CommonCrypto.h>
// -----------------------------------------
7. 호출 방법 :
- iv 값 없이 호출 : C_Encryption().getAES256EncodeString(secretKey:"0123456789abcdef0123456789abcdef", iv:"", string:"hello")
- iv 값 포함 호출 : C_Encryption().getAES256EncodeString(secretKey:"0123456789abcdef0123456789abcdef", iv:"0123456789abcdef", string:"hello")
// -----------------------------------------
*/
// [리턴 데이터 반환 변수 선언]
var returnData = ""
// [사전 인풋 값 체크 방어 로직 추가]
if secretKey != nil && secretKey != "" && secretKey.count == 32
&& string != nil && string != "" && string.count > 0 {
// [AES256 : 비밀키 길이가 32 필요]
// [iv 값 길이 16 필요]
// [데이터 길이가 null 아니어야함]
}
else {
print("")
print("====================================")
print("[C_Encryption >> getAES256EncodeString() :: AES256 인코딩 실시]")
print("-------------------------------")
print("error :: 인풋 데이터 체크 에러 발생")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv :: \(iv)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [리턴 결과 반환]
return returnData
}
// [인풋 값을 Data 형식으로 생성 실시]
let keyData = secretKey.data(using: .utf8)!
let ivData = iv.data(using: .utf8)!
let strData = string.data(using: .utf8)!
// [인코딩 Data 생성 실시]
guard let encodeData = try? C_Encryption().crypt(
key: keyData,
iv: ivData,
input: strData,
operation: CCOperation(kCCEncrypt)
)
else {
print("")
print("====================================")
print("[C_Encryption >> getAES256EncodeString() :: AES256 인코딩 실시]")
print("-------------------------------")
print("error :: AES256 인코딩 수행 에러")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv :: \(iv)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
return returnData
}
// [정상적으로 인코딩 데이터가 생성된 경우 Base64 로 포맷 후 리턴 실시]
returnData = encodeData.base64EncodedString()
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> getAES256EncodeString() :: AES256 인코딩 실시]")
print("-------------------------------")
print("type :: Success")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv :: \(iv)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [결과 리턴 실시]
return returnData
}
// MARK: - [AES256 디코딩]
func getAES256DecodeString(secretKey:String, iv:String, string:String) -> String {
/*
// -----------------------------------------
[getAES256DecodeString 메소드 설명 : CBC 모드]
// -----------------------------------------
1. AES 암호화 란 비밀키를 사용해 인코딩 , 디코딩을 수행하는 암호화 기법입니다
// -----------------------------------------
2. AES 128 [secret key] : 16 byte
// -----------------------------------------
3. AES 192 [secret key] : 24 byte
// -----------------------------------------
4. AES 256 [secret key] : 32 byte
// -----------------------------------------
5. AES Iv [공통] : 16 byte
// -----------------------------------------
6. 필수 사항 [브릿지 헤더에 import 추가] : #import <CommonCrypto/CommonCrypto.h>
// -----------------------------------------
7. 호출 방법 :
- iv 값 없이 호출 : C_Encryption().getAES256DecodeString(secretKey:"0123456789abcdef0123456789abcdef", iv:"", string:"pZwJZBLuy3mDACEQT4YTBw==")
- iv 값 포함 호출 : C_Encryption().getAES256DecodeString(secretKey:"0123456789abcdef0123456789abcdef", iv:"0123456789abcdef", string:"UQdw44JDqzsxYpkSCwXDIA==")
// -----------------------------------------
*/
// [리턴 데이터 반환 변수 선언]
var returnData = ""
// [사전 인풋 값 체크 방어 로직 추가]
if secretKey != nil && secretKey != "" && secretKey.count == 32
&& string != nil && string != "" && string.count > 0 {
// [AES256 : 비밀키 길이가 32 필요]
// [iv 값 길이 16 필요]
// [데이터 길이가 null 아니어야함]
}
else {
print("")
print("====================================")
print("[C_Encryption >> getAES256DecodeString() :: AES256 디코딩 실시]")
print("-------------------------------")
print("error :: 인풋 데이터 체크 에러 발생")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv :: \(iv)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [리턴 결과 반환]
return returnData
}
// [인풋 값을 Data 형식으로 생성 실시]
let keyData = secretKey.data(using: .utf8)!
let ivData = iv.data(using: .utf8)!
let strData = Data(base64Encoded: string)!
// [디코딩 Data 생성 실시]
guard let decodeData = try? C_Encryption().crypt(
key: keyData,
iv: ivData,
input: strData,
operation: CCOperation(kCCDecrypt)
)
else {
print("")
print("====================================")
print("[C_Encryption >> getAES256DecodeString() :: AES256 디코딩 실시]")
print("-------------------------------")
print("error :: AES256 디코딩 수행 에러")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv :: \(iv)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
return returnData
}
// [정상적으로 디코딩 데이터가 생성된 경우 원본 데이터 리턴 실시]
returnData = String(data:decodeData, encoding: .utf8) ?? ""
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> getAES256DecodeString() :: AES256 디코딩 실시]")
print("-------------------------------")
print("type :: Success")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv :: \(iv)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [결과 리턴 실시]
return returnData
}
// MARK: - [AES256 에러 타입 정의 및 데이터 인코딩 , 디코딩 수행 실시]
enum Error: Swift.Error {
case keyGeneration(status: Int)
case cryptoFailed(status: CCCryptorStatus)
case badKeyLength
case badInputVectorLength
}
private func crypt(key: Data, iv:Data, input: Data, operation: CCOperation) throws -> Data {
// MARK: [SecretKeySpec : 인코딩, 디코딩 수행에서 AES 지정]
let secretKeySpecType = kCCAlgorithmAES
// MARK: [Cipher : 인코딩, 디코딩 수행에서 필요한 패딩 지정]
let padding = kCCOptionPKCS7Padding
// MARK: [인코딩 및 디코딩 수행 데이터]
var outLength = Int(0)
var outBytes = [UInt8](repeating: 0, count: input.count + kCCBlockSizeAES128)
// MARK: [키 생성 상태 값 지정]
var status: CCCryptorStatus = CCCryptorStatus(kCCSuccess)
input.withUnsafeBytes { (encryptedBytes: UnsafePointer<UInt8>!) -> () in
iv.withUnsafeBytes { (ivBytes: UnsafePointer<UInt8>!) in
key.withUnsafeBytes {
(keyBytes: UnsafePointer<UInt8>!) -> () in status = CCCrypt(
operation,
// MARK: [SecretKeySpec : 인코딩, 디코딩 수행에서 AES 지정]
CCAlgorithm(secretKeySpecType),
// MARK: [Cipher : 인코딩, 디코딩 수행에서 필요한 패딩 지정]
CCOptions(padding),
// MARK: [Cipher : KeySpec + iv]
keyBytes, // [key]
key.count, // [keylength]
// MARK: [Cipher : KeySpec + iv]
ivBytes, // [iv]
// MARK: [inputData]
encryptedBytes, // [inputData]
input.count, // [inputDataLength]
// MARK: [outputData]
&outBytes, // [outputData]
outBytes.count, // [outputDataLength]
&outLength // [dataOutMoved]
)
}
}
}
guard status == kCCSuccess else {
throw Error.cryptoFailed(status: status)
}
return Data(bytes: UnsafePointer<UInt8>(outBytes), count: outLength)
}
// MARK: - [URL 인코딩 관련 메소드]
func urlEncodeString(data: String) -> String {
/*
// -----------------------------------------
[urlEncodeString 메소드 설명]
// -----------------------------------------
1. URL 인코딩 관련 메소드
// -----------------------------------------
2. 호출 방법 : C_Encryption().urlEncodeString(data: "투케이")
// -----------------------------------------
3. 리턴 반환 : URL 인코딩 데이터
// -----------------------------------------
*/
// [초기 리턴 데이터 변수 선언 실시]
var returnData = ""
// [인풋 데이터 널 체크 수행 실시]
if data != nil
&& data.count>0
&& data != ""
&& data.trimmingCharacters(in: .whitespacesAndNewlines) != ""
&& data.trimmingCharacters(in: .whitespacesAndNewlines) != "null"
&& data.isEmpty == false {
// [URL 인코딩 수행 실시]
returnData = data.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)!
}
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> urlEncodeString() :: URL 인코딩 수행 실시]")
print("-------------------------------")
print("input :: \(data)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [리턴 데이터 반환 실시]
return returnData
}
// MARK: - [URL 디코딩 관련 메소드]
func urlDecodeString(data: String) -> String {
/*
// -----------------------------------------
[urlDecodeString 메소드 설명]
// -----------------------------------------
1. URL 디코딩 관련 메소드
// -----------------------------------------
2. 호출 방법 : C_Encryption().urlDecodeString(data: "%ED%88%AC%EC%BC%80%EC%9D%B4")
// -----------------------------------------
3. 리턴 반환 : URL 디코딩 데이터
// -----------------------------------------
*/
// [초기 리턴 데이터 변수 선언 실시]
var returnData = ""
// [인풋 데이터 널 체크 수행 실시]
if data != nil
&& data.count>0
&& data != ""
&& data.trimmingCharacters(in: .whitespacesAndNewlines) != ""
&& data.trimmingCharacters(in: .whitespacesAndNewlines) != "null"
&& data.isEmpty == false {
// [URL 디코딩 수행 실시]
returnData = data.removingPercentEncoding!
}
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> urlDecodeString() :: URL 디코딩 수행 실시]")
print("-------------------------------")
print("input :: \(data)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [리턴 데이터 반환 실시]
return returnData
}
// MARK: - [Aes256 인코딩 : key + iv + salt 사용]
func getAES_Salt_EncodeString(secretKey:String, iv:String, salt:String, string:String) -> String {
/*
// -----------------------------------------
[getAES_Salt_EncodeString 메소드 설명]
// -----------------------------------------
1. AES 암호화 란 비밀키를 사용해 인코딩 , 디코딩을 수행하는 암호화 기법입니다
// -----------------------------------------
2. AES 128 [secret key] : 16 byte
// -----------------------------------------
3. AES 192 [secret key] : 24 byte
// -----------------------------------------
4. AES 256 [secret key] : 32 byte
// -----------------------------------------
5. AES Iv [공통] : 16 byte
// -----------------------------------------
6. AES Salt [공통] : 16 byte
// -----------------------------------------
7. 필수 사항 [브릿지 헤더에 import 추가] : #import <CommonCrypto/CommonCrypto.h>
// -----------------------------------------
8. 호출 방법 :
C_Encryption().getAES_Salt_EncodeString(
secretKey:"0123456789abcdef0123456789abcdef",
iv:"0123456789abcdef0123456789abcdef",
salt: "0123456789abcdef0123456789abcdef",
string:"hello"
)
// -----------------------------------------
*/
// [리턴 데이터 반환 변수 선언]
var returnData = ""
// [사전 인풋 값 체크 방어 로직 추가]
if secretKey != nil && secretKey != "" && secretKey.isEmpty == false && secretKey.count == 32
&& iv != nil && iv != "" && iv.isEmpty == false && iv.count == 32
&& salt != nil && salt != "" && salt.isEmpty == false && salt.count == 32
&& string != nil && string != "" && string.isEmpty == false && string.count > 0 {
// [AES256 : 비밀키 길이가 32 필요]
// [iv 값 길이 32 필요 : hex]
// [salt 값 길이 32 필요 : hex]
// [데이터 길이가 null 아니어야함]
}
else {
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_EncodeString() :: AES [key + iv + salt] 인코딩 실시]")
print("-------------------------------")
print("error :: 인풋 데이터 체크 에러 발생")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [리턴 결과 반환]
return returnData
}
// [인풋 값을 Data 형식으로 생성 실시]
let keyData = secretKey.data(using: .utf8)!
let ivData = self.hexStringToData(string: iv) // [hex >> byte 변환]
let saltData = self.hexStringToData(string: salt) // [hex >> byte 변환]
let strData = string.data(using: .utf8)!
// [key + salt 사용해 새로운 키 생성 실시]
guard let newKey = try? C_Encryption().createKey(
secretKey: keyData, // [인풋 비밀키]
salt: saltData, // [인풋 salt 데이터]
iterationCount: UInt32(1000), // [iterationCount]
keyLength: kCCKeySizeAES256 // [256 = 32 length]
)
else {
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_EncodeString() :: AES [key + iv + salt] 인코딩 실시]")
print("-------------------------------")
print("error :: 새로운 비밀키 생성 에러")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
return returnData
}
// [인코딩 Data 생성 실시]
guard let encodeData = try? C_Encryption().crypt(
key: newKey,
iv: ivData,
input: strData,
operation: CCOperation(kCCEncrypt)
)
else {
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_EncodeString() :: AES [key + iv + salt] 인코딩 실시]")
print("-------------------------------")
print("error :: AES256 인코딩 수행 에러")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
return returnData
}
// [정상적으로 인코딩 데이터가 생성된 경우 Base64 로 포맷 후 리턴 실시]
returnData = encodeData.base64EncodedString()
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_EncodeString() :: AES [key + iv + salt] 인코딩 실시]")
print("-------------------------------")
print("type :: Success")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [결과 리턴 실시]
return returnData
}
// MARK: - [Aes256 디코딩 : key + iv + salt 사용]
func getAES_Salt_DecodeString(secretKey:String, iv:String, salt:String, string:String) -> String {
/*
// -----------------------------------------
[getAES_Salt_DecodeString 메소드 설명]
// -----------------------------------------
1. AES 암호화 란 비밀키를 사용해 인코딩 , 디코딩을 수행하는 암호화 기법입니다
// -----------------------------------------
2. AES 128 [secret key] : 16 byte
// -----------------------------------------
3. AES 192 [secret key] : 24 byte
// -----------------------------------------
4. AES 256 [secret key] : 32 byte
// -----------------------------------------
5. AES Iv [공통] : 16 byte
// -----------------------------------------
6. AES Salt [공통] : 16 byte
// -----------------------------------------
7. 필수 사항 [브릿지 헤더에 import 추가] : #import <CommonCrypto/CommonCrypto.h>
// -----------------------------------------
8. 호출 방법 :
C_Encryption().getAES_Salt_DecodeString(
secretKey:"0123456789abcdef0123456789abcdef",
iv:"0123456789abcdef0123456789abcdef",
salt: "0123456789abcdef0123456789abcdef",
string:"0yHy16m2dy5OpZH2+NX/4w=="
)
// -----------------------------------------
*/
// [리턴 데이터 반환 변수 선언]
var returnData = ""
// [사전 인풋 값 체크 방어 로직 추가]
if secretKey != nil && secretKey != "" && secretKey.isEmpty == false && secretKey.count == 32
&& iv != nil && iv != "" && iv.isEmpty == false && iv.count == 32
&& salt != nil && salt != "" && salt.isEmpty == false && salt.count == 32
&& string != nil && string != "" && string.isEmpty == false && string.count > 0 {
// [AES256 : 비밀키 길이가 32 필요]
// [iv 값 길이 32 필요 : hex]
// [salt 값 길이 32 필요 : hex]
// [데이터 길이가 null 아니어야함]
}
else {
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_DecodeString() :: AES [key + iv + salt] 디코딩 실시]")
print("-------------------------------")
print("error :: 인풋 데이터 체크 에러 발생")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [리턴 결과 반환]
return returnData
}
// [인풋 값을 Data 형식으로 생성 실시]
let keyData = secretKey.data(using: .utf8)!
let ivData = self.hexStringToData(string: iv) // [hex >> byte 변환]
let saltData = self.hexStringToData(string: salt) // [hex >> byte 변환]
let strData = Data(base64Encoded: string)!
// [key + salt 사용해 새로운 키 생성 실시]
guard let newKey = try? C_Encryption().createKey(
secretKey: keyData, // [인풋 비밀키]
salt: saltData, // [인풋 salt 데이터]
iterationCount: UInt32(1000), // [iterationCount]
keyLength: kCCKeySizeAES256 // [256 = 32 length]
)
else {
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_DecodeString() :: AES [key + iv + salt] 디코딩 실시]")
print("-------------------------------")
print("error :: 새로운 비밀키 생성 에러")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
return returnData
}
// [디코딩 Data 생성 실시]
guard let decodeData = try? C_Encryption().crypt(
key: newKey,
iv: ivData,
input: strData,
operation: CCOperation(kCCDecrypt)
)
else {
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_DecodeString() :: AES [key + iv + salt] 디코딩 실시]")
print("-------------------------------")
print("error :: AES256 디코딩 수행 에러")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
return returnData
}
// [정상적으로 디코딩 데이터가 생성된 경우 원본 데이터 리턴 실시]
returnData = String(data:decodeData, encoding: .utf8) ?? ""
// [로그 출력 실시]
print("")
print("====================================")
print("[C_Encryption >> getAES_Salt_DecodeString() :: AES [key + iv + salt] 디코딩 실시]")
print("-------------------------------")
print("type :: Success")
print("-------------------------------")
print("secretKey :: \(secretKey)")
print("-------------------------------")
print("iv [hex] :: \(iv)")
print("-------------------------------")
print("salt [hex] :: \(salt)")
print("-------------------------------")
print("input :: \(string)")
print("-------------------------------")
print("return :: \(returnData)")
print("====================================")
print("")
// [결과 리턴 실시]
return returnData
}
// MARK: - [key + salt 사용해 new key 생성 수행 부분]
private func createKey(secretKey: Data, salt: Data, iterationCount:UInt32, keyLength:Int) throws -> Data {
// MARK: [알고리즘 변수 선언]
let algo_1 = kCCPBKDF2
let algo_2 = kCCPRFHmacAlgSHA1
// MARK: [키 생성 상태 값 지정]
var status = Int32(0)
var derivedBytes = [UInt8](repeating: 0, count: keyLength)
secretKey.withUnsafeBytes { (passwordBytes: UnsafePointer<Int8>!) in
salt.withUnsafeBytes { (saltBytes: UnsafePointer<UInt8>!) in
status = CCKeyDerivationPBKDF(
// MARK: [알고리즘 - 1]
CCPBKDFAlgorithm(algo_1), // [알고리즘]
// MARK: [비밀키 지정]
passwordBytes, // [secretKey]
secretKey.count, // [secretKey Length]
// MARK: [salt 지정]
saltBytes, // [salt]
salt.count, // [salt Length]
// MARK: [알고리즘 - 2]
CCPseudoRandomAlgorithm(algo_2), // [알고리즘]
// MARK: [iterationCount]
iterationCount,
// MARK: [KeySpec : keyLength]
&derivedBytes, // [derivedKey]
keyLength // [keyLength]
)
}
}
guard status == 0 else {
throw Error.keyGeneration(status: Int(status))
}
return Data(bytes: UnsafePointer<UInt8>(derivedBytes), count: keyLength)
}
// MARK: - [hex string to byte array 변환 메소드]
func hexStringToData(string: String) -> Data {
let stringArray = Array(string)
var data: Data = Data()
for i in stride(from: 0, to: string.count, by: 2) {
let pair: String = String(stringArray[i]) + String(stringArray[i+1])
if let byteNum = UInt8(pair, radix: 16) {
let byte = Data([byteNum])
data.append(byte)
}
else{
fatalError()
}
}
return data
}
} // [클래스 종료]
[결과 출력]
반응형
'투케이2K 유틸파일' 카테고리의 다른 글
Comments