iOS Swift使用自定义私钥对字节数组进行SHA256withRSA签名的实现
你现有Swift代码签名结果和Java不一致的核心原因是算法选择错误:你使用的rsaSignatureDigestPSSSHA256要求输入为预计算完成的SHA256摘要,但Java实现是传入原始字节数组由Signature内部自动计算摘要,两边逻辑完全不匹配。同时私钥导入参数不全、强制解包也会导致功能不稳定。
以下是可与Java实现完全对齐的Swift代码:
import Security // 签名错误枚举 enum SignError: Error { case invalidPrivateKey case invalidInputData case signFailed(CFError?) } /// 非对称签名方法 /// - Parameters: /// - originalString: 待签名的原始字符串 /// - privateKeyBase64: Base64编码的私钥(支持PEM格式带头尾的输入) /// - algorithm: 签名算法,需和Java侧算法完全对应 /// - base64Options: 签名结果Base64编码的配置项 /// - Returns: Base64编码的签名结果 public func sign(originalString: String, privateKeyBase64: String, algorithm: SecKeyAlgorithm = .rsaSignatureMessagePSSSHA256, base64Options: Data.Base64EncodingOptions = []) throws -> String { // 清理PEM格式私钥的头尾和换行符 var cleanedKeyString = privateKeyBase64 .replacingOccurrences(of: "-----BEGIN RSA PRIVATE KEY-----", with: "") .replacingOccurrences(of: "-----END RSA PRIVATE KEY-----", with: "") .replacingOccurrences(of: "-----BEGIN PRIVATE KEY-----", with: "") .replacingOccurrences(of: "-----END PRIVATE KEY-----", with: "") .replacingOccurrences(of: "\n", with: "") .trimmingCharacters(in: .whitespacesAndNewlines) guard let keyData = Data(base64Encoded: cleanedKeyString) else { throw SignError.invalidPrivateKey } // 私钥导入配置,密钥长度需和实际私钥对应,常见为2048/4096 let keyAttributes: [CFString: Any] = [ kSecAttrKeyType: kSecAttrKeyTypeRSA, kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrKeySizeInBits: 2048, kSecAttrIsPermanent: false ] var error: Unmanaged<CFError>? guard let privateKey = SecKeyCreateWithData(keyData as CFData, keyAttributes as CFDictionary, &error) else { throw SignError.signFailed(error?.takeRetainedValue()) } // 校验私钥支持所选签名算法 guard SecKeyIsAlgorithmSupported(privateKey, .sign, algorithm) else { throw SignError.invalidPrivateKey } guard let inputData = originalString.data(using: .utf8) else { throw SignError.invalidInputData } // 执行签名 guard let signedData = SecKeyCreateSignature(privateKey, algorithm, inputData as CFData, &error) as Data? else { throw SignError.signFailed(error?.takeRetainedValue()) } return signedData.base64EncodedString(options: base64Options) }
Java与Swift算法对应表
可根据Java侧algorithm.getJvmName()的返回值替换Swift的algorithm参数:
| Java算法名 | Swift SecKeyAlgorithm值 |
|---|---|
| SHA1withRSA | .rsaSignatureMessagePKCS1v15SHA1 |
| SHA256withRSA | .rsaSignatureMessagePKCS1v15SHA256 |
| SHA512withRSA | .rsaSignatureMessagePKCS1v15SHA512 |
| SHA256withRSA/PSS | .rsaSignatureMessagePSSSHA256 |
| SHA512withRSA/PSS | .rsaSignatureMessagePSSSHA512 |
注意事项
- 默认情况下Java和Swift的PSS签名参数一致:盐长等于摘要长度、掩码生成函数为MGF1+对应哈希算法,可直接对齐;如果Java侧自定义了PSS参数,需同步调整Swift侧配置
- 如果使用椭圆曲线(ECC)签名,只需将
kSecAttrKeyType改为kSecAttrKeyTypeEC,算法替换为对应的ecdsaSignatureMessageX962SHA256即可
内容的提问来源于stack exchange,提问作者Sandeep
相关产品推荐
相关产品推荐

