タコさんブログ

プログラミングメモと小言

CryptoSwiftでAES暗号 (AES-256-CBC)

CryptoSwiftを使用して、 平文をSwift側で暗号化し、Ruby側で復号化する。
暗号方式はAES、鍵は256ビット長、暗号利用モードはCBC、パディング方式はPKCSを使用する。

環境

準備

適当な256ビット長の鍵(文字列)を用意する。

BDC171111B7285F67F035497EE9A081D

Swift

// 暗号化する平文
let cleartext = "Hello CryptoSwift"
// 平文をエンコードし、さらにバイト列に変換
let byteText = cleartext.dataUsingEncoding(NSUTF8StringEncoding)!.arrayOfBytes()
// 用意した鍵
let key = "BDC171111B7285F67F035497EE9A081D"
// 鍵をエンコードし、さらにバイト列に変換
let byteKey = key.dataUsingEncoding(NSUTF8StringEncoding)!.arrayOfBytes()
// IV(初期化ベクトル)、ivの型は[UInt8]
let iv = AES.randomIV(AES.blockSize)
do {
  // AES-256-CBCインスタンスの生成
  let aes = try AES(key: byteKey, iv: iv, blockMode: .CBC)
  // 平文を暗号化
  // デフォルトのパディングがPKC7になっているので、ここでは特に指定しない
  let encrypted = try aes.encrypt(byteText)
  // ruby側で使用するので、IV、encryptedを出力
  // バイト列([UInt8])をNSDataに変換し、Base64文字列にエンコード
  let strIV = NSData(bytes:iv).base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
  print("IV: " + strIV)  // 出力 -> IV: lBMiK2GWEwrPgNdGfrJEig==
  let strEnc = NSData(bytes:encrypted).base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
  print("Encrypted: " + strEnc)  // 出力 -> Encrypted: MHf5ZeUL/gjviiZitpZKJFuqppdTgEe+IklDgg3N1fQ=
} catch {
  print("Error")
}

CryptoSwift Note

  • AES生成時に鍵長を128、192に変更すれば、AES-128, AES-192も利用できる。
  • NSDataからバイト列に変換する arrayOfBytes がExtensionで用意されている
  • バイト列からNSDataを生成する簡易イニシャライザ NSData(bytes: [UInt8]) がExtensionで用意されている

Ruby

require 'base64'   # Base64を使用する
require 'openssl'  # OpenSSLを使用する

# 用意した鍵

key = 'BDC171111B7285F67F035497EE9A081D'
# iOS側で生成したIVをBase64デコード
iv = Base64::decode64 'lBMiK2GWEwrPgNdGfrJEig=='
# iOS側で生成した暗号文をBase64デコード
encrypted = Base64::decode64 'MHf5ZeUL/gjviiZitpZKJFuqppdTgEe+IklDgg3N1fQ='

# Cipherインスタンスの生成

cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.padding = 1  # パディングを有効にする
cipher.key = key    # 鍵の設定
cipher.iv = iv      # IVの設定
# 復号化
decrypted = ""
decrypted << cipher.update(encrypted)
decrypted << cipher.final

p decrypted  # 出力:Hello CryptoSwift

感想

CryptoSwiftは作者の興味と学習のために実装したと CryptoSwift: Cryptography You Can Doで言及されているとおり、暗号の参考程度にとどめるのが良いと思う。プロダクションに使用するのであれば、CommonCrypto か CommonCryptoのラッパーIDZSwiftCommonCryptoを使用する方が良いのではないか。IDZSwiftCommonCrypto の使用例 CommonCryptoのSwift製ラッパー IDZSwiftCommonCrypto を使ってみる - タコさんブログ

参考URL