メモです。
あ、これはお肉です。
Swift の素振りで、RSA 暗号を使った文字列の暗号化/復号を行ってみました。
実装は、参考にしたこちらの記事そのまんまなのですが、現行の Swift4 では動かない箇所がいくつかありました。
ので、動くようにしたコードをここに残しておきます。
コード
func main() { // 暗号化対象の文字列と UInt8 Byte Array でのデータ、文字数を確保しておく let plainText = "I'm TomoyaShibata!" let plainTextData = [UInt8](plainText.utf8) let plainTextDataLength = plainText.count // 自作したキーペア生成メソッドの呼び出す let keyPair = self.generateKeyPair() let blockSize = SecKeyGetBlockSize(keyPair.publicKey!) // 暗号化した結果を入れる、公開鍵のブロック長に応じた変数を用意する var encryptedData = [UInt8]( repeating: 0, count: Int(blockSize) ) var encryptedDataLength = blockSize // 暗号化対象の文字列を暗号化する // 暗号化/復号のばあいパディングには SecPadding.PKCS1 または SecPadding.OAEP いずれかが利用可能 // それ以外は署名/検証にしか使えないってコメントに書いてあった let encryptOsStatus = SecKeyEncrypt( keyPair.publicKey!, SecPadding.PKCS1, plainTextData, plainTextDataLength, &encryptedData, &encryptedDataLength ) // 暗号化に失敗していたら終了する if encryptOsStatus != noErr { print("Encryption Error") return } // 復号した結果を入れる、公開鍵のブロック長に応じた変数を用意する var decryptedData = [UInt8]( repeating: 0, count: Int(blockSize) ) var decryptedDataLength = blockSize // 暗号化されたデータを復号する // 暗号化/復号のばあいパディングには SecPadding.PKCS1 または SecPadding.OAEP いずれかが利用可能 // それ以外は署名/検証にしか使えないってコメントに書いてあった let decryptOsStatus = SecKeyDecrypt( keyPair.privateKey!, SecPadding.PKCS1, encryptedData, encryptedDataLength, &decryptedData, &decryptedDataLength ) // 復号に失敗していたら終了する if decryptOsStatus != noErr { print("Decryption Error") return } // 復号したデータを文字列にする let decryptText = NSString( bytes: &decryptedData, length: decryptedDataLength, encoding: String.Encoding.utf8.rawValue )! // 暗号化の文字列と、復号したデータの文字列を比較して同じ文字列かどうかを確認する if decryptText.compare(plainText) == ComparisonResult.orderedSame { print("SUCCESS!") } else { print("FAIL...") } } func generateKeyPair() -> (publicKey: SecKey?, privateKey: SecKey?) { // RSA 暗号/2048桁という指定を変数に確保している // RSA 暗号なので、桁数には 1024、2048、4096 いずれかの値が設定可能 // 4096桁では体感できるレベルで遅いのでちょっと面白い let parameters: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeRSA, kSecAttrKeySizeInBits as String: 2048 ] // SecKeyGeneratePair を KeyPair を生成する var publicKey: SecKey? var privateKey: SecKey? let osStatus = SecKeyGeneratePair(parameters as CFDictionary, &publicKey, &privateKey) // エラーなく生成できたら公開鍵と秘密鍵を Tuple で返却する switch osStatus { case noErr: return (publicKey, privateKey) default: return (nil, nil) } }