繁体   English   中英

在 Swift 中使用 RSA 证书加密

[英]Encrypt using RSA Certificate in Swift

我在操场上使用以下代码使用 RSA 加密字符串。 我需要使用证书本身进行加密,通过在旅途中提取密钥,而不是单独提取密钥然后加密。

import Foundation
import Security


struct RSA {

    static func encrypt(string: String, publicKey: String?) -> String? {
        guard let publicKey = publicKey else { return nil }

        let keyString = publicKey.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "").replacingOccurrences(of: "-----END CERTIFICATE-----", with: "").replacingOccurrences(of: "\r", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "").replacingOccurrences(of: " ", with: "")
        print(keyString)
        guard let data = Data(base64Encoded: keyString) else { return nil }
        print(data)
        var attributes: CFDictionary {
            return [kSecAttrKeyType : kSecAttrKeyTypeRSA,
                    kSecAttrKeyClass : kSecAttrKeyClassPublic,
                    kSecAttrKeySizeInBits : 2048,
                    kSecReturnPersistentRef : kCFBooleanTrue as Any] as CFDictionary
        }

        var error: Unmanaged<CFError>? = nil
        guard let secKey = SecKeyCreateWithData(data as CFData, attributes, &error) else {
            print(error.debugDescription)
            return nil
        }
        return encrypt(string: string, publicKey: secKey)
    }

    static func encrypt(string: String, publicKey: SecKey) -> String? {
        let buffer = [UInt8](string.utf8)

        var keySize = SecKeyGetBlockSize(publicKey)
        var keyBuffer = [UInt8](repeating: 0, count: keySize)

        // Encrypto should less than key length
        guard SecKeyEncrypt(publicKey, SecPadding.PKCS1, buffer, buffer.count, &keyBuffer, &keySize) == errSecSuccess else { return nil }
        return Data(bytes: keyBuffer, count: keySize).base64EncodedString()
    }
}


var pemString = "-----BEGIN CERTIFICATE-----##Base 64 encoded certificate string##-----END CERTIFICATE-----"


let password = "abcde"
let encryptedPassword = RSA.encrypt(string: password, publicKey: pemString)
print(encryptedPassword as Any)

但是它抛出以下异常:

可选(Swift.Unmanaged<__C.CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-50“从数据创建RSA公钥失败” UserInfo={NSDescription=从数据创建RSA公钥失败}))

如何正确地做同样的事情?

有问题的代码不会从证书中提取密钥。 相反,它尝试使用证书字符串本身创建SecKey 正确的做法是从证书数据创建一个SecCertificate对象,然后使用证书数据创建一个SecTrust 然后使用信任,复制公钥以制作SecKey对象。

最终代码将如下所示:

import Foundation
import Security


struct RSA {

    static func encrypt(string: String, certificate: String?) -> String? {
        guard let certificate = certificate else { return nil }

        let certificateString = certificate.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "").replacingOccurrences(of: "-----END CERTIFICATE-----", with: "").replacingOccurrences(of: "\r", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "").replacingOccurrences(of: " ", with: "")
        print(certificateString)

        // Convert the certificate string to Data
        guard let data = Data(base64Encoded: certificateString) else { return nil }
        print(data)

        // Create SecCertificate object using certificate data
        guard let cer = SecCertificateCreateWithData(nil, data as NSData) else { return nil }

        var trust: SecTrust?

        // Retrieve a SecTrust using the SecCertificate object. Provide X509 as policy
        let status = SecTrustCreateWithCertificates(cer, SecPolicyCreateBasicX509(), &trust)

        // Check if the trust generation is success
        guard status == errSecSuccess else { return nil }

        // Retrieve the SecKey using the trust hence generated
        guard let secKey = SecTrustCopyPublicKey(trust!) else { return nil }

        return encrypt(string: string, publicKey: secKey)
    }

    static func encrypt(string: String, publicKey: SecKey) -> String? {
        let buffer = [UInt8](string.utf8)

        var keySize = SecKeyGetBlockSize(publicKey)
        var keyBuffer = [UInt8](repeating: 0, count: keySize)

        // Encrypto should less than key length
        guard SecKeyEncrypt(publicKey, SecPadding.PKCS1, buffer, buffer.count, &keyBuffer, &keySize) == errSecSuccess else { return nil }
        return Data(bytes: keyBuffer, count: keySize).base64EncodedString()
    }
}


var pemString = "-----BEGIN CERTIFICATE-----##Base 64 encoded certificate string##-----END CERTIFICATE-----"


let password = "abcde"
let encryptedPassword = RSA.encrypt(string: password, certificate: pemString)
print(encryptedPassword as Any)

唯一的变化是static func encrypt(string: String, certificate: String?) -> String? 功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM