You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中RSA加密块大小为256,如何适配300+字节文本加密?

解决RSA OAEP SHA512加密大文本及提升块大小的问题

一、关于提升RSA加密块大小到512字节

RSA的加密块大小完全由密钥长度决定:

  • 256字节块对应2048位RSA密钥(2048 ÷ 8 = 256)
  • 512字节块对应4096位RSA密钥(4096 ÷ 8 = 512)

要达到512字节的块大小,你需要:

  • 生成或从服务器获取4096位的RSA公钥,替换当前使用的2048位密钥
  • 注意:即使是4096位密钥,使用rsaEncryptionOAEPSHA512算法时,实际可加密的明文长度会小于512字节——OAEP填充会占用SHA512哈希长度(64字节)+ 2字节的填充开销,所以最大明文长度约为512 - 64 - 2 = 446字节,依然无法直接加密更大的文本。因此,加密大文本的标准方案是混合加密。

二、加密大文本的标准方案:混合加密

RSA适合加密小数据(比如对称密钥),对称加密(如AES)适合加密大文本,结合两者的步骤如下:

  1. 生成随机的AES对称密钥(推荐用AES-256-GCM,自带认证,更安全)
  2. 用AES密钥加密你的大文本
  3. 用RSA公钥加密AES密钥
  4. 将「加密后的AES密钥」+「AES加密后的文本」+「AES的IV/认证标签」打包发送给服务器
  5. 服务器端先用RSA私钥解密出AES密钥,再用AES密钥解密文本

Swift代码实现

1. 生成AES密钥和IV

func generateAESKey() throws -> Data {
    var key = Data(count: 32) // AES-256需要32字节密钥
    let result = key.withUnsafeMutableBytes { bytes in
        SecRandomCopyBytes(kSecRandomDefault, 32, bytes.baseAddress!)
    }
    guard result == errSecSuccess else {
        throw NSError(domain: "AESKeyError", code: Int(result), userInfo: nil)
    }
    return key
}

func generateIV() -> Data {
    var iv = Data(count: 12) // GCM模式推荐12字节IV
    iv.withUnsafeMutableBytes { bytes in
        SecRandomCopyBytes(kSecRandomDefault, 12, bytes.baseAddress!)
    }
    return iv
}

2. AES-GCM加密文本

func aesEncrypt(plainText: String, key: Data, iv: Data) throws -> (cipherData: Data, tag: Data) {
    let plainData = plainText.data(using: .utf8)!
    let tagLength = 16 // GCM认证标签长度,推荐16字节
    
    var cipherData = Data(count: plainData.count)
    var tag = Data(count: tagLength)
    
    let status = cipherData.withUnsafeMutableBytes { cipherBytes in
        tag.withUnsafeMutableBytes { tagBytes in
            plainData.withUnsafeBytes { plainBytes in
                iv.withUnsafeBytes { ivBytes in
                    key.withUnsafeBytes { keyBytes in
                        CCCrypt(
                            CCOperation(kCCEncrypt),
                            CCAlgorithm(kCCAlgorithmAES),
                            CCOptions(kCCModeGCM),
                            keyBytes.baseAddress, key.count,
                            ivBytes.baseAddress,
                            plainBytes.baseAddress, plainData.count,
                            cipherBytes.baseAddress, cipherData.count,
                            tagBytes.baseAddress, tagLength
                        )
                    }
                }
            }
        }
    }
    
    guard status == kCCSuccess else {
        throw NSError(domain: "AESEncryptError", code: Int(status), userInfo: nil)
    }
    
    return (cipherData, tag)
}

3. 完整的混合加密函数

func hybridEncrypt(plainText: String, publicKey: SecKey, algorithm: SecKeyAlgorithm = .rsaEncryptionOAEPSHA512) throws -> [String: String] {
    // 1. 生成AES密钥和IV
    let aesKey = try generateAESKey()
    let iv = generateIV()
    
    // 2. AES加密文本
    let (aesCipherData, tag) = try aesEncrypt(plainText: plainText, key: aesKey, iv: iv)
    
    // 3. RSA加密AES密钥
    var error: Unmanaged<CFError>?
    guard SecKeyIsAlgorithmSupported(publicKey, .encrypt, algorithm) else {
        fatalError("Algorithm not supported by public key")
    }
    
    guard let encryptedAESKeyData = SecKeyCreateEncryptedData(publicKey, algorithm, aesKey as CFData, &error) else {
        throw error!.takeRetainedValue() as Error
    }
    
    // 4. 转换为Base64字符串,方便传输
    let encryptedAESKey = (encryptedAESKeyData as Data).base64EncodedString()
    let encryptedText = aesCipherData.base64EncodedString()
    let ivBase64 = iv.base64EncodedString()
    let tagBase64 = tag.base64EncodedString()
    
    // 返回打包后的结果
    return [
        "encrypted_key": encryptedAESKey,
        "encrypted_text": encryptedText,
        "iv": ivBase64,
        "tag": tagBase64
    ]
}

三、服务器端处理逻辑(简要说明)

服务器需要:

  1. 用RSA私钥解密encrypted_key得到AES密钥
  2. 用AES密钥、iv、tag解密encrypted_text得到原始文本

内容的提问来源于stack exchange,提问作者Satyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 07:12:18