簡體   English   中英

如何在 macOS 上使用 Security.framework 解密數據?

[英]How to decrypt data with Security.framework on macOS?

我需要在macOS上使用 RSA public解密數據,通過谷歌搜索我知道我們可以使用Security.framework的方法SecKeyCreateDecryptedData來實現這一點,但這會導致兩個問題:

  1. SecKeyCreateDecryptedData接受private執行解密,但在我的情況下,數據在服務器端用私鑰加密,需要在客戶端用public解密。

  2. 我試圖從 RSA public字符串創建SecKey ,但失敗了。

我的代碼:

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的方法,我測試了所有的算法,都不支持:

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
    }

如果您的代碼僅適用於 Mac OS,您可以使用SecKeyCreateFromData方法而不是SecKeyCreateWithData方法來創建Seckey

這是示例代碼:

    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
    }

並且您應該使用ASCII編碼將RSA公鑰字符串轉換為數據。

let pubKey = try! getPublicKey(from: kPubKey.data(using: .ascii))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM