【iOS】AESで暗号化・復号する方法（CryptoSwift）

## 背景
APIと連携するようなサーバー通信時には、平文ではなく暗号化したい。
そこで、`CryptoSwift`を用いて簡単に暗号化・復号できるらしいので試してみました。

[iOSアプリでAESでの暗号化のためCryptoSwiftを使用した](https://qiita.com/ochim/items/4690cdc5e7fde9ad1b45)
↓↓↓↓↓↓↓↓
自分の記事を作成中に`CryptoSwift`の良記事を見つけてしまったので、メモレベルで記載します。笑

## AESとは
>暗号化のやり方の一つ
2018年現在のアメリカで標準として採用されているやり方
共通鍵暗号方式
鍵長が128ビット、192ビット、256ビットから選ぶことができる
WPA2で標準で採用されているやり方
WPAで使われる場合もある
[引用：iOSアプリでAESでの暗号化のためCryptoSwiftを使用した](https://qiita.com/ochim/items/4690cdc5e7fde9ad1b45)

## バージョン

* Xcode 10.2.1
* Swift 5.0.1
* CryptoSwift 1.0.0

### CryptoSwiftライブラリを導入する
`CocoaPods`を用いてCryptoSwiftを導入します。`Podfile`は以下になります。

```:Podfile
target 'Qiita_AES' do
  use_frameworks!
  # CryptoSwiftライブラリを追加する
  pod 'CryptoSwift'
end
```

CocoaPodsの導入方法がわからない場合は、こちらの記事を参考にしてください。
[【Swift】CocoaPods導入手順
](https://qiita.com/ShinokiRyosei/items/3090290cb72434852460)

### 暗号化・復号用のEncryptionAESクラスを実装

```swift:EncryptionAES.swift
import Foundation
import CryptoSwift

class EncryptionAES {
    
    // 暗号化処理
    // key:変換キー
    // iv:初期化ベクトル(時間などを使用してランダム生成するとよりセキュアになる)
    // text:文字列
    func encrypt(key: String, iv:String, text:String) -> String {
        
        do {
            // 暗号化処理
            // AES インスタンス化
            let aes = try AES(key: key, iv: iv)
            let encrypt = try aes.encrypt(Array(text.utf8))
            
            // Data 型変換
            let data = Data( encrypt )
            // base64 変換
            let base64Data = data.base64EncodedData()
            // UTF-8変換 nil 不可
            guard let base64String =
                String(data: base64Data as Data, encoding: String.Encoding.utf8)
                else { return "" }

            // base64文字列
            return base64String
            
        } catch {
            // エラー処理
            return ""
        }
    }
    
    // 複合処理
    // key:変換キー
    // iv:🤭(時間などを使用してランダム生成するとよりセキュアになる)
    // base64:文字列
    func decrypt(key: String, iv:String, base64:String) -> String {
        
        do {
            // AES インスタンス化
            let aes = try AES(key: key, iv:iv)
            
            // base64 から Data型へ
            let byteData = base64.data(using: String.Encoding.utf8)! as Data
            // base64 デーコード
            guard let data = Data(base64Encoded: byteData)
                else { return "" }
            
            // UInt8 配列の作成
            let aBuffer = Array<UInt8>(data)
            // AES 複合
            let decrypted = try aes.decrypt(aBuffer)
            // UTF-8変換
            guard let text = String(data: Data(decrypted), encoding: .utf8)
                else { return "" }
            
            return text
        } catch {
            // エラー処理
            return ""
        }
    }
}
```

### 呼び出し方法

```swift
let key = "abcdefghijklmnop" // 128bit(16文字)のキーを入れる
let iv =  "1234567890123456" // データをシフト演算するキー128bit(16文字)
let json = "{\"id\":2,\"name\":\"ほげほげ君\",\"hobby\":\"ボルダリング\"}" // 暗号化・復号するjson

// EncryptionAESのインスタンス化
let aes = EncryptionAES()

// jsonを暗号化
let jsonEncrypted = try! aes.encrypt(key: key, iv: iv, text: json)
print(jsonEncrypted)
// -> PlOEf5oeBt2GsyWDHUk7OtOUV6nRPpYQvqE919jkrrpWaAvQc+IhkrO3gPmiNQbkQOLLXMlnQh5U2wbwEPYksg==

// jsonを復号
let jsonDecrypted = aes.decrypt(key: key, iv: iv, base64: jsonEncrypted)
print(jsonDecrypted)
// -> {"id":2,"name":"ほげほげ君","hobby":"ボルダリング"}
```

## まとめ
暗号化・復号と聞くと実装が大変なイメージでしたが、`CryptoSwift `なら簡単にできるのでおすすめです。^^

以上になります。
もし不明点や間違い等があればコメントくださいm(_ _)m