【问题标题】:Encrypt using RSA Certificate in Swift在 Swift 中使用 RSA 证书进行加密
【发布时间】:2020-04-02 09:00:14
【问题描述】:

我在操场上使用以下代码使用 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:错误 Domain=NSOSStatusErrorDomain Code=-50 "从 RSA 公钥创建 数据失败” UserInfo={NSDescription=从数据创建 RSA 公钥 失败}))

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

【问题讨论】:

    标签: ios swift encryption rsa x509certificate


    【解决方案1】:

    所提供的代码不会从证书中提取密钥。相反,它尝试使用证书字符串本身创建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?) -&gt; String? 函数。

    【讨论】:

    • 如果我们使用使用密码加密的私钥,这将如何改变?
    • 我想必须浏览文档才能找到合适的解决方案。如果您无法找到解决方案,请提出一个单独的问题。
    • 谢谢,我在这里发帖:stackoverflow.com/questions/61428695/…
    猜你喜欢
    • 1970-01-01
    • 2020-01-11
    • 1970-01-01
    • 2017-06-25
    • 2014-12-13
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多