iOS 開發之路(AES/DES加密實現) 三


  最近接觸的這個項目由於以前服務器上用的是DES/CBC/PKCS5Padding加密方式,為了讓在iOS上的加密結果與服務器端保持一致,我做了很多嘗試,現在分享給大家。PS:現在不推薦用DES了,只是服務器端不能隨便改,別的項目平台有依賴。

  首先是在Swift中,建一個bridge-Header文件用來調用OC的方法,這一步還是蠻簡單的。

  貼上我的實現代碼:

  

class CrypTools: NSObject {
    internal func cryptoOperation() -> String {
        // Validation checks.
        let jm = "fjdkasljfkls"
        let jmData = jm.data(using: String.Encoding.utf8)!
        let key = "\n\u{0014}\u{001E}(2<FP" //這里是java端對應的key byte[]的字符串表現形式 btye[] key = {10, 20, 30, 40, 50, 60 ,70, 80}
        var t:String = ""
        
        // Prepare data parameters
        let keyData: Data! = key.data(using: String.Encoding.utf8, allowLossyConversion: false)!
        let keyBytes = keyData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }
        
        //let keyBytes         = keyData.bytes.bindMemory(to: Void.self, capacity: keyData.count)
        let dataLength       = Int(jmData.count)
        let dataBytes        = jmData.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        }

        
        var bufferData       = Data(count: Int(dataLength) + 8)
        let bufferPointer    = bufferData.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> UnsafeMutablePointer<UInt8> in
            return bytes
        }
        let bufferLength     = size_t(bufferData.count)
        let ivStr = "\u{000B}\u{0016}!,7BMU" //這里是java端對應的iv變量字符串
        let iv = ivStr.data(using: String.Encoding.utf8)!
        let ivBuffer: UnsafePointer<UInt8>? = iv.withUnsafeBytes({ (bytes: UnsafePointer<UInt8>) -> UnsafePointer<UInt8> in
            return bytes
        })
        var bytesDecrypted   = Int(0)
        // Perform operation
        let cryptStatus = CCCrypt(
            0,                  // Operation 這里代表DES加密而非解密
            1,    // Algorithm 這里代表DES算法(其他數字可以是別的算法,如AES),研究一下OC的自帶的方法就行了
            1,                    // Options 這里代表PKCS7Padding
            keyBytes,                   // key data
            8,                  // key length 
            ivBuffer,                   // IV buffer
            dataBytes,                  // input data
            dataLength,                 // input length
            bufferPointer,              // output buffer
            bufferLength,               // output buffer length
            &bytesDecrypted)            // output bytes decrypted real length
        if Int32(cryptStatus) == Int32(kCCSuccess) {
            bufferData.count = bytesDecrypted // Adjust buffer size to real bytes
            print(bufferData)
            let a = bufferData.withUnsafeBytes{
                [UInt8](UnsafeBufferPointer(start: $0, count: bufferData.count))
            }
            print(a)
            t = bufferData.base64EncodedString()
        }
        return t
    }

}

  可以看到cryptStatus下對應的幾個參數我都做了注釋,其中option那一欄1對應PKCS7Padding,實測這和服務器端的PKCS7Padding填充沒有任何區別,之前沒有得出一致的加密結果時我一直以為是這個填充參數的問題,但實際上是iv和key的設置問題(這是重點)

  在java端iv和key多半以byte[] = {}來表示,我們要做的就是將這個byte[]轉換成字符串,最后再將這個字符串放在iOS代碼中(字符串可能要用Unicode編碼表示)。

  其實在Swift下,第三方庫CryptoSwift非常好用,大家可以上GitHub上檢索研究一下。只不過不支持老舊的DES加密,這里只是針對有DES加密需求的人給出解決方案。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM