CommonCrypto 生成长度为 16 个字符的加密字符串

CommonCrypto to generate encrypted string with 16 char length

这是我第一次尝试使用加密,所以我不确定我需要的是否可以通过以下代码实现。

我的问题 - 我需要它来生成一个包含 16 个字符的编码字符串,而不是目前正在生成的 64 个字符。

我更喜欢使用本地 swift 库而不是外部框架。因此,找不到太多关于如何使用 CommonCrypto 的信息。也不确定这是否是正确的方法。

我在哪里得到的例子

http://sketchytech.blogspot.co.nz/2016/02/resurrecting-commoncrypto-in-swift-for.html

我的用法

let keyString = "1234567812345678"
    let message = "12345678123456781234567812345678"
    let iv = "iv-salt-string--" // string of 16 characters in length

    let encoded = message.aesEncrypt(keyString, iv: iv)!
    print("encoded -> \(encoded)")

    let unencode = encoded.aesDecrypt(keyString, iv: iv)!
    print("unencode -> \(unencode)")

输出

encoded -> S81qV6F31xO8mUA1+HhsF7pHOMeE0f6Bbcmj3Zzk3EFLhQTCmfYlouorrUkYKL6K
unencode -> 12345678123456781234567812345678

分机

extension String {

    func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
            data = self.dataUsingEncoding(NSUTF8StringEncoding),
            cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {


                let keyLength              = size_t(kCCKeySizeAES128)
                let operation: CCOperation = UInt32(kCCEncrypt)
                let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
                let options:   CCOptions   = UInt32(options)



                var numBytesEncrypted :size_t = 0

                let cryptStatus = CCCrypt(operation,
                    algoritm,
                    options,
                    keyData.bytes, keyLength,
                    iv,
                    data.bytes, data.length,
                    cryptData.mutableBytes, cryptData.length,
                    &numBytesEncrypted)

                if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                    cryptData.length = Int(numBytesEncrypted)
                    let base64cryptString = cryptData.base64EncodedStringWithOptions(.Encoding64CharacterLineLength)
                    return base64cryptString


                }
                else {
                    return nil
                }
        }
        return nil
    }

    func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
        if let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
            data = NSData(base64EncodedString: self, options: .IgnoreUnknownCharacters),
            cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

                let keyLength              = size_t(kCCKeySizeAES128)
                let operation: CCOperation = UInt32(kCCDecrypt)
                let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
                let options:   CCOptions   = UInt32(options)

                var numBytesEncrypted :size_t = 0

                let cryptStatus = CCCrypt(operation,
                    algoritm,
                    options,
                    keyData.bytes, keyLength,
                    iv,
                    data.bytes, data.length,
                    cryptData.mutableBytes, cryptData.length,
                    &numBytesEncrypted)

                if UInt32(cryptStatus) == UInt32(kCCSuccess) {
                    cryptData.length = Int(numBytesEncrypted)
                    let unencryptedMessage = String(data: cryptData, encoding:NSUTF8StringEncoding)
                    return unencryptedMessage
                }
                else {
                    return nil
                }
        }
        return nil
    }
}

从十六进制转换为数据后,您有 16 个字节的输入。您指定 PKCS#7 填充 kCCOptionPKCS7Padding。如果数据是块大小的精确倍数,PKCS#7 填充必须将整个填充块添加到要加密的数据中,从而形成 32 字节的数据。 (这是因为必须始终添加一些填充,如果没有部分块,唯一的方法是添加一个填充块。)解密时,将删除 16 字节的填充,因此您将取回 16 字节的数据.

参见:PKCS#7 padding

如果输入数据总是块大小(16 字节)的倍数,那么您不需要添加填充,因此您不需要提供 kCCOptionPKCS7Padding作为一个选项。

extension String {

func aesEncrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = key.data(using: String.Encoding.utf8),
        let data = self.data(using: String.Encoding.utf8),
        let cryptData    = NSMutableData(length: Int((data.count)) + kCCBlockSizeAES128) {


        let keyLength              = size_t(kCCKeySizeAES128)
        let operation: CCOperation = UInt32(kCCEncrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(options)



        var numBytesEncrypted :size_t = 0

        let cryptStatus = CCCrypt(operation,
                                  algoritm,
                                  options,
                                  (keyData as NSData).bytes, keyLength,
                                  iv,
                                  (data as NSData).bytes, data.count,
                                  cryptData.mutableBytes, cryptData.length,
                                  &numBytesEncrypted)

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            let base64cryptString = cryptData.base64EncodedString(options: .lineLength64Characters)
            return base64cryptString


        }
        else {
            return nil
        }
    }
    return nil
}

func aesDecrypt(key:String, iv:String, options:Int = kCCOptionPKCS7Padding) -> String? {
    if let keyData = key.data(using: String.Encoding.utf8),
        let data = NSData(base64Encoded: self, options: .ignoreUnknownCharacters),
        let cryptData    = NSMutableData(length: Int((data.length)) + kCCBlockSizeAES128) {

        let keyLength              = size_t(kCCKeySizeAES128)
        let operation: CCOperation = UInt32(kCCDecrypt)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithmAES128)
        let options:   CCOptions   = UInt32(options)

        var numBytesEncrypted :size_t = 0

        let cryptStatus = CCCrypt(operation,
                                  algoritm,
                                  options,
                                  (keyData as NSData).bytes, keyLength,
                                  iv,
                                  data.bytes, data.length,
                                  cryptData.mutableBytes, cryptData.length,
                                  &numBytesEncrypted)

        if UInt32(cryptStatus) == UInt32(kCCSuccess) {
            cryptData.length = Int(numBytesEncrypted)
            let unencryptedMessage = String(data: cryptData as Data, encoding:String.Encoding.utf8)
            return unencryptedMessage
        }
        else {
            return nil
        }
    }
    return nil
}


  }

这是16位长度吗