タコさんブログ

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

CommonCryptoのSwift製ラッパー IDZSwiftCommonCrypto を使ってみる

IDZSwiftCommonCrypto を使ってみる

IDZSwiftCommonCryptoAppleCommonCryptoSwiftラッパーで、Realmで紹介されていたので、ちょっと試してみた。CryptoSwiftでAES暗号 (AES-256-CBC) - タコさんブログと同じように Swift側でIDZSwiftCommonCryptoを使って暗号化(AES-256-CBC)し、Ruby側で復号化する。

環境

IDZSwiftCommonCryptoで暗号化(AES-256-CBC

do {
  // 暗号化する平文
  let plainText = "Hello IDZSwiftCommonCrypto"
  // 用意した鍵(適当な256ビット長)を16進文字列に変換
  let keyStr = "BDC171111B7285F67F035497EE9A081D".utf8ToHexString()
  // 16進文字列を[UInt8]に変換
  let keyHex = arrayFromHexString(keyStr)
  // 16 byteの初期化ベクトル
  let iv = try Random.generateBytes(16)
  // Cryptorを生成
  let cryptor = Cryptor(operation:.Encrypt, algorithm:.AES, options:.PKCS7Padding, key:keyHex, iv:iv)
  // 暗号化
  if let cipheredText = cryptor.update(plainText)?.final() {
      // 使用したIV:Ts4lC0DdSZvufWOPb3uTbg==
      print(base64EncodedStringFromArray(iv))
      // 暗号化された文字列:gWTKuU8SK6g9OrNR2SLdtSxM/OCYXa2ZHVFkRvn3Qgg=
      print(base64EncodedStringFromArray(cipheredText))
  }
} catch RNGStatus.ParamError {
  print("IV Error")
} catch {
  print("error")
}

ちょっとしたエクステンション・関数

// UTF-8文字列をHex文字列に変換するエクステンション
extension String {
  func utf8ToHexString() -> String {
    return self.utf8.map { NSString(format: "%2X", $0) as String }.reduce("", combine: {$0 + $1})
  }
}

// UInt8配列をBase64文字列に変換する関数
func base64EncodedStringFromArray(array: [UInt8]) -> String {
  let nsdata = dataFromByteArray(array)
  return nsdata.toBase64EncodedString()
}

// NSDataをBase64文字列に変換するエクステンション
extension NSData {
  func toBase64EncodedString() -> String {
    return self.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
  }
}

初期化ベクトルは16バイトで良いのか調べたら、Stack Overflow (Need solution for wrong IV length in AES)にあった。

Ruby側で復号化

Ruby側の復号化についてはCryptoSwiftでAES暗号 (AES-256-CBC) - タコさんブログとほぼ同じ。

require 'base64'
require 'openssl'

key = 'BDC171111B7285F67F035497EE9A081D'
encrypted = Base64::decode64 'gWTKuU8SK6g9OrNR2SLdtSxM/OCYXa2ZHVFkRvn3Qgg='
iv = Base64::decode64 'Ts4lC0DdSZvufWOPb3uTbg=='

# 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 IDZSwiftCommonCrypto

感想

IDZSwiftCommonCryptoは、Apple製のCommonCryptoを使用したラッパーなので、ある程度信はできるんじゃないでしょうか。ただあまりソースの更新はなさそう(?)

参考URL