暗号化
読み込みと書き出し
暗号化したいファイルの読み込んで暗号化し、そのデータを書き出します。
// 読み込み
let inputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/before.json")
let inputData = try! Data(contentsOf: inputUrl)
// 書き出し
let outputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/encrypto.byte")
try cryptData.write(to: outputUrl)
暗号化後のデータサイズを計算
IV(initialization vector)を含めたサイズを計算します。
let ivSize = kCCBlockSizeAES128
let cryptLength = size_t(ivSize + inputData.count + kCCBlockSizeAES128)
暗号化
var numBytesEncrypted: size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptStatus = cryptData.withUnsafeMutableBytes { cryptBytes in
inputData.withUnsafeBytes { dataBytes in
key.withUnsafeBytes { keyBytes in
CCCrypt(
CCOperation(kCCEncrypt),
CCAlgorithm(kCCAlgorithmAES),
options,
keyBytes,
keyLength,
cryptBytes,
dataBytes,
inputData.count,
cryptBytes + kCCBlockSizeAES128,
cryptLength,
&numBytesEncrypted
)
}
}
}
Bridging Headerの作成
今回はObjective-C製のCommonCryptoを用いるので、Bridging Headerファイルを作成します。
#import <CommonCrypto/CommonCrypto.h>
ソースコード全文
encrypto.swift
import Foundation
let inputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/before.json")
let inputData = try! Data(contentsOf: inputUrl)
let key = "0123456789ABCDEF".data(using: .utf8)!
let keyLength = key.count
let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
if validKeyLengths.contains(keyLength) {
let ivSize = kCCBlockSizeAES128
let cryptLength = size_t(ivSize + inputData.count + kCCBlockSizeAES128)
var cryptData = Data(count: cryptLength)
let status = cryptData.withUnsafeMutableBytes { ivBytes in
SecRandomCopyBytes(kSecRandomDefault, kCCBlockSizeAES128, ivBytes)
}
if status == 0 {
var numBytesEncrypted: size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptStatus = cryptData.withUnsafeMutableBytes { cryptBytes in
inputData.withUnsafeBytes { dataBytes in
key.withUnsafeBytes { keyBytes in
CCCrypt(
CCOperation(kCCEncrypt),
CCAlgorithm(kCCAlgorithmAES),
options,
keyBytes,
keyLength,
cryptBytes,
dataBytes,
inputData.count,
cryptBytes + kCCBlockSizeAES128,
cryptLength,
&numBytesEncrypted
)
}
}
}
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
cryptData.count = numBytesEncrypted + ivSize
} else {
print("Encryption failed")
return
}
let outputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/encrypto.byte")
try cryptData.write(to: outputUrl)
}
}
bridging-header.h
#import <CommonCrypto/CommonCrypto.h>
複合化
読み込みと書き出し
ファイルを読み込んで復号化して、そのデータを書き出します。
// 読み込み
let inputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/encrypto.byte")
let inputData = try! Data(contentsOf: inputUrl)
// 書き出し
let outputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/after.json")
try clearData.write(to: outputUrl)
復号化後のデータサイズを計算
IVを除いたサイズを計算します。
let ivSize = kCCBlockSizeAES128
let clearLength = size_t(inputData.count - ivSize)
複合
var numBytesDecrypted: size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptStatus = clearData.withUnsafeMutableBytes { cryptBytes in
inputData.withUnsafeBytes { dataBytes in
key.withUnsafeBytes { keyBytes in
CCCrypt(
CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES128),
options,
keyBytes,
keyLength,
dataBytes,
dataBytes + kCCBlockSizeAES128,
clearLength,
cryptBytes,
clearLength,
&numBytesDecrypted
)
}
}
}
Bridging Headerの作成
今回はObjective-C製のCommonCryptoを用いるので、Bridging Headerファイルを作成します。
#import <CommonCrypto/CommonCrypto.h>
ソースコード全文
decrypto.swift
import Foundation
let inputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/encrypto.byte")
let inputData = try! Data(contentsOf: inputUrl)
let key = "0123456789ABCDEF".data(using: .utf8)!
let keyLength = key.count
let validKeyLengths = [kCCKeySizeAES128, kCCKeySizeAES192, kCCKeySizeAES256]
if validKeyLengths.contains(keyLength) {
let ivSize = kCCBlockSizeAES128
let clearLength = size_t(inputData.count - ivSize)
var clearData = Data(count: clearLength)
var numBytesDecrypted: size_t = 0
let options = CCOptions(kCCOptionPKCS7Padding)
let cryptStatus = clearData.withUnsafeMutableBytes { cryptBytes in
inputData.withUnsafeBytes { dataBytes in
key.withUnsafeBytes { keyBytes in
CCCrypt(
CCOperation(kCCDecrypt),
CCAlgorithm(kCCAlgorithmAES128),
options,
keyBytes,
keyLength,
dataBytes,
dataBytes + kCCBlockSizeAES128,
clearLength,
cryptBytes,
clearLength,
&numBytesDecrypted
)
}
}
}
if UInt32(cryptStatus) == UInt32(kCCSuccess) {
clearData.count = numBytesDecrypted
} else {
print("Decryption failed:", cryptStatus)
return
}
let outputUrl: URL = URL(fileURLWithPath: "/Users/ユーザー名/Desktop/after.json")
try clearData.write(to: outputUrl)
}
bridging-header.h
#import <CommonCrypto/CommonCrypto.h>
コマンドラインでの実行
コンパイル
swiftcコマンドでコンパイルします。
-import-objc-header
オプションでブリッジングヘッダファイルを指定できます。
swiftc -import-objc-header bridging-header.h encrypto.swift
実行
生成された実行ファイルはシェルスクリプトと同じ感じで実行できます。
./encrypto