在Swift中使用RSA证书进行加密 [英] Encrypt using RSA Certificate in Swift

查看:150
本文介绍了在Swift中使用RSA证书进行加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I used the following code in a playground to Encrypt a string using RSA. I need the encryption to happen using certificate itself, by extracting the key on the go, rather than the key getting extracted separately and then encrypting.

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)

但是它会引发以下异常:

However it is throwing the following exception:

可选的(Swift.Unmanaged< __ C.CFErrorRef>(_ value:错误Domain = NSOSStatusErrorDomain Code = -50"RSA公钥创建自数据失败" UserInfo = {NSDescription =从数据创建RSA公钥失败}))

Optional(Swift.Unmanaged<__C.CFErrorRef>(_value: Error Domain=NSOSStatusErrorDomain Code=-50 "RSA public key creation from data failed" UserInfo={NSDescription=RSA public key creation from data failed}))

如何正确执行相同的操作?

How to do the same properly?

推荐答案

所提供的代码不会从证书中提取密钥.而是尝试使用证书字符串本身创建 SecKey .正确的方法是从证书数据创建 SecCertificate 对象,然后使用证书数据创建 SecTrust .然后使用信任关系,复制公钥以创建 SecKey 对象.

The code provided in question doesn't extract the Key from certificate. Rather, it tries to create the SecKey using the certificate string itself. The correct way to do the same is to create a SecCertificate object from the certificate data, then create a SecTrust using the certificate data. Then using the trust, copy the public key to make SecKey object.

最终代码如下:

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)

唯一的变化是在静态函数crypto(字符串:字符串,证书:字符串?)->字符串?函数.

这篇关于在Swift中使用RSA证书进行加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