王大师 發表於 2024-7-17 12:10:00

iOS开发基础109-网络安全

<p>在iOS开发中,保障应用的网络安全是一个非常重要的环节。以下是一些常见的网络安全措施及对应的示例代码:</p>
<h2 id="swift版">Swift版</h2>
<h3 id="1-使用https">1. 使用HTTPS</h3>
<p>确保所有的网络请求使用HTTPS协议,以加密数据传输,防止中间人攻击。</p>
<h4 id="示例代码">示例代码:</h4>
<p>在Info.plist中配置App Transport Security (ATS):</p>
<pre><code class="language-xml">&lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
&lt;dict&gt;
    &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt;
    &lt;false/&gt;
&lt;/dict&gt;
</code></pre>
<h3 id="2-ssl-pinning">2. SSL Pinning</h3>
<p>通过SSL Pinning可以确保应用程序只信任指定的服务器证书,防止被劫持到伪造的服务器。</p>
<h4 id="示例代码-1">示例代码:</h4>
<pre><code class="language-swift">import Foundation

class URLSessionPinningDelegate: NSObject, URLSessionDelegate {
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -&gt; Void) {
      if let serverTrust = challenge.protectionSpace.serverTrust,
         SecTrustEvaluate(serverTrust, nil) == errSecSuccess,
         let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0) {

            let localCertificateData = try? Data(contentsOf: Bundle.main.url(forResource: "your_cert", withExtension: "cer")!)
            let serverCertificateData = SecCertificateCopyData(serverCertificate) as Data

            if localCertificateData == serverCertificateData {
                let credential = URLCredential(trust: serverTrust)
                completionHandler(.useCredential, credential)
                return
            }
      }
      completionHandler(.cancelAuthenticationChallenge, nil)
}
}

// Usage
let url = URL(string: "https://yoursecurewebsite.com")!
let session = URLSession(configuration: .default, delegate: URLSessionPinningDelegate(), delegateQueue: nil)
let task = session.dataTask(with: url) { data, response, error in
    // Handle response
}
task.resume()
</code></pre>
<h3 id="3-防止sql注入">3. 防止SQL注入</h3>
<p>在处理用户输入时,使用参数化查询来防止SQL注入攻击。</p>
<h4 id="示例代码-2">示例代码:</h4>
<pre><code class="language-swift">import SQLite3

func queryDatabase(userInput: String) {
    var db: OpaquePointer?
    // Open database (assuming dbPath is the path to your database)
    sqlite3_open(dbPath, &amp;db)

    var queryStatement: OpaquePointer?
    let query = "SELECT * FROM users WHERE username = ?"
   
    if sqlite3_prepare_v2(db, query, -1, &amp;queryStatement, nil) == SQLITE_OK {
      sqlite3_bind_text(queryStatement, 1, userInput, -1, nil)
      
      while sqlite3_step(queryStatement) == SQLITE_ROW {
            // Process results
      }
    }
   
    sqlite3_finalize(queryStatement)
    sqlite3_close(db)
}
</code></pre>
<h3 id="4-data-encryption">4. Data Encryption</h3>
<p>在存储敏感数据时,使用iOS的加密库来加密数据,比如使用<code>Keychain</code>。</p>
<h4 id="示例代码-3">示例代码:</h4>
<pre><code class="language-swift">import Security

func saveToKeychain(key: String, data: Data) -&gt; OSStatus {
    let query: = [
      kSecClass as String: kSecClassGenericPassword,
      kSecAttrAccount as String: key,
      kSecValueData as String: data
    ]

    SecItemDelete(query as CFDictionary) // Delete any existing item
    return SecItemAdd(query as CFDictionary, nil) // Add new item
}

func loadFromKeychain(key: String) -&gt; Data? {
    let query: = [
      kSecClass as String: kSecClassGenericPassword,
      kSecAttrAccount as String: key,
      kSecReturnData as String: kCFBooleanTrue!,
      kSecMatchLimit as String: kSecMatchLimitOne
    ]

    var dataTypeRef: AnyObject?
    let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &amp;dataTypeRef)

    if status == noErr {
      return dataTypeRef as? Data
    } else {
      return nil
    }
}
</code></pre>
<h3 id="5-输入验证与清理">5. 输入验证与清理</h3>
<p>对用户输入进行验证和清理,防止XSS(跨站脚本攻击)和其他注入攻击。</p>
<h4 id="示例代码-4">示例代码:</h4>
<pre><code class="language-swift">func sanitize(userInput: String) -&gt; String {
    // Remove any script tags or other potentially dangerous content
    return userInput.replacingOccurrences(of: "&lt;script&gt;", with: "", options: .caseInsensitive)
                  .replacingOccurrences(of: "&lt;/script&gt;", with: "", options: .caseInsensitive)
}

