原文地址: iOS API 无法使用 SHA-256 和 MGF1Padding 加密/解密 RSA/ECB/OAEP
iOS 标准 API 无法加密/解密 Java RSA-OAEP“RSA/ECB/OAEPwithSHA-256andMGF1Padding”。SHA-512 相同。
iOS API 和 Java OAEP 之间的差异
OAEP是RSA中使用的明文填充方法,并使用两种摘要(散列)算法作为算法。
信息摘要
MGF(掩模生成函数)摘要
iOS 标准 API 和 Java API 之间的 OAEP 规范略有不同。
Java 中的 RSA/ECB/OAEPwithSHA-256andMGF1Padding:消息摘要=SHA-256,MGF1 摘要= SHA-1
SecurityAlgorithm.rsaEncryptionOAEPSHA256(适用于 iOS):消息摘要=SHA-256,MGF1 摘要= SHA-256
消息摘要相同,但MGF1摘要不同,因此它们不兼容。 通常 SHA-1 对于 MGF1 摘要应该足够了,但 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上有一个验证程序和库 。
对苹果说些什么
SecKeyAlgorithm的解释太短了,不是吗?