在这一节里,我们介绍一个叫做 CryptoSwift 的开源项目。它几乎支持所有常用的密码学算法,因此,除了使用之外,如果你了解算法的原理,这个项目也是一个不错的算法实现资料。
AES 加密和解密
不过,之前我们已经详细介绍过 AES 的执行过程了,这里,就主要来看下如何完成泊学 App 中将要使用的 AES-256-CBC 算法。至于其它的,大家理解了这个过程之后,自己按照官方文档来用就完全没问题了。
简单来说,在 CryptoSwift 里,AES 算法使用的 key / iv,以及要加密的内容,都是通过字节数组表示的,写成 Swift,就是 Array<UInt8>
。至于使用的具体是 AES-128,AES-192 还是 AES-256 算法,则是通过 key 的长度自动识别的。因此,我们需要自己确保使用的 key / iv 以及要加密的数据的长度是符合 AES 算法要求的,否则 CryptoSwift 会发生异常。
创建 key
为了定义一个 AES-256-CBC 使用的 key,我们可以定义一个 32 字节的 Array<UInt8>
:
let key = { () -> [UInt8] in
var tmp: [UInt8] = []
for i in 1...32 { tmp.append(UInt8(i)) }
return tmp
}()
当然,数组的内容应该是随机的,这里我们只是形式上演示创建一个 key 的过程。
创建 iv
接下来,创建 iv,它的长度应该是 16 字节,因此,除了长度之外,它的创建过程和 key 是一样的:
let iv = { () -> [UInt8] in
var tmp: [UInt8] = []
for i in 1...16 { tmp.append(UInt8(i)) }
return tmp
}()
创建 AES 对象
有了 key 和 iv 之后,就可以像这样创建 AES
对象了:
let aes = try! AES(key: key, blockMode: CBC(iv: iv), padding: .pkcs7)
其中,blockMode
还支持 CFB
,CTR
,ECB
等其它 AES 加密模式,大家可以在这里查看所有支持的模式,不过它们的用法是类似的,大家要用的时候,去翻翻代码就好了。
至于 padding
,除了 .pkcs7
之外,我们还可以依据使用的算法,传递:.pkcs5
,.noPadding
以及 .zeroPadding
,大家可以在这里找到这些填充类型的定义。
AES 加密和解密
最后,就是完成 AES-CBC-256 加密和解密了,要加密的数据,也是 Array<UInt8>
表示的字节数组:
do {
let encrypted = try aes.encrypt(Array("Hello world".utf8))
}
catch {
/// encrypt error
}
如果一切正常,返回的 encrypted
同样是一个 Array[UInt8]
。我们可以用同样的 aes
对象进行解密:
let decrypted = try aes.decrypt(encrypted)
这样得到的 decrypted
还是一个 Array<UInt8>
。当然,把它再变回 String
也很容易:
let hw = String(bytes: decrypted, encoding: .utf8) ?? ""
What's next?
至此,泊学 App 中需要的 AES 加密解密也就有解决方案了。下一节,我们分别为 HTTP 请求的参数以及服务器返回结果的数据预处理,编写一个简单的封装。