はじめに
queryParanetersに暗号化した値を貼り付けたらencode処理で怒られた、という個人的な備忘録です。
経緯
・普段暗号化処理はCryptoSwiftを使っているのですが、今回それを使わずに以下の記事を参考に暗号化処理を実装していました。
PEM形式の公開鍵を使ってRSA暗号する処理をSwiftでやってみた
iOSで Swiftから暗号化ライブラリを使う
・値を準備出来たので、APIKitのqueryParametersに値をブチ混んでみたら、response内のエラーメッセージで「decode出来んよ」と言われてしまいました。
・それだけなら暗号化処理を疑って終わりなのですが、作った値をAdvanced REST Clientで叩いてみたら正常値を返すので、APIKitを疑って覗いてみた次第です。
何が悪かったのか
・今回実装した通信処理で使う某APIのドキュメントに、暗号化処理の実装サンプルがあったので写経していたのですが、最後のaddingPercentEncoding()が余計でした。
func makeEcryptData() -> String? {
// 〜色々割愛〜
var pubKey = self.publicKey
let plainBuffer = [UInt8](plainString.utf8)
var cipherBufferSize = UInt(SecKeyGetBlockSize(pubKey))
var cipherBuffer = [UInt8](count:Int(cipherBufferSize), repeatedValue:0)
// 暗号化
let status = SecKeyEncrypt(pubKey,
SecPadding(kSecPaddingPKCS1),
plainBuffer,
UInt(plainBuffer.count),
&cipherBuffer,
&cipherBufferSize)
if (status != errSecSuccess){
return nil
}
let data = NSData(bytes: &cipherBuffer, length: Int(cipherBufferSize))
// base64でEncodeする分には問題無し
let encryption = data.base64EncodedSteing(options: NSData.Base64EncodingOptions.lineLength64Characters)
// ⭐️これは余計🌟
let rasHogeInfo = encryption.addingPercentEncoding(withAllowdedCharacters: NSCharacterSet.alphanumerics)!
return rsaHogeInfo
}
この処理をして、APIKitのqueryParametersにセットすると、以下のencode処理が実施され、最終的に作られるURL文字列には更にencodeされた文字列が入るので怒られるというオチでした。
public func buildURLRequest() throws -> URLRequest {
// 割愛
// ここ!
if let queryParameters = queryParameters, !queryParameters.isEmpty {
components.percentEncodedQuery = URLEncodedSerialization.string(from: queryParameters)
}
}
反省と改善策
・最終的に叩くURL文字列とBodyの中身はDEBUG時にはログを毎回出すようにする(自戒)
・APIKitを今のプロジェクトで初めて使っているのですが(Alamofireばかりだったので)、これを機に中身を勉強してみたいと思いました。
・ドキュメントに用意された実装サンプルを無闇に信じない
-> ここ問題は無いという決めつけが地味に痛かった。。
さいごに
通信時にログを用意していれば気づける問題ですが、同じように詰まっていた人の助けになれば幸いです。