// Usage
let userInput = "&lt;script&gt;alert('xss')&lt;/script&gt;"
let sanitizedInput = sanitize(userInput: userInput)
print(sanitizedInput) // Outputs: alert('xss')
</code></pre>
<h2 id="oc版">OC版</h2>
<h3 id="1-使用https-1">1. 使用HTTPS</h3>
<p>确保所有的网络请求都使用HTTPS协议,以加密数据传输,防止中间人攻击。</p>
<h4 id="示例代码-5">示例代码:</h4>
<p>在<code>Info.plist</code>中配置App Transport Security (ATS):</p>
<pre><code class="language-xml">&lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
&lt;dict&gt;
    &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt;
    &lt;false/&gt;
&lt;/dict&gt;
</code></pre>
<h3 id="2-ssl-pinning-1">2. SSL Pinning</h3>
<p>通过SSL Pinning可以确保应用程序只信任指定的服务器证书,防止被劫持到伪造的服务器。</p>
<h4 id="示例代码-6">示例代码:</h4>
<pre><code class="language-objective-c">#import &lt;Foundation/Foundation.h&gt;

@interface URLSessionPinningDelegate : NSObject &lt;NSURLSessionDelegate&gt;

@end

@implementation URLSessionPinningDelegate

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler {
    if () {
      SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
      SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
      
      NSString *certPath = [ pathForResource:@"your_cert" ofType:@"cer"];
      NSData *localCertData = ;
      NSData *serverCertData = (__bridge NSData *)(SecCertificateCopyData(serverCertificate));
      
      if () {
            NSURLCredential *credential = ;
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
            return;
      }
    }
    completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}

@end

// Usage
NSURL *url = ;
NSURLSessionConfiguration *sessionConfig = ;
URLSessionPinningDelegate *pinningDelegate = [ init];
NSURLSession *session = ;

NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error == nil) {
      // Handle response
    }
}];
;
</code></pre>
<h3 id="3-防止sql注入-1">3. 防止SQL注入</h3>
<p>在处理用户输入时,使用参数化查询来防止SQL注入攻击。</p>
<h4 id="示例代码-7">示例代码:</h4>
<pre><code class="language-objective-c">#import &lt;sqlite3.h&gt;

- (void)queryDatabase:(NSString *)userInput {
    sqlite3 *db;
    // Open database (assuming dbPath is the path to your database)
    if (sqlite3_open(, &amp;db) == SQLITE_OK) {
      sqlite3_stmt *statement;
      const char *query = "SELECT * FROM users WHERE username = ?";
      
      if (sqlite3_prepare_v2(db, query, -1, &amp;statement, NULL) == SQLITE_OK) {
            sqlite3_bind_text(statement, 1, , -1, SQLITE_TRANSIENT);
            
            while (sqlite3_step(statement) == SQLITE_ROW) {
                // Process results
            }
      }
      
      sqlite3_finalize(statement);
      sqlite3_close(db);
    }
}
</code></pre>
<h3 id="4-data-encryption-1">4. Data Encryption</h3>
<p>在存储敏感数据时,使用iOS的加密库来加密数据,比如使用<code>Keychain</code>。</p>
<h4 id="示例代码-8">示例代码:</h4>
<pre><code class="language-objective-c">#import &lt;Security/Security.h&gt;

- (OSStatus)saveToKeychainWithKey:(NSString *)key data:(NSData *)data {
    NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrAccount: key,
                            (__bridge id)kSecValueData: data};
   
    SecItemDelete((__bridge CFDictionaryRef)query); // Delete any existing item
    return SecItemAdd((__bridge CFDictionaryRef)query, NULL); // Add new item
}

- (NSData *)loadFromKeychainWithKey:(NSString *)key {
    NSDictionary *query = @{(__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrAccount: key,
                            (__bridge id)kSecReturnData: (__bridge id)kCFBooleanTrue,
                            (__bridge id)kSecMatchLimit: (__bridge id)kSecMatchLimitOne};
   
    CFTypeRef dataTypeRef = NULL;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &amp;dataTypeRef);
   
    if (status == noErr) {
      return (__bridge_transfer NSData *)dataTypeRef;
    } else {
      return nil;
    }
}
</code></pre>
<h3 id="5-输入验证与清理-1">5. 输入验证与清理</h3>
<p>对用户输入进行验证和清理,防止XSS(跨站脚本攻击)和其他注入攻击。</p>
<h4 id="示例代码-9">示例代码:</h4>
<pre><code class="language-objective-c">- (NSString *)sanitize:(NSString *)userInput {
    // Remove any script tags or other potentially dangerous content
    NSString *sanitizedInput = ;
    sanitizedInput = ;
    return sanitizedInput;
}

// Usage
NSString *userInput = @"&lt;script&gt;alert('xss')&lt;/script&gt;";
NSString *sanitizedInput = ;
NSLog(@"%@", sanitizedInput); // Outputs: alert('xss')
</code></pre>
<p>通过这些措施,你可以显著提升iOS应用的网络安全性。根据项目需求,灵活运用这些技术以确保用户数据的安全。</p>


</div>
<div id="MySignature" role="contentinfo">
    将来的你会感谢今天如此努力的你!
版权声明:本文为博主原创文章,未经博主允许不得转载。<br><br>
来源:https://www.cnblogs.com/chglog/p/18307042
頁: [1]
查看完整版本: iOS开发基础109-网络安全