美文网首页
swift-RSA(一)

swift-RSA(一)

作者: ksnowlv | 来源:发表于2018-07-17 19:12 被阅读490次

    如何使用swift进行RSA加解密呢?

    一.这四个方面:加载公钥/加载私钥/RSA加密/RSA解密
    • 1.加载公钥
        @objc public func publicKey(fileFullPath: NSString, block :@escaping YKRSASignBlock ) {
            
            if !FileManager.default.fileExists(atPath: fileFullPath as String){
                block(NSError.init(domain: "file not exist at the full path ", code: -1, userInfo: nil),nil)
            }
    
            let certificateData = NSData(contentsOfFile: fileFullPath as String);
            
            let myCertificate: SecCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)!
            let policy = SecPolicyCreateBasicX509()
            var trust: SecTrust?
            var status: OSStatus = SecTrustCreateWithCertificates(myCertificate, policy, &trust)
            
            if status == noErr {
                var trustResult:SecTrustResultType = SecTrustResultType(rawValue: 0)!
                status = SecTrustEvaluate(trust!, &trustResult)
                let secKey =  SecTrustCopyPublicKey(trust!)
                self.publicSecKey = secKey
                block(nil, secKey)
            }else{
                
                block(NSError(domain: "load error", code: Int(status), userInfo: nil), nil)
            }
        }
    
    • 2.加载私钥
        @objc public func privateKey(fileFullPath: NSString, password: NSString, block :@escaping YKRSASignBlock ) {
            
            if !FileManager.default.fileExists(atPath: fileFullPath as String){
                block(NSError.init(domain: "file not exist at the full path ", code: -1, userInfo: nil),nil)
            }
            
            let p12Data = NSData(contentsOfFile: fileFullPath as String);
            
            guard p12Data != nil else {
                return
            }
            
            let options = [kSecImportExportPassphrase: password]  as [String : Any]
            var items : CFArray?
            var status: OSStatus = SecPKCS12Import(p12Data!, options as CFDictionary, &items)
            var privateKey:SecKey?
            
            if status == noErr {
                
                let resArray:Array = (items as Array?)!
                let identityDict: Dictionary = resArray.first as! Dictionary<String, AnyObject>
                let identity = identityDict[ kSecImportItemIdentity as String]
    //            let identityDict = CFArrayGetValueAtIndex(items, 0)
    //            let secImportItemIdentity = unsafeBitCast(kSecImportItemIdentity, to: UnsafeRawPointer.self)
    //            let identityApp:SecIdentity = CFDictionaryGetValue(identityDict.unsafelyUnwrapped as! CFDictionary, secImportItemIdentity) as! SecIdentity
                status = SecIdentityCopyPrivateKey(identity as! SecIdentity, &privateKey)
                if status == noErr {
                    self.privateSecKey = privateKey
                     block(nil, self.privateSecKey)
                    return
                }
            }
            block(NSError(domain: "load error", code: Int(status), userInfo: nil), nil)
        }
    
    • 3.使用RSA加密
    @objc public func encrypt(source: NSString) -> NSString? {
            
            guard source.length > 0 && self.publicSecKey != nil else {
                return ""
            }
            
            let data: NSData = (source.data(using: String.Encoding.utf8.rawValue)! as NSData)
            var resData:NSData? = nil
            
    //        if #available(iOS 10.0, *) {
    //            var error: Unmanaged<CFError>?
    //            resData =  SecKeyCreateEncryptedData(self.publicSecKey!, SecKeyAlgorithm.rsaEncryptionPKCS1, data as CFData, &error)
    //
    //            print("res = \(String(describing: error?.takeUnretainedValue().localizedDescription))")
    //        } else
            //{
                // Fallback on earlier versions
                
            let blockLen =  SecKeyGetBlockSize(self.publicSecKey!)
            var outBuf = [UInt8](repeating: 0, count: blockLen)
            var outBufLen:Int = blockLen
            
            let status: OSStatus = SecKeyEncrypt(self.publicSecKey!, SecPadding.PKCS1, data.bytes.assumingMemoryBound(to: UInt8.self), data.length, &outBuf, &outBufLen)
                
            if status == noErr {
                resData = NSData(bytes: outBuf, length: outBufLen)
            }
    
            if resData != nil {
                
                let resString = resData!.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: NSData.Base64EncodingOptions.lineLength64Characters.rawValue))
    
                return resString as NSString
            }
            
            return nil
        }
    
    
    • 4.使用RSA解密
        @objc public func decrypt(source: NSString) -> NSString? {
            
            guard source.length > 0 && self.privateSecKey != nil else {
                return ""
            }
            
            let data: Data = (NSData(base64Encoded: (source as String), options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)! as Data)
            
            
            let blockLen =  SecKeyGetBlockSize(self.privateSecKey!)
            
            let outBuf = UnsafeMutablePointer<UInt8>.allocate(capacity: blockLen)
            
            defer {
                outBuf.deallocate()
            }
            
            var outLen: Int = blockLen
            var status: OSStatus = noErr
            
            var resData:NSData? = nil
            
    //        if #available(iOS 10.0, *) {
    //            var error: Unmanaged<CFError>?
    //            resData =  SecKeyCreateDecryptedData(self.privateSecKey!, SecKeyAlgorithm.rsaEncryptionPKCS1, data as CFData, &error)
    //
    //            print("res = \(String(describing: error?.takeUnretainedValue().localizedDescription))")
    //        } else {
    //            // Fallback on earlier versions
    //            //let status = SecKeyEncrypt(seckey, SecPadding.PKCS1, chunkData, chunkData.count, outBuf, &encryptedDataLength)
    //
    //        }
            
            data.withUnsafeBytes { (bytes:UnsafePointer<UInt8>) -> Void in
                status = SecKeyDecrypt(self.privateSecKey!, SecPadding.PKCS1, bytes, data.count, outBuf, &outLen)
                
                print("status = \(status)")
            }
            
            if status == noErr {
                resData = NSData(bytes: outBuf, length: outLen)
            }
            
            if resData != nil  {
                return String(data: (resData! as Data), encoding: String.Encoding.utf8) as NSString?
            }
            
            return nil
        }
        
    

    二.问题。

    • 1.返回的为什么是NSString?混编
    • 2.为什么不支持超过128字节数据加解密?别急,见下一篇
    • 3.为什么不使用新版的RSA加解密?新版的只支持iOS10以上

    相关文章

      网友评论

          本文标题:swift-RSA(一)

          本文链接:https://www.haomeiwen.com/subject/nrbgpftx.html