iOS の標準APIでは、Java の RSA-OAEP の "RSA/ECB/OAEPwithSHA-256andMGF1Padding" の暗号化・復号ができません。SHA-512も同様。
iOS API と Java の OAEP の違い
OAEP は RSA で使われる平文パディングの手法で、アルゴリズムとしては2つのダイジェスト(ハッシュ)アルゴリズムを使います。
- メッセージダイジェスト
- MGF(Mask Generation Function) ダイジェスト
iOS の標準API と Java API では OAEP の仕様が微妙に違います。
- Java の RSA/ECB/OAEPwithSHA-256andMGF1Padding: メッセージダイジェスト=SHA-256, MGF1ダイジェスト=SHA-1
- iOS の SecurityAlgorithm.rsaEncryptionOAEPSHA256: メッセージダイジェスト=SHA-256, MGF1ダイジェスト=SHA-256
メッセージダイジェストは同じなのですが、MGF1ダイジェストが違うため、互換性がありません。
MGF1ダイジェストのほうは普通 SHA-1 で十分なはずなのですが、iOS ではなぜかメッセージダイジェストに合わせて変わってしまう様子。
このため、iOS 標準API では、Java の "RSA/ECB/OAEPwithSHA-256andMGF1Padding" に対応することは不可能です。
対策1) Java 側を iOS に合わせる
Java 側を iOS の仕様に合わせる方法です。
Java 側では、メインダイジェストと MGF1 ダイジェストを個別に指定することができるので、容易に iOS 側に合わせることができます。
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
cipher.init(Cipher.DECRYPT_MODE, privKey,
new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT));
対策2) 自前で OAEP を実装する
iOS 側で自前で OAEP を実装する方法です。こちらはちょっと面倒。
iOS 側では、OAEP Padding のみを実装し、あとは rsaEncryptionRaw で RSA 暗号化・復号を実行する、ということで MGF1 ダイジェストをあわせることができます。
OAEP の実装自体はそれほど難しくありません。OAEP を実装したものを RsaOaepPadding.swift として公開しています。
これを使うと、RSA/ECB/OAEPwithSHA-256andMGF1Padding 相当の暗号化は以下のように実装できます。
let plainData = "TEST TEXT".data(using: .utf8)!
// main digest SHA256, MGF1 digest SHA1 で RsaOAEPPadding クラスを生成
let padding = RsaOAEPPadding(mainDigest: OAEPDigest.SHA256, mgf1Digest: OAEPDigest.SHA1)
// OAEP Padding を計算 (RSA鍵長は 2048bit = 256byte前提)
let padded = try! padding.pad(plain: plainData, blockSize: 256);
// raw で暗号化
guard let cipherData = SecKeyCreateEncryptedData(publicKey, SecKeyAlgorithm.rsaEncryptionRaw, padded as CFData, &error) else {
// Error処理
}
復号は以下のようになります。
guard let decryptedBlock = SecKeyCreateDecryptedData(privKey, SecKeyAlgorithm.rsaEncryptionRaw, cipherData as CFData, &error) else {
// Error 処理
}
// OAEP Padding 解除
let decrypted = try! padding.unpad(padded: decryptedBlock as Data)
let decryptedString = String(data: decrypted, encoding: .utf8)!
検証用テストプログラム
検証用のプログラムおよびライブラリを https://github.com/tmurakam/rsa-oaep においておきます。
Apple に言いたいこと
SecKeyAlgorithm の説明、不足しすぎじゃね?
参考文献・サイトなど
- OAEP (Wikipedia)
- RSAのパディング:PKCS#1 v1.5, OAEP, PSSを整理してみた