首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Security.framework上在macOS上解密数据?

如何在Security.framework上在macOS上解密数据?
EN

Stack Overflow用户
提问于 2021-01-15 07:17:21
回答 1查看 771关注 0票数 2

我需要在public上使用macOS密钥解密数据,通过谷歌我知道我们可以使用方法SecKeyCreateDecryptedData of Security.framework来实现这一点,但这会导致两个问题:

  1. SecKeyCreateDecryptedData接受private密钥来执行解密,但在我的情况下,数据在服务器端用私钥加密,需要在客户端用public密钥解密。

  1. I试图从RSA public密钥字符串创建SecKey,但失败了。

我的代码:

代码语言:javascript
复制
import Foundation
 
func getPublicKey(from data: Data) throws -> SecKey {
    var error: Unmanaged<CFError>? = nil
    let publicKeyMaybe = SecKeyCreateWithData(
        data as NSData,
        [
            kSecAttrKeyType: kSecAttrKeyTypeRSA,
            kSecAttrKeyClass: kSecAttrKeyClassPublic
        ] as NSDictionary,
        &error)
    guard let publicKey = publicKeyMaybe else {
        throw error!.takeRetainedValue() as Error
    }
    return publicKey
}

func decrypt(key: SecKey, data cipherTextData: Data) -> Data? {
    let algorithm: SecKeyAlgorithm = .eciesEncryptionCofactorVariableIVX963SHA256AESGCM
    guard SecKeyIsAlgorithmSupported(key, .decrypt, algorithm) else {
        print("Can't decrypt. Algorithm not supported.")
        return nil
    }

    var error: Unmanaged<CFError>? = nil
    let clearTextData = SecKeyCreateDecryptedData(key,
                                                  algorithm,
                                                  cipherTextData as CFData,
                                                  &error) as Data?
    if let error = error {
        print("Can't decrypt. %@", (error.takeRetainedValue() as Error).localizedDescription)
        return nil
    }
    guard clearTextData != nil else {
        print("Can't decrypt. No resulting cleartextData.")
        return nil
    }
    print("Decrypted data.")
    return clearTextData
}

func testDecrypt() {
    let rawString = "0ed3a2c57f5dEJgqXT9760269b8cc5cd76f3afcf"
    let decodedData = Data.init(base64Encoded: rawString, options: [])!

    let pubKey = try! getPublicKey(from: kPubKey.data(using: .utf8)!) // Error: RSA public key creation from data failed
    let decryptedData = decrypt(key: pubKey, data: decodedData)!
    let decrypted = String.init(data: decryptedData, encoding: .utf8)!

    print(">>>>>>> decrypted string: \(decrypted)")
}

testDecrypt()

使用Kazunori Takaishi方法,我测试了所有算法,它们都不受支持:

代码语言:javascript
复制
func decrypt(key: SecKey, data cipherTextData: Data) -> Data? {
        let algorithms: [SecKeyAlgorithm] = [
            .rsaSignatureRaw,
            .rsaSignatureDigestPKCS1v15Raw,
            .rsaSignatureDigestPKCS1v15SHA1,
            .rsaSignatureDigestPKCS1v15SHA224,
            .rsaSignatureDigestPKCS1v15SHA256,
            .rsaSignatureDigestPKCS1v15SHA384,
            .rsaSignatureDigestPKCS1v15SHA512,
            .rsaSignatureMessagePKCS1v15SHA1,
            .rsaSignatureMessagePKCS1v15SHA224,
            .rsaSignatureMessagePKCS1v15SHA256,
            .rsaSignatureMessagePKCS1v15SHA384,
            .rsaSignatureMessagePKCS1v15SHA512,
            .rsaSignatureDigestPSSSHA1,
            .rsaSignatureDigestPSSSHA224,
            .rsaSignatureDigestPSSSHA256,
            .rsaSignatureDigestPSSSHA384,
            .rsaSignatureDigestPSSSHA512,
            .rsaSignatureMessagePSSSHA1,
            .rsaSignatureMessagePSSSHA224,
            .rsaSignatureMessagePSSSHA256,
            .rsaSignatureMessagePSSSHA384,
            .rsaSignatureMessagePSSSHA512,
            .ecdsaSignatureRFC4754,
            .ecdsaSignatureDigestX962,
            .ecdsaSignatureDigestX962SHA1,
            .ecdsaSignatureDigestX962SHA224,
            .ecdsaSignatureDigestX962SHA256,
            .ecdsaSignatureDigestX962SHA384,
            .ecdsaSignatureDigestX962SHA512,
            .ecdsaSignatureMessageX962SHA1,
            .ecdsaSignatureMessageX962SHA224,
            .ecdsaSignatureMessageX962SHA256,
            .ecdsaSignatureMessageX962SHA384,
            .ecdsaSignatureMessageX962SHA512,
            .rsaEncryptionRaw,
            .rsaEncryptionPKCS1,
            .rsaEncryptionOAEPSHA1,
            .rsaEncryptionOAEPSHA224,
            .rsaEncryptionOAEPSHA256,
            .rsaEncryptionOAEPSHA384,
            .rsaEncryptionOAEPSHA512,
            .rsaEncryptionOAEPSHA1AESGCM,
            .rsaEncryptionOAEPSHA224AESGCM,
            .rsaEncryptionOAEPSHA256AESGCM,
            .rsaEncryptionOAEPSHA384AESGCM,
            .rsaEncryptionOAEPSHA512AESGCM,
            .eciesEncryptionStandardX963SHA1AESGCM,
            .eciesEncryptionStandardX963SHA224AESGCM,
            .eciesEncryptionStandardX963SHA256AESGCM,
            .eciesEncryptionStandardX963SHA384AESGCM,
            .eciesEncryptionStandardX963SHA512AESGCM,
            .eciesEncryptionCofactorX963SHA1AESGCM,
            .eciesEncryptionCofactorX963SHA224AESGCM,
            .eciesEncryptionCofactorX963SHA256AESGCM,
            .eciesEncryptionCofactorX963SHA384AESGCM,
            .eciesEncryptionCofactorX963SHA512AESGCM,
            .eciesEncryptionStandardVariableIVX963SHA224AESGCM,
            .eciesEncryptionStandardVariableIVX963SHA256AESGCM,
            .eciesEncryptionStandardVariableIVX963SHA384AESGCM,
            .eciesEncryptionStandardVariableIVX963SHA512AESGCM,
            .eciesEncryptionCofactorVariableIVX963SHA224AESGCM,
            .eciesEncryptionCofactorVariableIVX963SHA256AESGCM,
            .eciesEncryptionCofactorVariableIVX963SHA384AESGCM,
            .eciesEncryptionCofactorVariableIVX963SHA512AESGCM,
            .ecdhKeyExchangeStandard,
            .ecdhKeyExchangeStandardX963SHA1,
            .ecdhKeyExchangeStandardX963SHA224,
            .ecdhKeyExchangeStandardX963SHA256,
            .ecdhKeyExchangeStandardX963SHA384,
            .ecdhKeyExchangeStandardX963SHA512,
            .ecdhKeyExchangeCofactor,
            .ecdhKeyExchangeCofactorX963SHA1,
            .ecdhKeyExchangeCofactorX963SHA224,
            .ecdhKeyExchangeCofactorX963SHA256,
            .ecdhKeyExchangeCofactorX963SHA384,
            .ecdhKeyExchangeCofactorX963SHA512
        ]
        
        for a in algorithms {
            if SecKeyIsAlgorithmSupported(key, .decrypt, a) {
                print(">>>>>>>>>>>>> supported algorithm: \(a)")
            }
        }
        
        //==================
        
        let algorithm: SecKeyAlgorithm = .rsaEncryptionPKCS1 // .rsaSignatureMessagePKCS1v15SHA256 // .rsaSignatureDigestPKCS1v15SHA1 // .rsaSignatureDigestPKCS1v15Raw // .rsaSignatureDigestPKCS1v15SHA256 //.rsaEncryptionPKCS1
        
//        guard SecKeyIsAlgorithmSupported(key, .decrypt, algorithm) else {
//            print("Can't decrypt. Algorithm not supported.")
//            return nil
//        }

        var error: Unmanaged<CFError>? = nil
        let clearTextData = SecKeyCreateDecryptedData(key,
                                                      algorithm,
                                                      cipherTextData as CFData,
                                                      &error) as Data?
        if let error = error {
            print("Can't decrypt. \((error.takeRetainedValue() as Error).localizedDescription)")
            return nil
        }
        guard clearTextData != nil else {
            print("Can't decrypt. No resulting cleartextData.")
            return nil
        }
        print("Decrypted data.")
        return clearTextData
    }
EN

回答 1

Stack Overflow用户

发布于 2021-01-24 19:51:59

如果您的代码仅在Mac上工作,则可以使用Seckey方法而不是SecKeyCreateWithData方法来创建SecKeyCreateWithData

这是示例代码:

代码语言:javascript
复制
    func getPublicKey(from data: Data?) throws -> SecKey {
        var error: Unmanaged<CFError>? = nil
        guard let data = data else { throw error!.takeRetainedValue() as Error }
        let publicKeyMaybe = SecKeyCreateFromData([:] as CFDictionary, data as NSData, &error)
        guard let publicKey = publicKeyMaybe else {
            throw error!.takeRetainedValue() as Error
        }
        return publicKey
    }

您应该使用RSA编码将ASCII公钥字符串转换为数据。

代码语言:javascript
复制
let pubKey = try! getPublicKey(from: kPubKey.data(using: .ascii))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65731921

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档